再次调用同一函数时,如何停止 canvas 动画?
How do I stop a canvas animation when the same function is called again?
我目前正在编写一个网站,点击导航 link,HTML canvas 会在相关内容框上画一条线 (我使用了 markE 的这里的精彩答案 作为动画教程)。我正在制作这些线条的动画,我 运行 进入以下问题:
如何在单击另一个 link 时阻止第一个动画完成?
我试过多次创建标志和 cancelAnimationFrame,但都没有成功。
这是一些简化的代码,目前使用了一个标志:
HTML
<div class="container">
<nav>
<ul>
<li>
<a href="#about" id="about" onclick="draw(this.id);">About</a>
</li>
<li>
<a href="#contact" id="contact" onclick="draw(this.id);">Work</a>
</li>
</ul>
</nav>
</div>
<canvas id="canvas" width="500" height="500"></canvas>
JavaScript
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var isRunning = false;
function draw(contentId) {
if (isRunning) return;
isRunning = true;
var t = 1;
var vertices = [];
function calcWaypoints(vertices) {
var waypoints = [];
for (var i = 1; i < vertices.length; i++) {
var pt0 = vertices[i - 1];
var pt1 = vertices[i];
var dx = pt1.x - pt0.x;
var dy = pt1.y - pt0.y;
for (var j = 0; j < 100; j++) {
var x = pt0.x + dx * j / 100;
var y = pt0.y + dy * j / 100;
waypoints.push({
x: x,
y: y
});
}
}
return (waypoints);
}
function animate() {
if (t < points.length - 1) {
window.requestAnimationFrame(animate);
}
ctx.beginPath();
ctx.moveTo(points[t - 1].x, points[t - 1].y);
ctx.lineTo(points[t].x, points[t].y);
ctx.stroke();
t++;
isRunning = false;
}
// Clear the canvas before drawing
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Assign coordinates
if (contentId == 'about') {
vertices.push({x: 50, y: 0}, {x: 50, y: 50});
vertices.push({x: 40, y: 60}, {x: 0, y: 60});
// Animate lines
ctx.lineCap = "round";
ctx.lineWidth = border;
ctx.strokeStyle = "green";
var points = calcWaypoints(vertices);
animate(points);
}
if (contentId == 'contact') {
vertices.push({x: 150, y: 0}, {x: 150, y: 50});
vertices.push({x: 160, y: 60}, {x: 300, y: 60});
vertices.push({x: 300, y: 70}, {x: 310, y: 70});
ctx.lineCap = "round";
ctx.lineWidth = border;
ctx.strokeStyle = "green";
var points = calcWaypoints(vertices);
animate(points);
}
}
重申一下,以防我不清楚:当我点击 'about' 然后直接点击 'contact' 时,我想要我第一次初始化时初始化的绘制动画单击 'about' 完全停止(包括清除 canvas),然后 'contact' 动画开始。目前,'contact' 动画确实开始了,但 'about' 动画也坚持要结束。当我点击 'about' 两次时发生同样的事情 - 动画同时运行两次...
如果它对任何人有帮助,我设法解决了它(逻辑上有一些错误,cancelAnimationFrame 最终做了我需要的而不是使用标志):
HTML
<div class="container">
<nav>
<ul>
<li>
<a href="#about" id="about" onclick="checkDraw(this.id);">About</a>
</li>
<li>
<a href="#contact" id="contact" onclick="checkDraw(this.id);">Work</a>
</li>
</ul>
</nav>
</div>
<canvas id="canvas" width="500" height="500"></canvas>
JavaScript
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var requestId;
function checkDraw(contentId) {
stopAnimation();
draw(contentId);
}
function stopAnimation(e) {
cancelAnimationFrame(requestId);
}
function draw(contentId) {
currentID = contentId;
var t = 1;
var vertices = [];
function calcWaypoints(vertices) {
var waypoints = [];
for (var i = 1; i < vertices.length; i++) {
var pt0 = vertices[i - 1];
var pt1 = vertices[i];
var dx = pt1.x - pt0.x;
var dy = pt1.y - pt0.y;
for (var j = 0; j < 100; j++) {
var x = pt0.x + dx * j / 100;
var y = pt0.y + dy * j / 100;
waypoints.push({
x: x,
y: y
});
}
}
return (waypoints);
}
function animate() {
if (t < points.length - 1) {
requestId = requestAnimationFrame(animate);
}
ctx.beginPath();
ctx.moveTo(points[t - 1].x, points[t - 1].y);
ctx.lineTo(points[t].x, points[t].y);
ctx.stroke();
t++;
}
// Clear the canvas before drawing
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Assign coordinates
if (contentId == 'about') {
vertices.push({x: 50, y: 0}, {x: 50, y: 50});
vertices.push({x: 40, y: 60}, {x: 0, y: 60});
// Animate lines
ctx.lineCap = "round";
ctx.lineWidth = border;
ctx.strokeStyle = "green";
var points = calcWaypoints(vertices);
animate(points);
}
if (contentId == 'contact') {
vertices.push({x: 150, y: 0}, {x: 150, y: 50});
vertices.push({x: 160, y: 60}, {x: 300, y: 60});
vertices.push({x: 300, y: 70}, {x: 310, y: 70});
ctx.lineCap = "round";
ctx.lineWidth = border;
ctx.strokeStyle = "green";
var points = calcWaypoints(vertices);
animate(points);
}
}
我希望这是有道理的!
我目前正在编写一个网站,点击导航 link,HTML canvas 会在相关内容框上画一条线 (我使用了 markE 的这里的精彩答案 作为动画教程)。我正在制作这些线条的动画,我 运行 进入以下问题:
如何在单击另一个 link 时阻止第一个动画完成?
我试过多次创建标志和 cancelAnimationFrame,但都没有成功。
这是一些简化的代码,目前使用了一个标志:
HTML
<div class="container">
<nav>
<ul>
<li>
<a href="#about" id="about" onclick="draw(this.id);">About</a>
</li>
<li>
<a href="#contact" id="contact" onclick="draw(this.id);">Work</a>
</li>
</ul>
</nav>
</div>
<canvas id="canvas" width="500" height="500"></canvas>
JavaScript
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var isRunning = false;
function draw(contentId) {
if (isRunning) return;
isRunning = true;
var t = 1;
var vertices = [];
function calcWaypoints(vertices) {
var waypoints = [];
for (var i = 1; i < vertices.length; i++) {
var pt0 = vertices[i - 1];
var pt1 = vertices[i];
var dx = pt1.x - pt0.x;
var dy = pt1.y - pt0.y;
for (var j = 0; j < 100; j++) {
var x = pt0.x + dx * j / 100;
var y = pt0.y + dy * j / 100;
waypoints.push({
x: x,
y: y
});
}
}
return (waypoints);
}
function animate() {
if (t < points.length - 1) {
window.requestAnimationFrame(animate);
}
ctx.beginPath();
ctx.moveTo(points[t - 1].x, points[t - 1].y);
ctx.lineTo(points[t].x, points[t].y);
ctx.stroke();
t++;
isRunning = false;
}
// Clear the canvas before drawing
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Assign coordinates
if (contentId == 'about') {
vertices.push({x: 50, y: 0}, {x: 50, y: 50});
vertices.push({x: 40, y: 60}, {x: 0, y: 60});
// Animate lines
ctx.lineCap = "round";
ctx.lineWidth = border;
ctx.strokeStyle = "green";
var points = calcWaypoints(vertices);
animate(points);
}
if (contentId == 'contact') {
vertices.push({x: 150, y: 0}, {x: 150, y: 50});
vertices.push({x: 160, y: 60}, {x: 300, y: 60});
vertices.push({x: 300, y: 70}, {x: 310, y: 70});
ctx.lineCap = "round";
ctx.lineWidth = border;
ctx.strokeStyle = "green";
var points = calcWaypoints(vertices);
animate(points);
}
}
重申一下,以防我不清楚:当我点击 'about' 然后直接点击 'contact' 时,我想要我第一次初始化时初始化的绘制动画单击 'about' 完全停止(包括清除 canvas),然后 'contact' 动画开始。目前,'contact' 动画确实开始了,但 'about' 动画也坚持要结束。当我点击 'about' 两次时发生同样的事情 - 动画同时运行两次...
如果它对任何人有帮助,我设法解决了它(逻辑上有一些错误,cancelAnimationFrame 最终做了我需要的而不是使用标志):
HTML
<div class="container">
<nav>
<ul>
<li>
<a href="#about" id="about" onclick="checkDraw(this.id);">About</a>
</li>
<li>
<a href="#contact" id="contact" onclick="checkDraw(this.id);">Work</a>
</li>
</ul>
</nav>
</div>
<canvas id="canvas" width="500" height="500"></canvas>
JavaScript
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var requestId;
function checkDraw(contentId) {
stopAnimation();
draw(contentId);
}
function stopAnimation(e) {
cancelAnimationFrame(requestId);
}
function draw(contentId) {
currentID = contentId;
var t = 1;
var vertices = [];
function calcWaypoints(vertices) {
var waypoints = [];
for (var i = 1; i < vertices.length; i++) {
var pt0 = vertices[i - 1];
var pt1 = vertices[i];
var dx = pt1.x - pt0.x;
var dy = pt1.y - pt0.y;
for (var j = 0; j < 100; j++) {
var x = pt0.x + dx * j / 100;
var y = pt0.y + dy * j / 100;
waypoints.push({
x: x,
y: y
});
}
}
return (waypoints);
}
function animate() {
if (t < points.length - 1) {
requestId = requestAnimationFrame(animate);
}
ctx.beginPath();
ctx.moveTo(points[t - 1].x, points[t - 1].y);
ctx.lineTo(points[t].x, points[t].y);
ctx.stroke();
t++;
}
// Clear the canvas before drawing
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Assign coordinates
if (contentId == 'about') {
vertices.push({x: 50, y: 0}, {x: 50, y: 50});
vertices.push({x: 40, y: 60}, {x: 0, y: 60});
// Animate lines
ctx.lineCap = "round";
ctx.lineWidth = border;
ctx.strokeStyle = "green";
var points = calcWaypoints(vertices);
animate(points);
}
if (contentId == 'contact') {
vertices.push({x: 150, y: 0}, {x: 150, y: 50});
vertices.push({x: 160, y: 60}, {x: 300, y: 60});
vertices.push({x: 300, y: 70}, {x: 310, y: 70});
ctx.lineCap = "round";
ctx.lineWidth = border;
ctx.strokeStyle = "green";
var points = calcWaypoints(vertices);
animate(points);
}
}
我希望这是有道理的!