及时绘制 HTML5/Javascript 画布路径

Draw HTML5/Javascript Canvas Path in Time(及时绘制 HTML5/Javascript 画布路径)
本文介绍了及时绘制 HTML5/Javascript 画布路径的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一条路径:

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.

How can I split the path into subpaths of given length? For example: context.splitCurrentPathIntoSubPath(0, 0.75) should return only the first 3/4 of the path.

我想用它来实现动画.如果有更简单的方法,也欢迎.

I would like to use this to realise an animation. If there is an easier method, it is also welcome.

推荐答案

我在使用 D3.js 为 SVG 弧线制作动画时遇到了类似的问题.我的解决方案借鉴了这一点.它不是最直观的,但通常用于 D3 动画.它需要仔细设置虚线偏移和线长.CSS Tricks 很好地解释了这里的技术,我强烈建议在查看我的代码之前阅读它.

I came across a similar problem when animating SVG arcs using D3.js. My solution borrows from that. It isn't the most intuitive, but is commonly used in D3 animations. It requires careful setting of the dash offset and line length. CSS Tricks gives a good explanation of the technique here which I strongly recommend reading before viewing my code.

我已经用这种技术修改了上面的 JSFiddle 在此处为您的线路实施.请注意,即使线路自行循环,这也会起作用.

I have modified the above JSFiddle with this technique implemented for your line here. Note this will work even if the line loops back on itself.

关于行长的说明:

此实现要求您知道行的大​​致长度,以便您可以将长度 var 设置为大于它.对于贝塞尔曲线和二次曲线,这很棘手,但仍然可以完成(这个 SO 问题看起来很有希望).对于我的演示,我通过反复试验发现你的大约是 608 像素.将长度设置为 10000 可能会确保您的线条始终正确绘制,但代价是每毫秒调用大量不必要的间隔回调.底线是:如果您关心性能,请找出贝塞尔公式;如果不这样做,请将该变量设置为高.

This implementation requires you to know the approx length of your line so that you can set the length var to be greater than it. For bezier and quadratic curves this is tricky but can nevertheless be done (this SO question looks promising). For my demo I used trial and error to find that yours was about 608px. Setting length to 10000 will probably ensure your lines always draw correctly, but at the cost of having lots of needless interval callbacks called every millisecond. The bottom line is: if you care about performance, figure out the bezier formula stuff; if you don't, set that variable high.

代码:

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();
}

这篇关于及时绘制 HTML5/Javascript 画布路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Update another component when Formik form changes(当Formik表单更改时更新另一个组件)
Formik validation isSubmitting / isValidating not getting set to true(Formik验证正在提交/isValiating未设置为True)
React Validation Max Range Using Formik(使用Formik的Reaction验证最大范围)
Validation using Yup to check string or number length(使用YUP检查字符串或数字长度的验证)
Updating initialValues prop on Formik Form does not update input value(更新Formik表单上的初始值属性不会更新输入值)
password validation with yup and formik(使用YUP和Formick进行密码验证)