Перемещение начальной позиции шаблона холста

#html #canvas

#HTML #холст

Вопрос:

У меня есть код:

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

Как я могу переместить начальную позицию изображения шаблона?

Ответ №1:

В ответ на принятый ответ: вместо того, чтобы отменять смещение, я бы использовал save() amp; restore() , чтобы избежать потенциальных проблем:

 ctx.save();
ctx.translate(offset_x, offset_y);
ctx.fillRect(-offset_x, -offset_y, fill_x, fill_y);
ctx.restore();
  

Комментарии:

1. save и restore кажется, что это более аккуратный способ сделать это.

2. Для чего-то столь же тривиального, как применение одного преобразования к контексту, я бы не рекомендовал использовать save() and restore() . С манипулированием стеком состояний связаны накладные расходы (хотя и минимальные), и если вы будете делать это для каждого простого преобразования, вы получите ненужный удар по производительности. Смотрите Этот jsPerf (который я не беру на себя ответственность) для быстрого сравнения: jsperf.com/canvas-transform-vs-save-restore/2

3. Чуть более года спустя приведенный выше тест perf теперь показывает, что сохранение / восстановление выполняется быстрее, чем повторный перевод (по крайней мере, в Firefox и Chrome на OS X). Для чего-то такого простого проблемы с производительностью не обязательно должны превалировать над простотой и удобочитаемостью. Но, как и в случае с любым кодом, у всех нас есть свои личные предпочтения 🙂

Ответ №2:

Вы можете добиться этого, переведя холст, нарисовав на нем, а затем переведя его обратно туда, откуда вы начали:

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

Комментарии:

1. @GLeBaTi Я только что немного отредактировал код, который я здесь разместил. Важным изменением является то, что вызов fillRect() только заполняет область запрошенного вами размера (т. е. fill_x и fill_y ) потому что мы передаем начало координат в качестве нашего смещения. Я также скорректировал знаки на смещении, используемые для вызовов translate, чтобы сделать результаты немного более интуитивно понятными.

Ответ №3:

Более общие, сложные преобразования одного шаблона легко выполняются. Хитрость заключается в том, чтобы выполнять их непосредственно перед вызовом fill() или 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();
}