1

嗨,我有以下代码在画布上生成螺旋,我想要的是在绘制螺旋时对其进行动画处理,此时使用下面的代码,当页面加载时螺旋被完全绘制。我想看到正在绘制的螺旋。我想使用 requestAnimationFrame 来完成这项工作。

我的 html

<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" href="styles.css">
<meta charset="utf-8">
    <title>Spiral</title>
</head>
<body>
    <canvas id="canvas" style="border: 1px solid black" width="300" height="300"></canvas>
<script src="scripts.js"></script>
</body>
</html>

和我的 Javascript

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
ctx.moveTo(centerX,centerY);


    var gap =2;
    var steps = 60;

    var increment = 2*Math.PI/steps;
    var theta = increment;

while(theta < 20*Math.PI) {
    var newX = centerX + theta * Math.cos(theta) * gap;
    var newY = centerY + theta * Math.sin(theta) * gap;
    ctx.lineTo(newX,newY);
    theta = theta + increment;
}
ctx.stroke();

请参阅 jsfiddle https://jsfiddle.net/gustav1105/hx8tm43k/

4

2 回答 2

2

要使用动画window.requestAnimationFrame(yourFunction);,这将调用同步到屏幕并与浏览器同步的函数,以提供最佳的动画性能。它还将传递它调用的函数,以毫秒为单位。

我刚刚添加了一个update清除屏幕的功能。然后用一个小模块调用你的螺旋,根据时间对其进行动画处理。然后更新函数请求一个新的帧并退出。

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
ctx.lineWidth = 3;
function drawSpiral(time) {
    var angOff, gap, steps, increment, theta, newX, newY;
    // use time to get an angle offset
    angOff = time / -60;
    ctx.beginPath();
    ctx.moveTo(centerX, centerY);
    gap = 2;
    steps = 60;
    increment = 2 * Math.PI / steps;
    theta = increment;
    while (theta < 20 * Math.PI) {
        newX = centerX + theta * Math.cos(theta + angOff) * gap;
        newY = centerY + theta * Math.sin(theta + angOff) * gap;
        ctx.lineTo(newX, newY);
        theta = theta + increment;
    }
    ctx.stroke();
}
function update(time) { // called by browser through requestAnimationFrame
    // time is the current time in milliseconds

    // clear the canvas
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    // draw the spiral animating via the time
    drawSpiral(time);

    // this gets the next animation frame
    // that is in sync with the browsers rendering and
    // will keep in sync with the screen refresh so you dont
    // get any shearing
    requestAnimationFrame(update); //' request next animation frame
}
// start the animation
requestAnimationFrame(update);
	<canvas id="canvas" style="border: 1px solid black" width="300" height="300"></canvas>

于 2016-01-13T19:59:39.723 回答
1

我假设您希望动画在给定的时间跨度(例如 4 秒)内绘制螺旋。我将您的绘图代码放在 update() 函数中。我用 update() 函数调用了 requestAnimationFrame 函数。第一次调用update()函数时,我记录了动画的开始时间。然后我通过从开始时间减去当前时间戳然后除以所需的总时间(例如 4 秒 = 4000 毫秒)来计算绘图进度(0 = 开始,1 = 结束)。然后,我绘制了当前进度的螺旋线。如果螺旋不完整(即进度 < 1),则再次调用 requestAnimationFrame() 函数。

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
var gap = 2;
var steps = 60;
var increment = 2 * Math.PI / steps;
var start = null;
function update(timeStamp) {
    if (!start) {
        start = timeStamp;
    }
    var progress = Math.min((timeStamp - start) / 4000, 1);
    var theta = increment;
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.moveTo(centerX,centerY);
    while (theta < progress * 20 * Math.PI) {
        var newX = centerX + theta * Math.cos(theta) * gap;
        var newY = centerY + theta * Math.sin(theta) * gap;
        ctx.lineTo(newX,newY);
        theta = theta + increment;
    }
    ctx.stroke();
    if (progress < 1) {
        requestAnimationFrame(update);
    }
}
requestAnimationFrame(update);
<canvas id="canvas" style="border: 1px solid black" width="300" height="300"></canvas>

于 2016-01-13T21:43:46.267 回答