clearTimeout 不停止 canvas 动画
clearTimeout not stopping canvas animation
所以我有一个简单的 canvas 动画,我想使用拨动开关开始和停止。动画工作正常并启动,但 clearTimeout 似乎不起作用。
我确保变量 "timeOut" 是全局定义的,因此它应该可以访问它,这似乎是过去类似于此问题的常见建议。我在其他地方犯错了吗?在 Firefox、Chrome 和 Chromium 上试过。
let timeOut;
function circles() {
let canvas = document.querySelector('canvas');
canvas.width = document.querySelector('canvas').offsetWidth;
canvas.height = document.querySelector('canvas').offsetHeight;
let c = canvas.getContext('2d');
let topRadius = 30;
let colorArray = [
'#ff0000',
'#00ff00',
'#0000ff',
]
let mouse = {
x: undefined,
y: undefined
}
window.addEventListener('mousemove', function(e) {
mouse.x = e.x;
mouse.y = e.y;
})
window.addEventListener('resize', function() {
canvas.width = document.querySelector('canvas').offsetWidth;
canvas.height = document.querySelector('canvas').offsetHeight;
init();
});
function Circle(x, y, dx, dy, radius) {
this.x = x;
this.y = y;
this.dx = dx;
this.dy = dx;
this.radius = radius;
this.minRadius = radius;
this.color = colorArray[Math.floor(Math.random() * colorArray.length)];
this.draw = function() {
if (this.radius < 0) {
this.radius = this.minRadius;
}
c.beginPath();
c.arc(this.x, this.y, this.radius, 0, Math.PI*2, false);
c.fillStyle = this.color;
c.fill();
}
this.update = function() {
if (this.y + this.radius > innerHeight || this.y - this.radius <= 0) {
this.dy = -this.dy;
}
if (this.x + this.radius > canvas.width|| this.x - this.radius <= 0) {
this.dx = -this.dx;
}
this.x+=this.dx;
this.y+=this.dy;
if (mouse.x - this.x < 50 && mouse.x - this.x > -50 && mouse.y - this.y < 50 && mouse.y - this.y > -50) {
if (this.radius < topRadius) {
this.radius += 1;
}
} else if (this.radius > this.minRadius){
this.radius -= 1;
}
this.draw();
}
}
let circleArray = [];
function init() {
circleArray = [];
for (let i =0; i<50; i++) {
let radius = Math.random() * 10;
let x = Math.random() * (canvas.width - radius*2) + radius;
let y = Math.random() * (canvas.height - radius * 2) + radius;
let dx = (Math.random() - 0.5) * 4;
let dy = (Math.random() - 0.5 )* 4;
circleArray.push(new Circle(x, y, dx, dy, radius));
}
}
function animate() {
requestAnimationFrame(animate);
c.clearRect(0,0, canvas.width, innerHeight);
for(let i=0; i < circleArray.length; i++) {
circleArray[i].update();
}
}
init();
animate();
}
$('#startstop').click(function() {
if(!timeOut) {
timeOut = setTimeout(circles, 1000);
} else {
clearTimeout(timeOut);
timeOut = null;
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="display: flex; justify-content: space-around;">
<canvas style="width: 100px; height: 800px; background: red;"></canvas>
<div id="startstop">toggle</div>
</div>
此动画不会停止,因为您在 setTimeout
上调用了 clearTimeout
,但它只运行一次。您的问题与 animate
函数有关。这相对循环requestAnimationFrame
。您可以将其存储为请求,然后 cancelAnimationFrame
您非常接近解决方案 ;)
在函数 animate
中添加第 3 行(在 for 循环之前),即具有此值:
if (!timeOut) return;
祝你好运!
所以我有一个简单的 canvas 动画,我想使用拨动开关开始和停止。动画工作正常并启动,但 clearTimeout 似乎不起作用。
我确保变量 "timeOut" 是全局定义的,因此它应该可以访问它,这似乎是过去类似于此问题的常见建议。我在其他地方犯错了吗?在 Firefox、Chrome 和 Chromium 上试过。
let timeOut;
function circles() {
let canvas = document.querySelector('canvas');
canvas.width = document.querySelector('canvas').offsetWidth;
canvas.height = document.querySelector('canvas').offsetHeight;
let c = canvas.getContext('2d');
let topRadius = 30;
let colorArray = [
'#ff0000',
'#00ff00',
'#0000ff',
]
let mouse = {
x: undefined,
y: undefined
}
window.addEventListener('mousemove', function(e) {
mouse.x = e.x;
mouse.y = e.y;
})
window.addEventListener('resize', function() {
canvas.width = document.querySelector('canvas').offsetWidth;
canvas.height = document.querySelector('canvas').offsetHeight;
init();
});
function Circle(x, y, dx, dy, radius) {
this.x = x;
this.y = y;
this.dx = dx;
this.dy = dx;
this.radius = radius;
this.minRadius = radius;
this.color = colorArray[Math.floor(Math.random() * colorArray.length)];
this.draw = function() {
if (this.radius < 0) {
this.radius = this.minRadius;
}
c.beginPath();
c.arc(this.x, this.y, this.radius, 0, Math.PI*2, false);
c.fillStyle = this.color;
c.fill();
}
this.update = function() {
if (this.y + this.radius > innerHeight || this.y - this.radius <= 0) {
this.dy = -this.dy;
}
if (this.x + this.radius > canvas.width|| this.x - this.radius <= 0) {
this.dx = -this.dx;
}
this.x+=this.dx;
this.y+=this.dy;
if (mouse.x - this.x < 50 && mouse.x - this.x > -50 && mouse.y - this.y < 50 && mouse.y - this.y > -50) {
if (this.radius < topRadius) {
this.radius += 1;
}
} else if (this.radius > this.minRadius){
this.radius -= 1;
}
this.draw();
}
}
let circleArray = [];
function init() {
circleArray = [];
for (let i =0; i<50; i++) {
let radius = Math.random() * 10;
let x = Math.random() * (canvas.width - radius*2) + radius;
let y = Math.random() * (canvas.height - radius * 2) + radius;
let dx = (Math.random() - 0.5) * 4;
let dy = (Math.random() - 0.5 )* 4;
circleArray.push(new Circle(x, y, dx, dy, radius));
}
}
function animate() {
requestAnimationFrame(animate);
c.clearRect(0,0, canvas.width, innerHeight);
for(let i=0; i < circleArray.length; i++) {
circleArray[i].update();
}
}
init();
animate();
}
$('#startstop').click(function() {
if(!timeOut) {
timeOut = setTimeout(circles, 1000);
} else {
clearTimeout(timeOut);
timeOut = null;
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="display: flex; justify-content: space-around;">
<canvas style="width: 100px; height: 800px; background: red;"></canvas>
<div id="startstop">toggle</div>
</div>
此动画不会停止,因为您在 setTimeout
上调用了 clearTimeout
,但它只运行一次。您的问题与 animate
函数有关。这相对循环requestAnimationFrame
。您可以将其存储为请求,然后 cancelAnimationFrame
您非常接近解决方案 ;)
在函数 animate
中添加第 3 行(在 for 循环之前),即具有此值:
if (!timeOut) return;
祝你好运!