canvas用于在网页上绘制图象、动画,能够将其理解为画布,在这个画布上构建想要的结果。
canvas能够绘制动态结果,除了经常运用的划定规矩动画以外,还能够采纳粒子的观点来完成较庞杂的动效,本文离别采纳一般动效与粒子殊效完成了一个简朴的时钟。
一般时钟
一般动效即应用canvas的api,完成有划定规矩的图案、动画。
结果
该结果完成比较简朴,重要剖析一下刻度与指针角度偏移的完成。
绘制刻度
此例为小时刻度的绘制:表盘上共有12个小时,Math.PI为180°,每小时占有30°。
.save()示意保留canvas当前环境的状况,在此基础上举行绘制。绘制完成今后,返回之前保留过的途径状况和属性。
分钟刻度同理,转变角度与款式即可。
// 小时时候刻度 offscreenCanvasCtx.save(); for (var i = 0; i < 12; i++) { offscreenCanvasCtx.beginPath(); // 刻度色彩 offscreenCanvasCtx.strokeStyle = '#fff'; // 刻度宽度 offscreenCanvasCtx.lineWidth = 3; // 每小时占有30° offscreenCanvasCtx.rotate(Math.PI / 6); // 最先绘制的位置 offscreenCanvasCtx.lineTo(140, 0) // 完毕绘制的位置; offscreenCanvasCtx.lineTo(120, 0); // 绘制途径 offscreenCanvasCtx.stroke(); } offscreenCanvasCtx.restore();
指针指向
以秒针为例:猎取当前时候的秒数,并盘算对应的偏移角度
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<=image.width;i++){ for(var j=1;j<=image.height;j++){ pos=[(i-1)*image.width+(j-1)]*4; //获得像素位置 if(data[pos]>=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 < len; i++) { curr_pixel = pixels[i]; ctx.fillStyle = curr_pixel.fillStyle; ctx.fillRect(curr_pixel.x, curr_pixel.y, 1, 1); } }
粒子时钟
衬着笔墨时钟
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<=textHeight;i++){ for(let j=1;j<=textWidth;j++){ pos=[(i-1)*textWidth+(j-1)]*4; //获得像素位置 if(data[pos]>=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中一般动效与粒子动效的完成 要领引见(代码示例)的细致内容,更多请关注ki4网别的相干文章!