数日前、同僚が特殊効果を見せてくれました。それはジグソーパズルです。違いは、パズルがアニメーションであることです。 DEMOを作ってほしいと言われたので、しばらく自分で作ってみましたが、確かに難しくはありませんでした。キャンバスを使えば簡単に作れます。したがって、このブログ投稿は専門家には適していません。 。 。 。趣味で何気なく書いただけです。
レンダリング:
少なくともこれを初めて見たときは、とても斬新だと思ったので、面白半分に作ってみました。ポスターが出たと思ったら、高評価をお願いします。
早速、デモ から始めましょう: ビデオ パズル (効果を確認するまでしばらく待つ必要がある場合があります。w3school から直接ビデオ リンクを作成しました。ドラッグ アンド ドロップできます。非常に単純で、まだいくつかのバグがあるかもしれません。結局のところ、これは単に原理を説明するためのデモです。) もう 1 つの点は、ビデオの現在のフレームをキャンバスに直接描画することはモバイル デバイスではサポートされていないようです。 。 。 。少なくともiPadで見たところ、絵が描けないことが分かりました。もし解決方法をご存知の方がいらっしゃいましたら、ご回答いただければ幸いです
。
原則: パズルの各ピースはキャンバスであり、オフスクリーン キャンバスも必要です。まずビデオタグを作成します
そして、ビデオを非表示にし、ビデオの再生時に各フレームをオフスクリーン キャンバスに描画します (オフスクリーン キャンバスは、データを保存するために使用される非表示のキャンバスです)。
の書き込み方法は非常に簡単です。
ctx.drawImage(video, 0, 0 、vw、vh);
の場合は、drawImage メソッドを使用して直接描画します。なぜ最初にオフスクリーン キャンバスを使用するのでしょうか? データの各フレームをすべてのパズル ピースのキャンバスに同時に直接描画すると、ブラウザーが即座にクラッシュするからです。したがって、オフスクリーンのキャンバスをバッファとして使用します。まず現在のフレームのデータをキャンバスに保存し、そのキャンバスをパズルのピースとしてキャンバスに描画します。キャンバスをキャンバスに描画するのも非常に簡単です。drawImage を使用することもできます:
ctx2.drawImage(cs , -this.cols*this.w , -this.rows*this.h , vw , vh);
それでは。 。 。 。原理は非常に簡単ですが、requestAnimationFrame を使用してフレームをループする場合は、速度を制限する必要があることを思い出してください。たとえば、以下に示すように、30 ミリ秒ごとに取得することをお勧めします。 ~50 ミリ秒。低すぎるとブラウザがクラッシュしやすくなります。高すぎると、ビデオがフリーズします。
function animate(){
var newTime = new Date();
if(newTime - lastTime > 30){
lastTime = newTime;
ctx.drawImage(video , 0 , 0 , vw , vh);
キャンバス。forEach(function(){
var ctx2 = this.cas.getContext('2d');
ctx2.drawImage(cs , -this.cols*this.w , -this.rows*this .h , vw , vh);
});
}
if("requestAnimationFrame" in window){
requestAnimationFrame(animate);
}
else if("webkitRequestAnimationFrame" " ウィンドウ内){
webkitRequestAnimationFrame(animate);
}
else if("msRequestAnimationFrame" in window){
msRequestAnimationFrame(animate);
}
else if("mozRequestAnimationFrame" " in window ){
mozRequestAnimationFrame(animate);
}
}
最後にすべてのコードを投稿します:
视频拼图
<script><br> var video = document.getElementById("video") ;<br> var cs = document.getElementById("liping");<br> var ctx = cs.getContext('2d')<br> var rows = 3,<br>cols = 3,<br> cb = document.querySelector(".allCanvas"),<br> vw = 600,<br> vh = 400,<br> キャンバス = [];</p>
<p> function createCanvas(){<br> var num = rows*cols;<br> for(var i=0;i<cols></cols> for(var j=0;j<rows></rows> var Canvas = new vCanvas(Math.random()*600, Math.random()*600 , vw/rows , vh/cols , j , i);<br> Canvases.push(canvas);<br> }<br> }<br> }</p>
<p> var vCanvas = function(x,y,w,h,cols,rows){<br> this.x = x;<br> this.y = y;<br> this.w = w;<br> this。 h = h;<br> this.cols =cols;<br> this.rows = rows;<br> this.creat();<br> this.behavior();<br> }<br> vCanvas.prototype = {<br> creat:function(){<br> this.cas = document.createElement("canvas");<br> cb.appendChild(this.cas);<br> this.cas.className = "vcanvas ";<br> this.cas.id = "vc_" (this.cols 1)*(this.rows 1);<br> this.cas.style.left = this.x "px";<br> this .cas.style.top = this.y "px";<br> this.cas.width = this.w;<br> this.cas.height = this.h;<br> },<br> 動作: function(){<br> this.cas.onmousedown = function(e){<br> e = e || window.event;<br> var that = this;<br> var om = {<br> x:e.clientX,<br> y:e.clientY<br> }<br> window.onmousemove = function(e ){<br> e = e || window.event;<br> var nm = {<br> x:e.clientX,<br> y:e.clientY<br> }<br> that.style.left = parseInt(that.style.left.replace ("px","")) (nm.x-om.x) "px";<br> that.style.top = parseInt(that.style.top.replace("px","")) ( nm.y-om.y) "px";<br> om = nm;<br> }<br> window.onmouseup = function(){<br> this.onmousemove = null;<br> }<br> }<br> }<br> }</p>
<p> Array.prototype.forEach = function(callback){<br> for(var i=0;i<this.length></this.length> callback.call(this[i]);<br> }<br> }</p>
<p> var lastTime = 0;<br> function initAnimate(){<br> lastTime = new Date();<br> createCanvas();<br> animate();<br> }</p>
<p> function animate(){<br> var newTime = new Date();<br> if(newTime - lastTime > 30){<br> lastTime = newTime;<br> ctx.drawImage(video , 0 , 0 , vw 、vh);<br> Canvases.forEach(function(){<br> var ctx2 = this.cas.getContext('2d');<br> ctx2.drawImage(cs , -this.cols*this.w , -this.rows*this.h , vw , vh);<br> });<br> }<br> if("requestAnimationFrame" in window){<br> requestAnimationFrame(animate);<br> }<br> else if("webkitRequestAnimationFrame" in window){<br> webkitRequestAnimationFrame(animate);<br> }<br> else if("msRequestAnimationFrame" in window){<br> msRequestAnimationFrame(animate);<br> }<br> else if("mozRequestAnimationFrame" in window){<br> mozRequestAnimationFrame(animate);<br> }<br> }</p>
<p> video.play();<br> initAnimate();<br> </script>