javascript特效:制作粒子签名
- html 代码:
<canvas id="canvas"></canvas>
- javascript代码:
1 <script> 2 var canvas = document.getElementById("canvas"); 3 //canvas 的大小 4 canvas.width = 900; 5 canvas.height = 150; 6 var ctx = canvas.getContext(\'2d\'); 7 var img; 8 var mouseX = null, mouseY = null; 9 var mouseRadius = 50; //power:大小1-100 10 var RAF = (function () { 11 return window.requestAnimationFrame || 12 window.webkitRequestAnimationFrame || 13 window.mozRequestAnimationFrame || 14 window.oRequestAnimationFrame || 15 window.msRequestAnimationFrame || 16 function (callback) { 17 window.setTimeout(callback, 1000 / 60); 18 }; 19 })(); 20 Array.prototype.forEach = function (callback) { 21 for (var i = 0; i < this.length; i++) { 22 callback.call((typeof this[i] === "object") ? this[i] : window, i, this[i]); 23 } 24 }; 25 window.onmousemove = function (e) { 26 if (e.target.tagName === "CANVAS") { 27 mouseX = e.clientX - e.target.getBoundingClientRect().left; 28 mouseY = e.clientY - e.target.getBoundingClientRect().top; 29 } else { 30 mouseX = null; 31 mouseY = null; 32 } 33 }; 34 var particleArray = []; 35 var animateArray = []; 36 var particleSize_x = 1; 37 var particleSize_y = 2; 38 var canvasHandle = { 39 init: function () { 40 this._reset(); 41 this._initImageData(); 42 this._execAnimate(); 43 }, 44 _reset: function () { 45 particleArray.length = 0; 46 animateArray.length = 0; 47 this.ite = 100; 48 this.start = 0; 49 this.end = this.start + this.ite; 50 }, 51 _initImageData: function () { 52 this.imgx = (canvas.width - img.width) / 2; 53 this.imgy = (canvas.height - img.height) / 2; 54 ctx.clearRect(0, 0, canvas.width, canvas.height); 55 ctx.drawImage(img, this.imgx, this.imgy, img.width, img.height); 56 var imgData = ctx.getImageData(this.imgx, this.imgy, img.width, img.height); 57 for (var x = 0; x < img.width; x += particleSize_x) { 58 for (var y = 0; y < img.height; y += particleSize_y) { 59 var i = (y * imgData.width + x) * 4; 60 if (imgData.data[i + 3] >= 125) { 61 var color = "rgba(" + 62 imgData.data[i] + 63 "," + 64 imgData.data[i + 1] + 65 "," + 66 imgData.data[i + 2] + 67 "," + 68 imgData.data[i + 3] + 69 ")"; 70 var xRandom = x + Math.random() * 20, 71 vx = -Math.random() * 200 + 400, 72 yRandom = img.height / 2 - Math.random() * 40 + 20, 73 vy; 74 75 if (yRandom < this.imgy + img.height / 2) { 76 vy = Math.random() * 300; 77 } else { 78 vy = -Math.random() * 300; 79 } 80 particleArray.push( 81 new Particle( 82 xRandom + this.imgx, 83 yRandom + this.imgy, 84 x + this.imgx, 85 y + this.imgy, 86 vx, 87 vy, 88 color 89 ) 90 ); 91 particleArray[particleArray.length - 1].drawSelf(); 92 } 93 } 94 } 95 }, 96 _execAnimate: function () { 97 var that = this; 98 particleArray.sort(function (a, b) { 99 return a.ex - b.ex; 100 }); 101 if (!this.isInit) { 102 this.isInit = true; 103 animate(function (tickTime) { 104 if (animateArray.length < particleArray.length) { 105 if (that.end > (particleArray.length - 1)) { 106 that.end = (particleArray.length - 1); 107 } 108 animateArray = animateArray.concat(particleArray.slice(that.start, that.end)); 109 that.start += that.ite; 110 that.end += that.ite; 111 } 112 animateArray.forEach(function () { 113 this.update(tickTime); 114 }); 115 }); 116 } 117 } 118 }; 119 var tickTime = 16; 120 function animate(tick) { 121 if (typeof tick == "function") { 122 var tickTime = 16; 123 ctx.clearRect(0, 0, canvas.width, canvas.height); 124 tick(tickTime); 125 RAF(function () { 126 animate(tick); 127 }); 128 } 129 } 130 function Particle(x, y, ex, ey, vx, vy, color) { 131 this.x = x; 132 this.y = y; 133 this.ex = ex; 134 this.ey = ey; 135 this.vx = vx; 136 this.vy = vy; 137 this.a = 1500; 138 this.color = color; 139 this.width = particleSize_x; 140 this.height = particleSize_y; 141 this.stop = false; 142 this.static = false; 143 this.maxCheckTimes = 10; 144 this.checkLength = 5; 145 this.checkTimes = 0; 146 } 147 var oldColor = ""; 148 Particle.prototype = { 149 constructor: Particle, 150 drawSelf: function () { 151 if (oldColor !== this.color) { 152 ctx.fillStyle = this.color; 153 oldColor = this.color; 154 } 155 ctx.fillRect(this.x - this.width / 2, this.y - this.height / 2, this.width, this.height); 156 }, 157 move: function (tickTime) { 158 if (this.stop) { 159 this.x = this.ex; 160 this.y = this.ey; 161 } else { 162 tickTime = tickTime / 1000; 163 var cx = this.ex - this.x; 164 var cy = this.ey - this.y; 165 var angle = Math.atan(cy / cx); 166 var ax = Math.abs(this.a * Math.cos(angle)); 167 ax = this.x > this.ex ? -ax : ax; 168 var ay = Math.abs(this.a * Math.sin(angle)); 169 ay = this.y > this.ey ? -ay : ay; 170 this.vx += ax * tickTime; 171 this.vy += ay * tickTime; 172 this.vx *= 0.95; 173 this.vy *= 0.95; 174 this.x += this.vx * tickTime; 175 this.y += this.vy * tickTime; 176 if (Math.abs(this.x - this.ex) <= this.checkLength && Math.abs(this.y - this.ey) <= this.checkLength) { 177 this.checkTimes++; 178 if (this.checkTimes >= this.maxCheckTimes) { 179 this.stop = true; 180 } 181 } else { 182 this.checkTimes = 0; 183 } 184 } 185 }, 186 update: function (tickTime) { 187 this.move(tickTime); 188 this.drawSelf(); 189 this._checkMouse(); 190 }, 191 _checkMouse: function () { 192 var that = this; 193 if (!mouseX) { 194 goback(); 195 return; 196 } 197 var distance = Math.sqrt(Math.pow(mouseX - this.x, 2) + Math.pow(mouseY - this.y, 2)); 198 var angle = Math.atan((mouseY - this.y) / (mouseX - this.x)); 199 if (distance < mouseRadius) { 200 this.stop = false; 201 this.checkTimes = 0; 202 if (!this.recordX) { 203 this.recordX = this.ex; 204 this.recordY = this.ey; 205 } 206 this.a = 2000 + 1000 * (1 - distance / mouseRadius); 207 var xc = Math.abs((mouseRadius - distance) * Math.cos(angle)); 208 var yc = Math.abs((mouseRadius - distance) * Math.sin(angle)); 209 xc = mouseX > this.x ? -xc : xc; 210 yc = mouseY > this.y ? -yc : yc; 211 this.ex = this.x + xc; 212 this.ey = this.y + yc; 213 } else { 214 goback(); 215 } 216 function goback() { 217 if (that.recordX) { 218 that.stop = false; 219 that.checkTimes = 0; 220 that.a = 1500; 221 that.ex = that.recordX; 222 that.ey = that.recordY; 223 that.recordX = null; 224 that.recordY = null; 225 } 226 } 227 } 228 }; 229 //use image 230 function useImage() { 231 img = document.getElementById("logo"); 232 if (img.complete) { 233 canvasHandle.init(); 234 } else { 235 img.onload = function () { 236 canvasHandle.init(); 237 }; 238 } 239 } 240 //use text 241 function useText() { 242 img = document.createElement(\'canvas\'); 243 img.width = 720; 244 img.height = 60; 245 var imgctx = img.getContext("2d"); 246 imgctx.textAlign = "center"; 247 imgctx.textBaseline = "middle"; 248 imgctx.font = "48px 华文行楷"; 249 imgctx.fillText(\'千江有水千江月,万里无云万里天\', img.width / 2, img.height / 2); 250 canvasHandle.init(); 251 } 252 useText(); 253 </script>
View Code
版权声明:本文为abcxyz原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。