Javascript 如何用背景图像在画布上画一条线

Javascript 如何用背景图像在画布上画一条线,javascript,html,canvas,Javascript,Html,Canvas,我试图在画布上画一条线(我可以这么做),但我想使用背景图像在这条线上放置一个重复的图案(除非有其他方法在画布上的一条线上放置一个重复的背景图像?) 如何用背景图像画一条线 我理解剪裁的概念,但这似乎只适用于形状。。。一笔也没有。有什么想法吗 下面是我尝试的一小部分 你不是在用第二个drawImage电话画所有的东西吗 编辑:是的,但这不是你的意思,尝试开始和关闭路径 ctx.beginPath(); ctx.moveTo(0,0) ctx.lineTo(100,100) ctx.lin

我试图在画布上画一条线(我可以这么做),但我想使用背景图像在这条线上放置一个重复的图案(除非有其他方法在画布上的一条线上放置一个重复的背景图像?)

如何用背景图像画一条线

我理解剪裁的概念,但这似乎只适用于形状。。。一笔也没有。有什么想法吗

下面是我尝试的一小部分


你不是在用第二个drawImage电话画所有的东西吗

编辑:是的,但这不是你的意思,尝试开始和关闭路径

 ctx.beginPath();
 ctx.moveTo(0,0)
 ctx.lineTo(100,100)
 ctx.lineTo(100,0);
 ctx.closePath()
 ctx.lineWidth = 10;
 ctx.stroke();
 ctx.clip();

 ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height);

我看到两种解决办法:

  • 构建与粗线对应的多边形,然后将图像填充为图案。基本上,这需要计算切线并做一些数学计算。我在这里写了一篇关于类似问题的小文章:

    你可以在这里看到小提琴:
代码是这样的,基本上你想要一个w1=w2(相同的开始/结束厚度)的varLine

  • 第二种解决方案非常快:使用GlobalComposite操作模式为您进行剪裁。 例如,绘制线条,使用“源输入”,然后在线条顶部绘制图像。
    这是非常方便的,但是这里的问题是,只有在画线之前画布是干净的,它才会起作用。如果您可以自由选择绘制顺序,这不是问题,否则,您必须在临时画布中绘制线条,然后在主画布上绘制画布
更新的小提琴在这里:

编辑:用提琴重复图像:


[使用图像画线]

您可以使用此实用程序功能确定直线段上的任何百分点:

    function getLineXYatPercent(startPt,endPt,percent) {
        var dx = endPt.x-startPt.x;
        var dy = endPt.y-startPt.y;
        var X = startPt.x + dx*percent;
        var Y = startPt.y + dy*percent;
        return( {x:X,y:Y} );
    }
在这之后,沿着每条线段重复定位图像只需要一点数学知识:

    var dx=points[i].x-points[i-1].x;
    var dy=points[i].y-points[i-1].y;
    var length=Math.sqrt(dx*dx+dy*dy);
    var pctImage=imgWidth/length;
    for(var pct=pctImage/2;pct<1.00;pct+=pctImage){
         var pos=getLineXYatPercent(points[i-1],points[i],pct);
         ctx.drawImage(img,0,0,img.width,img.height,pos.x,pos.y,imgWidth,imgHeight);
    }   
var dx=points[i].x-points[i-1].x;
var dy=点[i].y-点[i-1].y;
变量长度=数学sqrt(dx*dx+dy*dy);
var pctImage=imgWidth/长度;
对于(var pct=pctImage/2;pct

我有点迟了,但是既然不需要使用剪辑或计算矢量,你可以考虑使用内置的支持(这更快),简单地设置一个笔画样式,作为一个图像样式:

var pattern = ctx.createPattern(image, 'repeat');  /// create pattern
ctx.strokeStyle = pattern;                         /// set as stroke style

ctx.moveTo(10, 10);
ctx.lineTo(200, 200);
ctx.lineWidth = 10;
ctx.stroke();                           /// strokes with the image as background

如果要更改图案大小,只需更改在本例中使用的画布(“code>图像”
)的大小:

<canvas id="image" width=100 height=100></canvas>

如果在绘制时需要调整图案的位置,则可以使用先平移的增量值,然后减去要使用图案绘制的线的位置,使用
translate()
,这将使线保持与平移前相同的位置,但移动图案本身:

ctx.translate(dx, dy);
ctx.moveTo(x1 - dx, y1 - dy);
ctx.lineTo(x2 - dx, y2 - dy);
...

这里没有什么大问题,但是你的帖子应该是评论而不是回答。为什么?我提供了一个潜在的答案,第二个drawImage调用在整个画布上绘制。因此我提供了一个答案而不是评论。在你编辑之前,这是一篇一行的帖子,仅此而已。尝试提供代码和小提琴,我试图让你的Idea的工作失败了…谢谢!这似乎起作用了。有没有办法使图像在x轴和y轴上重复?不客气。我想你是在谈论第二种解决方案:当然:不是drawImage,而是基于图像填充图案(图像加载时只创建一次)(创建图案就是复制,所以不要在循环/动画中创建图案。)@Bill:我只是为重复做了一个小例子。谢谢……从你的评论中得到了……只是需要一个正确的方向!好的。我只是想100%确定这个建议是好的,并分享图片!:-)是的,我一直忘了模式的有用性——我该死的记忆:)在你的演示中,#2是
延迟
最终控制重复模式之间的间隔吗?@markE噢,
延迟
++只是OPs原始小提琴的剩余部分。我只是在essential周围剪了一点,让它更清晰(如答案中所示)-我没有清除其他位(让代码在某种程度上可以被OP识别)。基于插值的拖尾线看起来不错!
var pattern = ctx.createPattern(image, 'repeat');  /// create pattern
ctx.strokeStyle = pattern;                         /// set as stroke style

ctx.moveTo(10, 10);
ctx.lineTo(200, 200);
ctx.lineWidth = 10;
ctx.stroke();                           /// strokes with the image as background
<canvas id="image" width=100 height=100></canvas>
ctxImg.drawImage(img, 0, 0, canvas1.width, canvas1.height);
ctx.translate(dx, dy);
ctx.moveTo(x1 - dx, y1 - dy);
ctx.lineTo(x2 - dx, y2 - dy);
...