Moving the start position of canvas pattern
12,252
Solution 1
You can achieve this by translating the canvas, drawing on it, and then translating it back to where you started:
function draw(ctx) {
// create new image object to use as pattern
var img = new Image();
img.onload = function(){
// create pattern
var ptrn = ctx.createPattern(img,'repeat');
ctx.fillStyle = ptrn;
// offset vars
var offset_x = 60;
var offset_y = 75;
var fill_x = 500; // could be canvas.width
var fill_y = 500; // could be canvas.height
// offset
ctx.translate(offset_x, offset_y);
// draw
ctx.fillRect(-offset_x, -offset_y, fill_x, fill_y);
// undo offset
ctx.translate(-offset_x, -offset_y);
}
img.src = 'images/wallpaper.png?' + new Date().getTime();
}
Solution 2
In response to the accepted answer: rather than undo the offset, I would use save()
& restore()
to avoid potential problems:
ctx.save();
ctx.translate(offset_x, offset_y);
ctx.fillRect(-offset_x, -offset_y, fill_x, fill_y);
ctx.restore();
Solution 3
More general, complex transforms of the pattern alone are easily done. The trick is to do them immediately before the call to fill() or stroke().
function draw(ctx) {
// create new image object to use as pattern
var img = new Image();
img.onload = function(){
// create pattern
var ptrn = ctx.createPattern(img,'repeat');
ctx.fillStyle = ptrn;
ctx.beginPath();
ctx.rect(0, 0, 150, 150);
ctx.translate(-33, -33);
ctx.fill();
}
img.src = 'images/wallpaper.png?' + new Date().getTime();
}
Related videos on Youtube
Author by
Glebka
Updated on June 04, 2022Comments
-
Glebka almost 2 years
I have a code:
function draw(ctx) { // create new image object to use as pattern var img = new Image(); img.onload = function(){ // create pattern var ptrn = ctx.createPattern(img,'repeat'); ctx.fillStyle = ptrn; ctx.fillRect(0,0,150,150); } img.src = 'images/wallpaper.png?' + new Date().getTime(); }
How can i move the start position of pattern image?
-
Xenethyl over 12 years@GLeBaTi I just edited the code I posted here slightly. The important change is that the call to
fillRect()
only fills a region of the size you request (ie.fill_x
andfill_y
) because we pass the origin in as our offset. I also adjusted the signs on the offset used for the translate calls to make the results a bit more intuitive. -
mokagio over 9 years
save
andrestore
seems like tidier way to do it. -
Xenethyl about 9 yearsFor something as trivial as applying a single transformation to the context I would not recommend using
save()
andrestore()
. There is overhead associated with manipulating the state stack (albeit minimal), and if you do this for every simple transformation you'll be taking an unnecessary performance hit. See this jsPerf (which I take no credit for) for a quick comparison: jsperf.com/canvas-transform-vs-save-restore/2 -
cacheflowe about 8 yearsA little more than a year later, the perf test above now says that save/restore is faster than re-translating (at least in Firefox & Chrome on OS X). For something this simple, performance concerns shouldn't necessarily trump simplicity & readability. But, as with any code, we all have our personal preferences :)