Как обновить клонированный элемент HTML canvas с контекстом и данными исходного холста?

Я написал сценарий,который позволяет пользователям рисовать простые линии поверх элемента холста html 5. Конечная цель-сделать этот рисунок плитки и повторяется на остальные. Я получил клонированный холст на странице, но изо всех сил пытаюсь нарисовать одни и те же линии одновременно поверх нескольких холстов.

я вставлю свой код ниже

var size = 40;
var md = false;
var canvas = document.getElementById('canvas');
canvas.addEventListener('mousedown', down);
canvas.addEventListener('mouseup', toggledraw);

canvas.width  = 600;
canvas.height = 600;

canvas.addEventListener('mousemove', move);

function move(evt){

  var mousePos = getMousePos(canvas, evt);
  var posx = mousePos.x;
  var posy = mousePos.y;
  draw(canvas, posx, posy);

  window.posx;


  return mousePos;



};


function down(){
  md = true;
}

function toggledraw(){
  md = false;
}

function getMousePos(canvas, evt){
  var rect = canvas.getBoundingClientRect();
  return{
    x:evt.clientX - rect.left,
    y:evt.clientY - rect.top
  };
};

function draw(canvas, posx, posy){
  var context = canvas.getContext('2d');


  if(md){
    context.fillRect(posx, posy, size, size)
  }

};

cloneCanvas(canvas, window.posx, window.posy, size);

function cloneCanvas(canvas, posx, posy, size,) {
  console.log(posx);


  var newCanvas = document.createElement('canvas');
  var context = newCanvas.getContext('2d');
  newCanvas.className = "newNew";


  newCanvas.width = canvas.width;
  newCanvas.height = canvas.height;
  document.body.appendChild(newCanvas);



  //context.fillRect(posx, posy, size, size)
  context.drawImage(canvas, posx, posy);



  return canvas;
}

3 ответов


способ, которым я бы это сделал, - обновить клонированный холст после рисования на основном холсте.

на основе вашего текущего кода я бы сначала хотел вернуть клонированный холст вместо старого холста. Таким образом, у вас есть ссылка на него.

 function cloneCanvas(canvas, posx, posy, size,) {
   ...
 //  --> return canvas;
 return newCanvas // Becomes this.
}

далее, глядя на строку:

cloneCanvas(canvas, window.posx, window.posy, size);

Я вижу, что вы используете свои собственные переменные" posx "и" posy". Я бы избавился от них, так как вы всегда захотите скопировать весь холст. (В этом случае.) Измените строку следующим образом

var clone = cloneCanvas(canvas, 0, 0, size);

далее, я написал небольшую вспомогательную функцию, чтобы связать два полотна.

function drawFromSource(source, destination) {
  return function() {
    var context = destination.getContext('2d');
    context.clearRect(0, 0, destination.width, destination.height);
    context.drawImage(source, 0, 0);
  }
}

эта функция возвращает обратный вызов, который при вызове рисует исходный холст на клонированный холст.

вы инициализируете его следующим образом:

var updateClone = drawFromSource(canvas, clone);

и последнее, но не менее важное, вы должны добавить вновь созданный обратный вызов в функцию draw. Сразу после того, как вы нарисуете на своем основном холсте.

function draw(canvas, posx, posy) {
  var context = canvas.getContext('2d');
  if (md) {
    context.fillRect(posx, posy, size, size)
    updateClone();
  }

};

вуаля! Вот ссылка к рабочему коду я перенес часть твоего кода.

https://jsfiddle.net/30efdvz3/5/

просто для удовольствия. Кафельная версия просто изменить "numberofTiles"

https://jsfiddle.net/30efdvz3/3/


попробуйте этот код

в этом я создал функцию для регистрации события мыши в соответствии с canvas. и вызовите эту функцию для всех холстов.

var size = 40;
var md = false;
var canvas1 = document.getElementById('canvas');
registerEvents(canvas1)
function move(evt){
    console.log(evt.target.id);
    var canvas = document.getElementById(evt.target.id);
    var mousePos = getMousePos(canvas, evt);
    var posx = mousePos.x;
    var posy = mousePos.y;
    draw(canvas, posx, posy);
    window.posx;
    return mousePos;
};

function registerEvents(canvas){
    canvas.addEventListener('mousedown', down);
    canvas.addEventListener('mouseup', toggledraw);
    canvas.width  = 600;
    canvas.height = 600;
    canvas.addEventListener('mousemove', move);
}
function down(){
    md = true;
}

function toggledraw(){
    md = false;
}

function getMousePos(canvas, evt){
    var rect = canvas.getBoundingClientRect();
    return{
        x:evt.clientX - rect.left,
        y:evt.clientY - rect.top
    };
};

function draw(canvas, posx, posy){
    var context = canvas.getContext('2d');
    if(md){
        context.fillRect(posx, posy, size, size)
    }
};
cloneCanvas(canvas, window.posx, window.posy, size);
function cloneCanvas(canvas, posx, posy, size,) {
    console.log(posx);
    var newCanvas = document.createElement('canvas');
    var context = newCanvas.getContext('2d');
    var id = "newCanvas";
    newCanvas.className = "newNew";
    newCanvas.id = id;
    newCanvas.width = canvas.width;
    newCanvas.height = canvas.height;
    newCanvas.style.border = "1px solid black";
    document.body.appendChild(newCanvas);
    context.drawImage(canvas, posx, posy);
    registerEvents(document.getElementById(id))
    return canvas;
}

вот работает скрипка


на самом деле вы были близки, я сделал только некоторые изменения и достиг того, что вы хотели, вот результат.

function cloneCanvas(canvas, posx, posy, size,) {
  var newCanvas = document.createElement('canvas');
  var context = newCanvas.getContext('2d');
  ...
  return context; // this should return the context!
}

и

var clonedCanvas = cloneCanvas(canvas, window.posx, window.posy, size);
// after you call the function get the 2d context to variable.

последние изменения

function draw(canvas, posx, posy){
  var context = canvas.getContext('2d');
  if(md){
  clonedCanvas.fillRect(posx, posy, size, size); // fillRect to variable that you defined at above,
    context.fillRect(posx, posy, size, size)
  }
};

выход Jsfiddle; enter image description here

надеюсь поможет,