我正在尝试在画布上绘制一条线(我可以这样做),但我想使用背景图像在线上放置重复图案(除非有另一种方法将重复的背景图像放在一条线上在画布?)。
如何使用背景图像绘制线条?
我理解剪辑的概念,但这似乎只适用于形状...而不是笔画。有任何想法吗?
这是我尝试的一个方面 http://jsfiddle.net/Z9cd7/
function (callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
var radius = 50;
var x = 100;
var dx = 10;
var y = 100;
var dy = 10;
var delay = 10;
var img = new Image();
img.onload = function () {
var canvas1 = document.getElementById("image");
var ctxImg = canvas1.getContext("2d");
ctxImg.drawImage(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height);
/*
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save();
ctx.beginPath();
ctx.arc(100, 100, radius, 0, 2 * Math.PI, false);
ctx.clip();
ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height);
ctx.restore();
*/
ctx.moveTo(0,0)
ctx.lineTo(100,100)
ctx.lineWidth = 10;
ctx.stroke()
ctx.clip();
ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height);
ctx.restore();
//animate();
}
img.src = "http://lh3.ggpht.com/_Z-i7eF_ACGI/TRxpFywLCxI/AAAAAAAAAD8/ACsxiuO_C1g/house%20vector.png";
答案 0 :(得分:3)
我看到两个解决方案:
代码就是这个,基本上你想要一个w1 = w2的varLine(相同的开始/结束厚度);
// varLine : draws a line from A(x1,y1) to B(x2,y2)
// that starts with a w1 width and ends with a w2 width.
// relies on fillStyle for its color.
// ctx is a valid canvas's context2d.
function varLine(ctx, x1, y1, x2, y2, w1, w2) {
var dx = (x2 - x1);
var dy = (y2 - y1);
w1 /= 2; // we only use w1/2 and w2/2 for computations.
w2 /= 2;
// length of the AB vector
var length = Math.sqrt(sq(dx) + sq(dy));
if (!length) return; // exit if zero length
var shiftx = -dy * w1 / length; // compute AA1 vector's x
var shifty = dx * w1 / length; // compute AA1 vector's y
ctx.beginPath();
ctx.moveTo(x1 + shiftx, y1 + shifty);
ctx.lineTo(x1 - shiftx, y1 - shifty); // draw A1A2
shiftx = -dy * w2 / length; // compute BB1 vector's x
shifty = dx * w2 / length; // compute BB1 vector's y
ctx.lineTo(x2 - shiftx, y2 - shifty); // draw A2B1
ctx.lineTo(x2 + shiftx, y2 + shifty); // draw B1B2
ctx.closePath(); // draw B2A1
ctx.fill();
}
更新的小提琴在这里: http://jsfiddle.net/gamealchemist/Z9cd7/1/
编辑:重复图像的小提琴: http://jsfiddle.net/gamealchemist/Z9cd7/2/
答案 1 :(得分:2)
我有点迟了但是由于不需要同时使用剪裁或计算向量,你可以考虑使用内置的支持(这更快),只需设置一个带有图像模式的笔触样式作为样式: / p>
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
如果你想改变图案尺寸,只需改变你在这种情况下使用的画布大小(“image
”):
<canvas id="image" width=100 height=100></canvas>
并在onload
处理程序中进行修改,以便缩放图像以适合画布:
ctxImg.drawImage(img, 0, 0, canvas1.width, canvas1.height);
如果您需要在绘制时调整图案的位置,可以使用translate()
使用首先翻译的delta值,然后减去要用图案绘制的线条的位置 - 将字符保持在与翻译前相同的位置,但移动模式本身:
ctx.translate(dx, dy);
ctx.moveTo(x1 - dx, y1 - dy);
ctx.lineTo(x2 - dx, y2 - dy);
...
答案 2 :(得分:1)
[使用图片绘制线条]
您可以使用此实用程序功能确定沿线段的任何百分点:
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);
}
演示:http://jsfiddle.net/m1erickson/R278u/
代码:
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: lightgray; }
#canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var $canvas=$("#canvas");
var canvasOffset=$canvas.offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var scrollX=$canvas.scrollLeft();
var scrollY=$canvas.scrollTop();
var isDown=false;
var points=[];
points.push({x:0,y:0});
points.push({x:100,y:125});
points.push({x:200,y:75});
points.push({x:300,y:100});
imgWidth=20;
imgHeight=20;
var img=new Image();
img.onload=function(){
draw();
}
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/house%20vector.png";
function draw(){
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.save();
ctx.beginPath();
ctx.moveTo(points[0].x,points[0].y);
for(var i=1;i<points.length;i++){
var p=points[i];
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);
}
}
}
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} );
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
答案 3 :(得分:0)
你不是只是用第二个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);