<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <canvas></canvas> <br> <div> <span>粒子设置:</span> <input type="text" value="小火柴的蓝色理想"> <button>文字设置确认</button> <button>按序筛选</button> <button>随机筛选</button> <button>不筛选</button> </div> <div> <span>粒子效果:</span> <button>按序显字</button> <button>随机显字</button> <button>混乱聚合</button> <button>重新混乱</button> </div> <div> <span>鼠标效果:</span> <span>1、鼠标移到文字上时,文字颜色变红;</span> <span>2、鼠标在文字上点击时,粒子远离鼠标指针</span> </div> <script> if(drawing1.getContext){ var cxt = drawing1.getContext('2d'); var W = drawing1.width = 300; var H = drawing1.height = 200; var imageData; var dataArr; btnSetText.onclick = function(){ fnSetText(textValue.value); } function fnSetText(str){ cxt.clearRect(0,0,W,H); 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 = cxt.getImageData(0,0,W,H); dataArr = setData(imageData,1,1); } fnSetText('小火柴'); btnchoose1.onclick = function(){ dataArr = setData(imageData,1,1); saveData(dataArr); } btnchoose2.onclick = function(){ dataArr = setData(imageData,2,1); saveData(dataArr); } btnchoose3.onclick = function(){ dataArr = setData(imageData,1,2); saveData(dataArr); } //筛选粒子 function setData(imageData,n,m){ //从imageData对象中取得粒子,并存储到dots数组中 var dots = []; //dots的索引 var index = 0; 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[index++] = { 'index':index, 'x':i, 'y':j, 'red':k, 'green':k+1, 'blue':k+2, 'randomX':Math.random()*W, 'randomY':Math.random()*H, 'mark':false } } } } //筛选粒子,仅保存dots.length/m个到newDots数组中 var newDots = []; var len = Math.floor(dots.length/m); for(var i = 0; i < len; i++){ newDots.push(dots.splice(Math.floor(Math.random()*dots.length),1)[0]); } return newDots; } function saveData(dataArr){ //将筛选后的粒子信息保存到新建的imageData中 var oNewImage = cxt.createImageData(W,H); for(var i = 0; i < dataArr.length; i++){ for(var j = 0; j < 4; j++){ oNewImage.data[dataArr[i].red+j] = imageData.data[dataArr[i].red+j]; } } //写入canvas中 cxt.putImageData(oNewImage,0,0); } //显示粒子 function showData(arr,oTimer,index,n){ oTimer = setTimeout(function(){ cxt.clearRect(0,0,W,H); //写入canvas中 saveData(arr[index++]); if(index == n){ clearTimeout(oTimer); }else{ //迭代函数 showData(arr,oTimer,index,n); } },60); } //重新混乱 function showDataToRandom(dataArr,oTimer,n){ oTimer = setTimeout(function fn(){ cxt.clearRect(0,0,W,H); for(var i = 0; i < dataArr.length; i++){ var temp = dataArr[i]; var x0 = temp.x; var y0 = temp.y; var disX = temp.randomX - temp.x; var disY = temp.randomY - temp.y; cxt.fillRect(x0 + disX/n,y0 + disY/n,1,1); } n--; if(n === 0){ clearTimeout(oTimer); }else{ showDataToRandom(dataArr,oTimer,n); } },60); } //混乱聚合 function showRandomToData(dataArr,oTimer,n){ oTimer = setTimeout(function(){ cxt.clearRect(0,0,W,H); for(var i = 0; i < dataArr.length; i++){ var temp = dataArr[i]; var x0 = temp.randomX; var y0 = temp.randomY; var disX = temp.x - temp.randomX; var disY = temp.y - temp.randomY; cxt.fillRect(x0 + disX/n,y0 + disY/n,1,1); } n--; if(n === 0){ clearTimeout(oTimer); }else{ showRandomToData(dataArr,oTimer,n); } },60); } btn1.onclick = function(){ btn1.arr = []; for(var i = 10; i > 1; i--){ btn1.arr.push(setData(imageData,i,1)); } showData(btn1.arr,btn1.oTimer,0,9); } btn2.onclick = function(){ btn2.arr = []; for(var i = 10; i > 0; i--){ btn2.arr.push(setData(imageData,2,i)); } showData(btn2.arr,btn2.oTimer,0,10); } btn3.onclick = function(){ clearTimeout(btn3.oTimer); showRandomToData(dataArr,btn3.oTimer,10); } btn4.onclick = function(){ clearTimeout(btn4.oTimer); showDataToRandom(dataArr,btn4.oTimer,10); } //鼠标移动 drawing1.onmousemove = function(e){ e = e || event; var x = e.clientX - drawing1.getBoundingClientRect().left; var y = e.clientY - drawing1.getBoundingClientRect().top; cxt.beginPath(); cxt.arc(x,y,10,0,Math.PI*2); for(var i = 0; i < dataArr.length; i++){ var temp = dataArr[i]; if(cxt.isPointInPath(temp.x,temp.y)){ cxt.fillStyle = 'red'; cxt.fillRect(temp.x,temp.y,1,1); } } cxt.fillStyle = 'black'; } //鼠标点击 drawing1.onmousedown = function(e){ var r = 20; e = e || event; var x = e.clientX - drawing1.getBoundingClientRect().left; var y = e.clientY - drawing1.getBoundingClientRect().top; cxt.beginPath(); cxt.arc(x,y,r,0,Math.PI*2); for(var i = 0; i < dataArr.length; i++){ var temp = dataArr[i]; if(cxt.isPointInPath(temp.x,temp.y)){ temp.mark = true; var angle = Math.atan2((temp.y - y),(temp.x - x)); temp.endX = x - r*Math.cos(angle); temp.endY = y - r*Math.sin(angle); var disX = temp.x - temp.endX; var disY = temp.y - temp.endY; cxt.fillStyle = '#fff'; cxt.fillRect(temp.x,temp.y,1,1); cxt.fillStyle = '#f00'; cxt.fillRect(temp.endX,temp.endY,1,1); cxt.fillStyle="#000"; dataRecovery(10); }else{ temp.mark = false; } } var oTimer = null; function dataRecovery(n){ clearTimeout(oTimer); oTimer = setTimeout(function(){ cxt.clearRect(0,0,W,H); for(var i = 0; i < dataArr.length; i++){ var temp = dataArr[i]; if(temp.mark){ var x0 = temp.endX; var y0 = temp.endY; var disX = temp.x - x0; var disY = temp.y - y0; cxt.fillRect(x0 + disX/n,y0 + disY/n,1,1); }else{ cxt.fillRect(temp.x,temp.y,1,1); } } dataRecovery(n-1); if(n === 1){ clearTimeout(oTimer); } },17); } } } </script> </body> </html>
以上这篇基于canvas粒子系统的构建详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。
您可能感兴趣的文章: