$(function () { var canvas = document.getElementById("cas"), ctx = canvas.getContext("2d"), vpx = canvas.width / 2, vpy = canvas.height / 2, Radius = 150, balls = [], angleX = Math.PI / 100, angleY = Math.PI / 100; var Animation = function () { this.init(); }; Animation.prototype = { isrunning: false, init: function () { balls = []; var num = 500; for (var i = 0; i <= num; i++) { var a , b; var k = -1 + (2 * (i + 1) - 1) / num; var a = Math.acos(k); var b = a * Math.sqrt(num * Math.PI); var x = Radius * Math.sin(a) * Math.cos(b); var y = Radius * Math.sin(a) * Math.sin(b); var z = Radius * Math.cos(a); var b = new ball(x, y, z, 1.5); balls.push(b); b.paint(); } }, start: function () { this.isrunning = true; animate(); }, stop: function () { this.isrunning = false; } }; function animate() { ctx.clearRect(0, 0, canvas.width, canvas.height); rotateX(); rotateY(); balls.sort(function (a, b) { return b.z - a.z; }); for (var i = 0; i < balls.length; i++) { balls[i].paint(); } if (animation.isrunning) { if ("requestAnimationFrame" in window) { requestAnimationFrame(animate); } else if ("webkitRequestAnimationFrame" in window) { webkitRequestAnimationFrame(animate); } else if ("msRequestAnimationFrame" in window) { msRequestAnimationFrame(animate); } else if ("mozRequestAnimationFrame" in window) { mozRequestAnimationFrame(animate); } } } function rotateX() { var cos = Math.cos(angleX); var sin = Math.sin(angleX); for (var i = 0; i < balls.length; i++) { var y1 = balls[i].y * cos - balls[i].z * sin; var z1 = balls[i].z * cos + balls[i].y * sin; balls[i].y = y1; balls[i].z = z1; } } function rotateY() { var cos = Math.cos(angleY); var sin = Math.sin(angleY); for (var i = 0; i < balls.length; i++) { var x1 = balls[i].x * cos - balls[i].z * sin; var z1 = balls[i].z * cos + balls[i].x * sin; balls[i].x = x1; balls[i].z = z1; } } var ball = function (x, y, z, r) { this.x = x; this.y = y; this.z = z; this.r = r; this.width = 2 * r; }; ball.prototype = { paint: function () { var fl = 450 //焦距 ctx.save(); ctx.beginPath(); var scale = fl / (fl - this.z); var alpha = (this.z + Radius) / (2 * Radius); ctx.arc(vpx + this.x, vpy + this.y, this.r * scale, 0, 2 * Math.PI, true); ctx.fillStyle = "rgba(255,255,255," + (alpha + 0.5) + ")" ctx.fill(); ctx.restore(); } }; var animation = new Animation(); animation.start(); window.addEventListener("mousemove", function (event) { var x = event.clientX - canvas.offsetLeft - vpx - document.body.scrollLeft - document.documentElement.scrollLeft; var y = event.clientY - canvas.offsetTop - vpy - document.body.scrollTop - document.documentElement.scrollTop; angleY = -x * 0.0001; angleX = -y * 0.0001; }); document.getElementById("controlBtn").onclick = function () { this.innerText === "开始" ? this.innerText = "停止" : this.innerText = "开始"; this.innerText === "开始" ? animation.stop() : animation.start(); } });
<div> <canvas id="cas" width="500" height="500">浏览器不支持canvas,请更新浏览器后再浏览</canvas> <div style="width:50px;margin:10px auto"> <button id="controlBtn">停止</button> </div> </div> <div class="vimiumReset vimiumHUD" style="right: 315px; opacity: 1;">Vimium has been updated to <a class="vimiumReset" href="https://chrome.google.com/extensions/detail/dbepggeogbaibhgnhhndojpepiihcmeb">1.49</a>.<a class="vimiumReset close-button" href="#">×</a></div>
body { background:#000; } #cas { display: block; border: 1px solid; margin: auto; }