假设我有一条路:
var context = canvas.getContext('2d');
context.beginPath();
context.moveTo(100, 20);
context.lineTo(200, 160);
context.quadraticCurveTo(230, 200, 250, 120);
context.bezierCurveTo(290, -40, 300, 200, 400, 150);
context.lineTo(500, 90);
context.lineWidth = 5;
context.strokeStyle = 'blue';
context.stroke();
这将一次打印所有路径:
如何将路径分成给定长度的子路径?例如:context.splitCurrentPathIntoSubPath(0, 0.75)
应该只返回路径的前3/4。
我想用它来实现动画。如果有更简单的方法,也欢迎您。
使用D3.js为SVG弧线设置动画时遇到了类似的问题。我的解决方案是从中借用的。它不是最直观的,但通常用于D3动画中。需要仔细设置破折号偏移和行长。CSS技巧在这里很好地解释了该技术,我强烈建议在查看代码之前阅读该技术。
我已经在此处为您的生产线实现了此技术,从而修改了上面的JSFiddle 。请注意,即使线本身回绕,这也将起作用。
关于行长的注释:
此实现要求您知道行的大约长度,以便可以将长度var设置为大于该长度。对于贝塞尔曲线和二次曲线,这很棘手,但还是可以做到的(这个SO问题看起来很有希望)。对于我的演示,我通过反复试验发现您的像素约为608px。将length设置为10000可能会确保您的线条始终正确绘制,但是代价是有很多不必要的间隔回调(每毫秒调用一次)。底线是:如果您关心性能,请找出贝塞尔曲线公式的内容;如果不这样做,则将该变量设置为高。
码:
的HTML
<body>
<canvas id="canvas" width="500" height="500">
webgl couldn't be started
</canvas>
</body>
的JavaScript
canvasHolder = document.getElementById( 'canvas' );
context = canvasHolder.getContext('2d');
context.fillStyle = 'white';
var w = canvasHolder.width, h = canvasHolder.height;
context.fillRect( 0, 0, w, h);
//set the direction the line draws in
//1->ltr | -1->rtl
var dir = -1;
//IMPORTANT: this must be set to greater than the length
//of the line
var length = 608;
//the speed of the line draw
var speed = 1;
var progress = 0;
var lineInterval;
//Go!
context.globalCompositeOperation='copy';
drawLine();
function drawLine() {
//this clears itself once the line is drawn
lineInterval = setInterval(updateLine, 1);
}
function updateLine() {
//define the line
defineLine();
if(progress<length)
{
progress+=speed;
moveDash(progress, dir);
} else {
clearInterval(lineInterval);
}
}
function defineLine() {
context.beginPath();
context.moveTo(100, 20);
context.lineTo(200, 160);
context.quadraticCurveTo(230, 200, 250, 120);
context.bezierCurveTo(290, -40, 300, 200, 400, 150);
context.lineTo(500, 90);
context.lineWidth = 5;
context.strokeStyle = 'blue';
}
function moveDash(frac, dir) {
//default direction right->left
var dir = dir || -1
context.setLineDash([length]);
context.lineDashOffset = dir*(frac+length);
context.stroke();
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句