這篇文章帶給大家的內容是關於canvas中普通動效與粒子動效的實現方法介紹(程式碼範例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。
canvas用於在網頁上繪製圖像、動畫,可以將其理解為畫布,在這個畫布上建立想要的效果。
canvas可以繪製動態效果,除了常用的規則動畫之外,還可以採用粒子的概念來實現較複雜的動效,本文分別採用普通動效與粒子特效實現了一個簡單的時鐘。
普通時鐘
普通動效即利用canvas的api,實現有規則的圖案、動畫。
效果
#此效果實作比較簡單,主要分析一下刻度與指標角度偏移的實現。
繪製刻度
此範例為小時刻度的繪圖:錶盤上共有12個小時,Math.PI為180°,每小時佔據30°。
.save()表示儲存canvas目前環境的狀態,在此基礎上進行繪製。繪製完成之後,傳回先前儲存過的路徑狀態和屬性。
分鐘刻度同理,改變角度與樣式即可。
// 小时时间刻度 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,共有90000個像素,每個像素佔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系列中会针对粒子系统实现更多的动态效果。
以上是canvas中普通動效與粒子動效的實作 方法介紹(程式碼範例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!