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();
}
Share:
12,252

Related videos on Youtube

Glebka
Author by

Glebka

Updated on June 04, 2022

Comments

  • Glebka
    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
    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 and fill_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
    mokagio over 9 years
    save and restore seems like tidier way to do it.
  • Xenethyl
    Xenethyl about 9 years
    For something as trivial as applying a single transformation to the context I would not recommend using save() and restore(). 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
    cacheflowe about 8 years
    A 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 :)