<style type="text/css"> canvas { margin: 20px; } </style> <h1>小蝌蚪模拟风场</h1> <canvas id="canvas" width=700 height=500 style="border: 1px solid #ccc;"></canvas>
<script> $(function () { var Arrow = function (x, y, angle, speed, alive) { this.x = x; this.y = y; this.angle = angle; this.speed = speed || 10; //小蝌蚪长度来代表速度 this.alive = alive || true; //是否活着 this.liveLength = Math.random() * 20; //生命长度 }; self.init = function () { this.canvas = document.getElementById(‘canvas‘); this.ctx = canvas.getContext(‘2d‘); this.cw = this.canvas.width; this.ch = this.canvas.height; this.arrows = this.initArrows(); }; self.initArrows = function () { var count = 200, arrowArray = [], arrow = {}; while (count--) { arrow = new Arrow(Math.random() * this.cw, Math.random() * this.ch, Math.random() * 360, 10, true); arrowArray.push(arrow); } return arrowArray; }; self.createArrows = function () { this.ctx.clearRect(0, 0, this.cw, this.ch); var i = this.arrows.length; while (i--) { var arrow = this.arrows[i]; arrow.reset(); if (arrow.alive) { arrow.draw(); } else { arrow.relive(); } } }; Arrow.prototype.draw = function () { var ex = ey = 0; ex = this.x - this.speed * Math.sin((180 - this.angle) * (Math.PI / 180)); //↓0°←90° ey = this.y - this.speed * Math.cos((180 - this.angle) * (Math.PI / 180)); ctx.beginPath(); ctx.translate(0, 0, 0); //坐标源点 ctx.moveTo(this.x, this.y); ctx.lineTo(ex, ey); ctx.fill(); ctx.stroke(); ctx.save(); ctx.translate(ex, ey); //我的箭头本垂直向下,算出直线偏离Y的角,然后旋转 ,rotate是顺时针旋转的,所以加个负号 var ang = (ex - this.x) / (ey - this.y); ang = Math.atan(ang); ey - this.y >= 0 ? ctx.rotate(-ang) : ctx.rotate(Math.PI - ang);//加个180度,反过来 ctx.lineTo(-4, -4); ctx.lineTo(0, -4); ctx.lineTo(4, -4); ctx.lineTo(0, 0); ctx.fill(); //箭头是个封闭图形 ctx.restore(); //用来恢复Canvas之前保存的状态,否则会影响后续绘制 ctx.closePath(); this.x = ex; //终点当起点 this.y = ey; }; Arrow.prototype.reset = function () { this.liveLength--; if (this.liveLength <= 0) { this.alive = false; } if (this.x < 0 || this.y < 0 || this.x > self.cw || this.y > self.ch) { this.alive = false; } }; Arrow.prototype.relive = function () { this.alive = true; this.x = Math.random() * self.cw; this.y = Math.random() * self.ch; this.liveLength = Math.random() * 20; }; self.init(); var animateArrow = function () { self.createArrows(); }; var timer = setInterval(animateArrow, 200); }); </script>
原文:http://www.cnblogs.com/my-codelife/p/5180234.html