效果图:
1 <!DOCTYPE html> 2 <html lang="en"> 3 4 <head> 5 <meta charset="UTF-8"> 6 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 7 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 8 <title>Canvas</title> 9 <style> 10 * { 11 margin: 0; 12 padding: 0; 13 } 14 15 html, 16 body { 17 height: 100%; 18 } 19 20 canvas { 21 display: block; 22 background-color: aqua; 23 } 24 </style> 25 </head> 26 27 <body> 28 <canvas id="canvas"></canvas> 29 30 <script> 31 var canvas = document.querySelector("#canvas"); 32 var ctx = canvas.getContext("2d"); 33 var w = canvas.width = window.innerWidth; 34 var h = canvas.height = window.innerHeight; 35 36 function randNum(min, max) { 37 return Math.random() * (max - min) + min; 38 } 39 40 function drawCircle(x, y, r, color) { 41 ctx.beginPath(); 42 ctx.arc(x, y, r, 0, Math.PI * 2); 43 ctx.strokeStyle = color || "#000"; 44 ctx.stroke(); 45 } 46 47 // 创建雨滴对象 48 function Drop() {} 49 50 Drop.prototype = { 51 init: function() { 52 this.x = randNum(0, w); 53 this.y = 0; 54 // y 方向速度 55 this.vy = randNum(3, 4); 56 // 雨滴下落的最大高度 80% ~ 90% 57 this.dropEnd = randNum(0.8 * h, 0.9 * h); 58 this.radius = 1; 59 // 半径扩大的速度 60 this.vRadius = 1; 61 // 圆的透明度 62 this.transparency = 1; 63 // 透明度的变化系数 64 this.vTransparency = 0.93; 65 }, 66 draw: function() { 67 // 雨滴下落中 68 if (this.y < this.dropEnd) { 69 ctx.fillStyle = "rgba(0, 255, 255)"; 70 ctx.fillRect(this.x, this.y, 2, 10); 71 } else { // 雨滴散开 72 ctx.beginPath(); 73 ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2); 74 ctx.strokeStyle = "rgba(0, 255, 255," + this.transparency + ")"; 75 ctx.stroke(); 76 } 77 78 this.update(); 79 }, 80 update: function() { 81 if (this.y < this.dropEnd) { 82 this.y += this.vy; 83 } else { 84 if (this.transparency > 0.03) { 85 this.radius += this.vRadius; 86 if (this.radius > 20) { 87 this.transparency *= this.vTransparency; 88 } 89 } else { 90 this.init(); 91 } 92 } 93 } 94 } 95 96 // main 97 window.onresize = function() { 98 w = canvas.width = window.innerWidth; 99 h = canvas.height = window.innerHeight; 100 } 101 102 var dropArray = []; 103 for (var i = 0; i < 30; i++) { 104 // 每个雨滴延迟2毫秒 105 setTimeout(function() { 106 var drop = new Drop(); 107 drop.init(); 108 dropArray.push(drop); 109 }, i * 200) 110 } 111 112 function animation() { 113 requestAnimationFrame(animation); 114 // 视觉渐变 115 ctx.fillStyle = "rgba(0, 0, 0, 0.1)" 116 ctx.fillRect(0, 0, w, h); 117 for (var i = 0; i < dropArray.length; i++) { 118 dropArray[i].draw(); 119 } 120 } 121 122 animation(); 123 </script> 124 125 </body> 126 127 </html>