How to draw a line in canvas with a background image

canvas, html, javascript

Solution

I see two solutions :

- Build the polygon that corresponds to the thick line, then fill it with your image as pattern. Basically this requires to compute the tangent and do a little math. i wrote a small article about a similar issue here : http://gamealchemist.wordpress.com/2013/08/28/variable-width-lines-in-html5-canvas/ you can see the fiddle here : http://jsfiddle.net/gamealchemist/GCwVU/

The code is this one, basically you want a varLine with w1 = w2 (same start / end thickness) ;

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

- Second solution is very quick : use the globalCompositeOperation modes to do the clipping for you. for instance draw the line, use 'source-in', then draw the image on top of the line. This is very handy, but the issue here is that it will work only if the canvas was clean before the line draw. If you can choose freely drawing order, this is not an issue, otherwise, you'll have to draw the line in a temp canvas, then draw the canvas on the main canvas.

Updated fiddle is here : http://jsfiddle.net/gamealchemist/Z9cd7/1/

Edit : fiddle for the image with repetitions : http://jsfiddle.net/gamealchemist/Z9cd7/2/

Problem

I'm trying to draw a line in canvas (which I can do), but I want to put a repeating pattern on the line using a background image (unless there is another way to put a repeating background image on a line in canvas?). How can I draw a line with a background image? I understand the concept of clipping, but that only seems to work with shapes... not with a stroke. Any ideas? Here is a jsfiddle of what I was trying 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"; ```

Original source