この記事では、キャンバスでの通常のモーション エフェクトとパーティクル モーション エフェクトの実装方法 (コード例) を紹介します。必要な方は参考にしていただければ幸いです。それはあなたを助けます。
キャンバスは、Web ページ上に画像やアニメーションを描画するために使用され、キャンバスとして理解され、目的の効果がこのキャンバス上に構築されます。
キャンバスでは、一般的に使用される通常のアニメーションに加えて、パーティクルの概念を使用して、より複雑なダイナミック エフェクトを実現することもできます。この記事では、通常のダイナミック エフェクトとパーティクルの特殊効果を使用して、単純なクロックを実装します。 。
通常の時計
通常のアニメーションは、キャンバス API を使用して通常のパターンとアニメーションを実現します。
効果
この効果は比較的簡単に実現でき、主に 2 つの間の角度オフセットを分析します。スケールとポインタを実行します。
目盛りの描画
この例は時間目盛りの描画です。文字盤には 12 時間があり、Math.PI は 180°、各時間は 30°を占めます。 。
.save()は現在のキャンバス環境の状態を保存し、それを基に描画することを意味します。描画が完了すると、以前に保存したパスのステータスと属性が返されます。
分スケールは同じですが、角度とスタイルを変更するだけです。
// 小时时间刻度 offscreenCanvasCtx.save(); for (var i = 0; i <p><strong>ポインタは次を指します</strong></p><p>秒針を例として取り上げます。現在時刻の秒を取得し、対応するオフセット角度を計算します</p><pre class="brush:php;toolbar:false"> var now = new Date(), sec = now.getSeconds(), min = now.getMinutes(), hr = now.getHours(); hr = hr > 12 ? hr - 12 : hr; //秒针 offscreenCanvasCtx.save(); offscreenCanvasCtx.rotate(sec * (Math.PI / 30)); ...... offscreenCanvasCtx.stroke();
パーティクル アニメーション
#canvas を使用して、複雑で不規則なアニメーションを描画できます。パーティクル エフェクトを使用すると、複雑でランダムなダイナミック エフェクトを実現できます。
パーティクルは、画像データ imageData
内の各ピクセルを参照します。各ピクセルを取得した後、その領域内のパーティクルと対話する属性またはイベントを追加して、動的な効果を実現します。
次の画像変換は、最初にエフェクトが適用される例です。 Canvas 画像をレンダリングし、テキストが配置されている領域の各ピクセルを取得します。
let image = new Image(); image.src='../image/logo.png'; let pixels=[]; //存储像素数据 let imageData; image.width = 300; image.height = 300 // 渲染图片,并获取该区域内像素信息 image.onload=function(){ ctx.drawImage(image,(canvas.width-image.width)/2,(canvas.height-image.height)/2,image.width,image.height); imageData=ctx.getImageData((canvas.width-image.width)/2,(canvas.height-image.height)/2,image.width,image.height); //获取图表像素信息 //绘制图像 };
画像のサイズは 300*300、合計 90,000 ピクセルで、各ピクセルは 4 ビットを占有し、rgba データを格納します。
function getPixels(){ var pos=0; var data=imageData.data; //RGBA的一维数组数据 //源图像的高度和宽度为300px for(var i=1;i=0){ var pixel={ x:(canvas.width-image.width)/2+j+Math.random()*20, //重新设置每个像素的位置信息 y:(canvas.height-image.height)/2+i+Math.random()*20, //重新设置每个像素的位置信息 fillStyle:'rgba('+data[pos]+','+(data[pos+1])+','+(data[pos+2])+','+(data[pos+3])+')' } pixels.push(pixel); } } } } function drawPixels() { var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); ctx.clearRect(0,0,canvas.width,canvas.height); var len = pixels.length, curr_pixel = null; for (var i = 0; i <h1>パーティクル クロック</h1><h2>レンダリング テキスト クロック</h2><pre class="brush:php;toolbar:false"> function time() { ctx.clearRect(0,0,canvas.width,canvas.height) ctx.font = "150px 黑体"; ctx.textBaseline='top'; ctx.fillStyle = "rgba(245,245,245,0.2)"; ctx.fillText(new Date().format('hh:mm:ss'),(canvas.width-textWidth)/2,(canvas.height-textHeight)/2,textWidth,textHeight); }
文字转换粒子概念同上,获取选定区域的像素,根据筛选条件进行选择并存入数组。经过遍历后重新绘制。
function getPixels(){ let imgData = ctx.getImageData((canvas.width-textWidth)/2,(canvas.height-textHeight)/2,textWidth,textHeight); let data = imgData.data pixelsArr = [] for(let i=1;i=0){ var pixel={ x:j+Math.random()*20, //重新设置每个像素的位置信息 y:i+Math.random()*20, //重新设置每个像素的位置信息 fillStyle:'rgba('+data[pos]+','+(data[pos+1])+','+(data[pos+2])+','+(data[pos+3])+')' }; pixelsArr.push(pixel); } } } }
imgData
保存了所选区域内的像素信息,每个像素点占据4位,保存了RGBA四位信息。筛选每个像素的第四位,这段代码中将所有透明度不为0的像素都保存到了数组pixelsArr
中。
x
、y
记载了该粒子的位置信息,为了产生效果图中的运动效果,给每个粒子添加了0-20个像素的偏移位置,每次重绘时,偏移位置随机生成,产生运动效果。
获取粒子之后,需要清除画布中原有的文字,将获取到的粒子重新绘制到画布上去。
function drawPixels() { // 清除画布内容,进行重绘 ctx.clearRect(0,0,canvas.width,canvas.height); for (let i in pixelsArr) { ctx.fillStyle = pixelsArr[i].fillStyle; let r = Math.random()*4 ctx.fillRect(pixelsArr[i].x, pixelsArr[i].y, r, r); } }
粒子重绘时的样式为筛选像素时原本的颜色与透明度,并且每个在画布上绘制每个粒子时,定义大小参数r,r取值为0-4中随机的数字。最终生成的粒子大小随机。
获取粒子并成功重绘之后,需要页面实时刷新时间。这里采用window.requestAnimationFrame(callback)
方法。
function time() { ...... getpixels(); //获取粒子 drawPixels(); // 重绘粒子 requestAnimationFrame(time); }
window.requestAnimationFrame(callback)
方法告诉浏览器您希望执行动画并请求浏览器在下一次重绘之前调用指定的函数来更新动画。该方法使用一个回调函数作为参数,这个回调函数会在浏览器重绘之前调用。
该方法不需要设置时间间隔,调用频率采用系统时间间隔(1s)。
效果
总结
本文主要通过两种不同的方式实现了时钟的动态效果,其中粒子时钟具有更多的可操作性。在以后的canvas系列中会针对粒子系统实现更多的动态效果。
以上が通常のモーションエフェクトとパーティクルモーションエフェクトをキャンバスに実装する方法の紹介(コード例)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。