html画布动画曲线

时间:2017-10-17 12:30:58

标签: javascript canvas html5-canvas

我使用canvas quadraticCurveTo相互连接创建了一些线条。我的目标是为这些线条制作动画。 我有一个使用lineTo方法的例子,如何为quadraticCurveTo方法更改它?

(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, element) {
    var currTime = new Date().getTime();
    var timeToCall = Math.max(0, 16 - (currTime - lastTime));
    var id = window.setTimeout(function () {
        callback(currTime + timeToCall);
    },
    timeToCall);
    lastTime = currTime + timeToCall;
    return id;
};

示例链接:http://jsfiddle.net/m1erickson/7faRQ/

我的期望:example image

2 个答案:

答案 0 :(得分:1)

沿路径的动画

要做小提琴,但使用任何路径功能,您可以使用线划线来设置绘制的路径数量。这将为您提供沿着恒定速度的路径的动画。

此方法的唯一问题是您不知道路径有多长。要知道这涉及一些相当复杂的数学(警告一些贝塞尔长度解决方案是近似值)。

在这个例子中,我用眼睛来计算长度。

requestAnimationFrame(loop);
const ctx = canvas.getContext("2d");
ctx.lineCap = "round";
const lines = [[10, 10], [300, 10, 250, 200], [100, 300, 20, 120, 10, 10]];
const render = {
   "2"(p) { ctx.lineTo(...p) },
   "4"(p) { ctx.quadraticCurveTo(...p) },   
   "6"(p) { ctx.bezierCurveTo(...p) },   
   start(width, col) { ctx.lineWidth = width; ctx.strokeStyle = col; ctx.beginPath() }
}
var startTime;
const len = 760;
function loop(time) {
   if(startTime === undefined){ startTime = time }
   const animTime = time - startTime;
   ctx.clearRect(0, 0, 300, 300);
   ctx.setLineDash([1, 0]);
   render.start(1,"blue")
   lines.forEach(l => render[l.length](l));
   ctx.stroke();
   ctx.setLineDash([(animTime / 10) % len, 10000]);
   render.start(8, "red")
   lines.forEach(l => render[l.length](l));
   ctx.stroke();
   requestAnimationFrame(loop);
}
canvas { border : 2px solid black; }
<canvas id="canvas"  width = 300 height = 300></canvas>

答案 1 :(得分:0)

我知道这个问题有点老了,但是对于这个问题的变体,SO充满了不好的答案,直到我找到这个问题之前,我都没有找到好的解决方案。 @ Blindman67使用setLineDash指向了正确的方向,以下内容对我来说很漂亮。 rnd2()返回该范围内的随机整数(但您始终可以使用常数或参数),而curve()计算其曲线的快速粗略近似长度(弦和段总长度的平均值),用1.2乘以确保我不会过去。我的setLineDash调用适用于alpha <1.0,因为它不会重复绘制曲线,也不会花费额外的时间来计算较长的不可见的空白。 raf()是requestAnimationFrame。

var lineLen = 0, delta = rnd2(20, 80);
var approxCurveLen = curves(c0.width, c0.height, ctx, false) * 1.2;
var step = () =>
{
    if (lineLen < approxCurveLen)
    {
        ctx.setLineDash([0, lineLen, delta, approxCurveLen-lineLen]);
        ctx.stroke();
        lineLen += delta;
        raf(step);
    }
    else
    {
        ctx.setLineDash([]);
    }
};
raf(step);