[英]How to keep smooth lines when drawing out animated bezier curves in html5 canvas
I finally found out how to animate drawing a bezier curve. 我终于找到了如何绘制bezier曲线的动画。 I've seen other solutions that use quadratic curves to do it, but I needed 4 points for what I was doing, and b-spline was too difficult finding random plots, plus it's just how I want to do it;
我已经看到其他解决方案使用二次曲线来做到这一点,但我需要4点才能完成我的工作,并且b-spline太难找到随机图,而且它只是我想要的方式; with Bezier Cuves.
与Bezier Cuves。
My issue is I can't find a good, fast speed without seeing the dots or lines. 我的问题是,如果没有看到点或线,我找不到好的,快速的速度。 I've gotta be missing something.
我一定会错过一些东西。 Could someone point out my error or a more efficient way to get this going smoothly at any time/speed?
有人可以指出我的错误或更有效的方式在任何时间/速度顺利进行吗? I need it to be steady and go faster than the example below, but if I do anymore the gaps get larger and larger...
我需要它稳定并且比下面的例子更快,但是如果我再做的话,差距越来越大......
fiddle with code: https://jsfiddle.net/qzsy8aL7/ 小提琴代码: https : //jsfiddle.net/qzsy8aL7/
//B(t) = (1 - t)^3P0 + 3t(1 - t)^2 P1 + 3t^2(1 - t)P2 + t^3P3
function animatedBSpline(context, points, t) {
// Draw curve segment
context.beginPath();
context.moveTo(
Math.pow(1 - t, 3) * points[0].x +
3 * t * Math.pow(1 - t, 2) * points[1].x +
3 * Math.pow(t, 2) * (1 - t) * points[2].x +
Math.pow(t, 3) * points[3].x,
Math.pow(1 - t, 3) * points[0].y +
3 * t * Math.pow(1 - t, 2) * points[1].y +
3 * Math.pow(t, 2) * (1 - t) * points[2].y +
Math.pow(t, 3) * points[3].y
);
// Draw spline segemnts
context.lineTo(
Math.pow((1 - t) + 0.001, 3) * points[0].x +
3 * (t + 0.001) * Math.pow((1 - t) + 0.001, 2) * points[1].x +
3 * Math.pow(t + 0.001, 2) * (1 - (t + 0.001)) * points[2].x +
Math.pow(t + 0.001, 3) * points[3].x,
Math.pow((1 - t) + 0.001, 3) * points[0].y +
3 * (t + 0.001) * Math.pow((1 - t) + 0.001, 2) * points[1].y +
3 * Math.pow(t + 0.001, 2) * (1 - (t + 0.001)) * points[2].y +
Math.pow(t + 0.001, 3) * points[3].y
);
//33d4ff
context.strokeStyle="#35bb23";
context.lineJoin="round";
context.lineWidth=2;
context.fillStyle = "black";
context.stroke();
context.fill();
// Keep going until t = 1
if (t < 1) requestAnimationFrame(function() {
animatedBSpline(context, points, t + 0.01);
});
else
context.closePath();
}
If any more information is needed please let me know. 如果需要更多信息,请告诉我。 I've been at this all day.
我整天都在这里。
To add: If I just outright draw it with these plots, and not animate it being done, it looks fine, obviously, but just wanted to point that out. 补充一点:如果我只是用这些情节直接绘制它,而不是为它做动画,它看起来很好,显然,但只是想指出这一点。 Its something with the way I'm animating it I just don't know.
它与我动画它的方式有关,我只是不知道。
Here's the full updated code with animation of green bezier curve: 这是带有绿色贝塞尔曲线动画的完整更新代码:
(function() { var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame; $(function() { var canvas = $('#drawings')[0]; var context = canvas.getContext('2d'); var lineLength = 0; var lineLengthMax = 7; var timer; // Define points var points = [[{ x: 600, y: 200 }, { x: 550, y: 100 }, { x: 350, y: 100 }, { x: 300, y: 250 }], [{ x: 350, y: 250 }, { x: 75, y: 225 }, { x: 30, y: 400 }, { x: 120, y: 450 }], [{ x: 200, y: 450 }, { x: 5, y: 380 }, { x: 25, y: 750 }, { x: 175, y: 610 }], [{ x: 200, y: 520 }, { x: 150, y: 560 }, { x: 175, y: 750 }, { x: 325, y: 605 }], [{ x: 400, y: 395 }, { x: 275, y: 450 }, { x: 250, y: 750 }, { x: 565, y: 655 }], [{ x: 515, y: 540 }, { x: 500, y: 695 }, { x: 660, y: 675 }, { x: 675, y: 560 }], [{ x: 600, y: 400 }, { x: 790, y: 315 }, { x: 1005, y: 500 }, { x: 675, y: 585 }], [{ x: 500, y: 250 }, { x: 700, y: 100 }, { x: 775, y: 350 }, { x: 700, y: 380 }]]; //33d4ff context.strokeStyle="#35bb23"; context.lineJoin="round"; context.lineWidth=2; doLineDraw(); //animatedBSpline(context, points, 0); function doLineDraw() { if (lineLength <= lineLengthMax) { clearTimeout(timer); // Kick things off at t = 0 context.beginPath(); animatedBSpline(context, points[lineLength], 0); //animatedBSpline(context, eval('points'+(lineLength)), 0); lineLength++; if (lineLength <= lineLengthMax) timer = setTimeout(doLineDraw, 2000); } } //B(t) = (1 - t)^3P0 + 3t(1 - t)^2 P1 + 3t^2(1 - t)P2 + t^3P3 function animatedBSpline(context, points, t) { // Draw curve segment if (t == 0) context.moveTo( Math.pow(1 - t, 3) * points[0].x + 3 * t * Math.pow(1 - t, 2) * points[1].x + 3 * Math.pow(t, 2) * (1 - t) * points[2].x + Math.pow(t, 3) * points[3].x, Math.pow(1 - t, 3) * points[0].y + 3 * t * Math.pow(1 - t, 2) * points[1].y + 3 * Math.pow(t, 2) * (1 - t) * points[2].y + Math.pow(t, 3) * points[3].y ); // Draw spline segemnts context.lineTo( Math.pow((1 - t) + 0.001, 3) * points[0].x + 3 * (t + 0.001) * Math.pow((1 - t) + 0.001, 2) * points[1].x + 3 * Math.pow(t + 0.001, 2) * (1 - (t + 0.001)) * points[2].x + Math.pow(t + 0.001, 3) * points[3].x, Math.pow((1 - t) + 0.001, 3) * points[0].y + 3 * (t + 0.001) * Math.pow((1 - t) + 0.001, 2) * points[1].y + 3 * Math.pow(t + 0.001, 2) * (1 - (t + 0.001)) * points[2].y + Math.pow(t + 0.001, 3) * points[3].y ); //context.fillStyle = "black"; context.stroke(); //context.fill(); // Keep going until t = 1 if (t < 1) requestAnimationFrame(function() { animatedBSpline(context, points, t + 0.01); }); } }); }());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <section> <article> <canvas id="drawings" width="1000" height="1000" /> </article> </section>
A couple key points, some of which were tangential to the question. 一些关键点,其中一些与问题相关。
eval
for referencing variable names which have numbers post-fixed. eval
来引用具有后固定数字的变量名称。 Just use an array instead. context.beginPath()
and context.moveTo()
before every new vertex, which causes context.stroke()
and context.fill()
to "forget" the previous instructions. context.beginPath()
和context.moveTo()
,这导致context.stroke()
和context.fill()
“忘记”前面的指令。 I moved the context.beginPath()
outside of animatedBSpline()
and specified context.moveTo()
to run at t==0
within that function, that way there are no disjointed points. 我将
context.beginPath()
移动到animatedBSpline()
context.beginPath()
之外,并指定context.moveTo()
在该函数中的t==0
运行,这样就没有脱节点。 I hope that helps. 我希望有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.