基于canvas粒子系统的构建详解(3)

按序像素显字的实现原理非常简单,比如,共有2000个粒子,共10个程度的过渡效果。则使用10个数组,分别保存200,400,600,800,100,1200,1400,1600,1800和2000个粒子。然后使用定时器将其逐步显示出来即可

<canvas></canvas> <button>开始显字</button> <script> var drawing1 = document.getElementById('drawing1'); if(drawing1.getContext){ var cxt = drawing1.getContext('2d'); var W = drawing1.width = 200; var H = drawing1.height = 200; var str = '小火柴'; cxt.textBaseline = 'top'; var sh = 60; cxt.font = sh + 'px 宋体' var sw = cxt.measureText(str).width; if(sw > W){ sw = W; } cxt.fillText(str,(W - sw)/2,(H - sh)/2,W); //获取imageData var imageData = cxt.getImageData(0,0,W,H); cxt.clearRect(0,0,W,H); //获得10组粒子 var imageDataArr = []; var n = 10; var index = 0; for(var i = n; i > 0; i--){ imageDataArr.push(setData(imageData,i)); } var oTimer = null; btn.onclick = function(){ clearTimeout(oTimer); showData(); } function showData(){ oTimer = setTimeout(function(){ cxt.clearRect(0,0,W,H); //写入drawing1中 cxt.putImageData(imageDataArr[index++],0,0); //迭代函数 showData(); if(index == 10){    index = 0; clearTimeout(oTimer); } },100); } function setData(imageData,n,m){ //从imageData对象中取得粒子,并存储到dots数组中 var dots = []; for(var i = 0; i < W; i+=n){ for(var j = 0; j < H ;j+=n){ //data值中的红色值 var k = 4*(i + j*W); //data值中的透明度 if(imageData.data[k+3] > 0){ //将透明度大于0的data中的红色值保存到dots数组中 dots.push(k); } } } //筛选粒子,仅保存m个到newDots数组中。如果不传入m,则不进行筛选 var newDots = []; if(m && (dots.length > m)){ for(var i = 0; i < m; i++){ newDots.push(Number(dots.splice(Math.floor(Math.random()*dots.length),1))); } }else{ newDots = dots; } //新建一个imageData,并将筛选后的粒子信息保存到新建的imageData中 var oNewImage = cxt.createImageData(W,H); for(var i = 0; i < newDots.length; i++){ oNewImage.data[newDots[i]+0] = imageData.data[newDots[i]+0]; oNewImage.data[newDots[i]+1] = imageData.data[newDots[i]+1]; oNewImage.data[newDots[i]+2] = imageData.data[newDots[i]+2]; oNewImage.data[newDots[i]+3] = imageData.data[newDots[i]+3]; } return oNewImage; } } </script>

【随机像素显字】

随机像素显字的原理类似,保存多个不同数量的随机像素的数组即可

<canvas></canvas> <button>开始显字</button> <script> var drawing1 = document.getElementById('drawing1'); if(drawing1.getContext){ var cxt = drawing1.getContext('2d'); var W = drawing1.width = 200; var H = drawing1.height = 200; var str = '小火柴'; cxt.textBaseline = 'top'; var sh = 60; cxt.font = sh + 'px 宋体' var sw = cxt.measureText(str).width; if(sw > W){ sw = W; } cxt.fillText(str,(W - sw)/2,(H - sh)/2,W); //获取imageData var imageData = cxt.getImageData(0,0,W,H); cxt.clearRect(0,0,W,H); //获得10组粒子 var imageDataArr = []; var n = 10; var index = 0; for(var i = n; i > 0; i--){ imageDataArr.push(setData(imageData,1,i)); } var oTimer = null; btn.onclick = function(){ clearTimeout(oTimer); showData(); } function showData(){ oTimer = setTimeout(function(){ cxt.clearRect(0,0,W,H); //写入drawing1中 cxt.putImageData(imageDataArr[index++],0,0); //迭代函数 showData(); if(index == 10){ clearTimeout(oTimer); index = 0; } },100); } function setData(imageData,n,m){ //从imageData对象中取得粒子,并存储到dots数组中 var dots = []; for(var i = 0; i < W; i+=n){ for(var j = 0; j < H ;j+=n){ //data值中的红色值 var k = 4*(i + j*W); //data值中的透明度 if(imageData.data[k+3] > 0){ //将透明度大于0的data中的红色值保存到dots数组中 dots.push(k); } } } //筛选粒子,仅保存dots.length/m个到newDots数组中 var newDots = []; var len = Math.floor(dots.length/m); for(var i = 0; i < len; i++){ newDots.push(Number(dots.splice(Math.floor(Math.random()*dots.length),1))); } //新建一个imageData,并将筛选后的粒子信息保存到新建的imageData中 var oNewImage = cxt.createImageData(W,H); for(var i = 0; i < newDots.length; i++){ oNewImage.data[newDots[i]+0] = imageData.data[newDots[i]+0]; oNewImage.data[newDots[i]+1] = imageData.data[newDots[i]+1]; oNewImage.data[newDots[i]+2] = imageData.data[newDots[i]+2]; oNewImage.data[newDots[i]+3] = imageData.data[newDots[i]+3]; } return oNewImage; } } </script>

粒子动画

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wygfpz.html