HTMLで演出っぽいものを作れるか、というのと、jQueryのプラグインを作ってみる練習。
Haxeを最近は使ってますが、これは生JSです。jQueryプラグインですしね。
さて。RayEffectです。
サンプル:→RayEffect JS
n0wriさんがwonderflで作られていたFlashエフェクトを元ネタにしています。(どこかの何かのキャンペーンサイトで同じようなエフェクトがあったような気がします。…が果たして何だったか。)
Canvasで真似して書けばあっさりできそうな気もしますが、CSSでもできそうなのでCSSとjQueryだけで再現してみました。
ソース
(function($){ $.fn.rayeffect = function(config){ var defaults = { duration:1000 } var options = $.extend(defaults, config); return this.each(function(index){ var TIME = options.duration; var ct = $(this); var w = ct.width(); var h = ct.height(); var elem = $(document.createElement("div")); elem.attr("id", "rayEffectTarget" + index); var src = ct.attr("src"); elem.css({position:"relative", width:w, height:h, overflow:"hidden", background:"url(" + src + ")"}).animate({width:w}, TIME, "linear"); var rayElem = $(document.createElement("div")); var cloneImg = ct.clone(); rayElem.append(cloneImg); rayElem.css({width:1, height:h, left:0, top:0, position:"absolute", overflow:"hidden"}); setTransformScaleLT(rayElem, w, 1); cloneImg.css({position:"absolute", display:"block"}).animate({left:-w}, TIME, "linear"); rayElem.animate({left:w}, TIME, "linear"); elem.append(rayElem); var parent = ct.parent(); parent.append(elem); ct.remove(); $.when(rayElem, cloneImg).done(function(){ elem.remove(); parent.append(ct); }); }); function setTransformScaleLT(jqElem, scaleX, scaleY){ jqElem.css("-webkit-transform", "scale(" + scaleX + "," + scaleY + ")") .css("-moz-transform", "scale(" + scaleX + "," + scaleY + ")") .css("-o-transform", "scale(" + scaleX + "," + scaleY + ")") .css("-ms-transform", "scale(" + scaleX + "," + scaleY + ")") .css("transform", "scale(" + scaleX + "," + scaleY + ")"); jqElem.css("-webkit-transform-origin", "0 0") .css("-moz-transform-origin", "0 0") .css("-o-transform-origin", "0 0") .css("-ms-transform-origin", "0 0") .css("transform-origin", "0 0"); } }; })(jQuery);
→gist
肝の部分は、引き伸ばしの画像を作ってるところで、CSSのtransform:scaleとtransform-originを使っています。
あとで見返してみると、わざわざDOMから外すよりも、上にエフェクト用画像を被せるだけにしたほうが軽くなりますかね。…まあ、それをいうなら横だけより縦とかいろんな方向できたほうが良かったりしますし、お試しとしてはまあいいかなと。
IE8以下は非対応ですが、スマホでも動くと思います。古いと動かないかもしれませんが、iOS6のSafari、Android4.0のブラウザでは普通に動いてくれました。(1つ動かすくらいなら重さも問題無さそう。)
ちなみに、IE8への対応もtransform:scaleを使わずに、単純に画像をwidth倍してwidth分ずつ移動させれば、同じような見え方になるはずではと思ったんですが、
IEだけ全滅しました。(他のブラウザは問題なし)
IEだけwidthが16384px?以上の画像を表示すると1pxになってしまうという仕様?があるらしく、どうしようもないようでした。
なんだこれぇ…。ってことで、IE9以上で表示されないよりはマシなのでtransform:scaleを使っています。まあ想定外の数値なんでしょう。(scaleで拡大するのは大丈夫な理由がよくわかりませんが…。)
jQueryのプラグイン作るのって難しいのかと思っていましたが、決まりがわかってれば簡単にできるんですね。面白い。
(こういうの書くとき、jsdo.itの方がいいのだろうか。)