哪位大神有空请帮忙看一下,为什么多次点击start按钮,动画中的小球速度会增加?
全部代码如下:
<!DOCTYPE html> <!-- To change this license header, choose License Headers in Project Properties. To change this template file, choose Tools | Templates and open the template in the editor. --> <html> <head> <title>Canvas start and stop</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> .container { width: 800px; height: 400px; margin: 0 auto; border: 2px dotted #498b50; } #mycanvas { border: 1px dotted #000; } </style> </head> <body> <div class="container"> <canvas id="mycanvas" width="800" height="400"></canvas> <input id="start" type="button" value="start"> <input id="stop" type="button" value="stop"> </div> <!--<p id="pid">x:</p>--> <!--<input id="accle" type="button" value="accelerate">--> <script> (function () { var lastTime = 0; var vendors = ['ms', 'moz', 'webkit', 'o']; for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']; window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame']; } if (!window.requestAnimationFrame) window.requestAnimationFrame = function (callback) { var id = window.setTimeout(function () { callback(); }, 0); return id; }; if (!window.cancelAnimationFrame) window.cancelAnimationFrame = function (id) { clearTimeout(id); }; }()); (function () { // Get the buttons. var startBtn = document.getElementById('start'); var stopBtn = document.getElementById('stop'); // var p = document.getElementById("pid"); // A variable to store the requestID. var requestID; // Canvas var canvas = document.getElementById("mycanvas"); var context = canvas.getContext("2d"); var w = canvas.width; var h = canvas.height; var x = 0; var y = 15; var xspeed = 3; var yspeed = 3; // Draw the initial box on the canvas. // Animate. function animate() { x += xspeed; y += yspeed; // p.innerHTML = "x:"+x; // If the box has not reached the end draw on the canvas. // Otherwise stop the animation. if (x <= 0 || x >= (w - 10)) { xspeed = -xspeed; } if (y <= 0 || y >= (h - 10)) { yspeed = -yspeed; } draw(); function draw() { context.save(); context.clearRect(0, 0, w, h); context.fillStyle = "#0066cc"; context.beginPath(); context.arc(x, y, 10, 0, Math.PI * 2, true); context.closePath(); context.fill(); } requestID = requestAnimationFrame(animate); } // Event listener for the start button. startBtn.addEventListener('click', function (e) { e.preventDefault(); // Start the animation. requestID = requestAnimationFrame(animate); }); // Event listener for the stop button. stopBtn.addEventListener('click', function (e) { e.preventDefault(); // Stop the animation; cancelAnimationFrame(requestID); }); }()); </script> </body> </html>
因为setTimeout. 你每次点击Start 按钮. 就开启一个setTimeout.
假设你点了2次Start 按钮. 就会开启两次setTimeout. 也就是说每秒钟执行2次animate() function.
所以速度会加快.
当你点Stop 按钮的时候. 就会关闭一个Timeout. 所以会减少animate() function的执行次数. 所以会速度减慢.
setTimeout的返回ID是以栈的形式保存吗?
@阳子杰:
到底是堆还是栈.这个不是很清楚.没研究过.. 因为用alert 监控id的时候. 你会发现. 它的id的递增的..
看起来应该是Timeout每执行一次都会返回一个id. 但是当你点stop的时候. 说不定是哪个timeout返回的id的..
@李丶GuanYao: 刚刚研究了一下,会把后启动的setTimeout清除掉
@李丶GuanYao:修改了一下延迟时间,真的是不确定是哪个timeout返回的ID~~
1.我api不熟悉,canvas有一对标签式必写的,为了在标签内的场景元素动画不受标签外的设置影响,你可以查查是什么标签?
2. 时间贞没控制好?