我使用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
答案 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);