Перемещать ректы на холсте одновременно - PullRequest
0 голосов
/ 01 июня 2019

Я создал несколько прямоугольников в элементе Canvas. Основная цель - переместить их все в направлении события касания или перемещения мыши. Может быть, ответ передо мной, но сейчас я слепой :(

Вот пример кода на plunker

Код:

var context = {
  collection: [],
  canvas: document.getElementById('canvas'),
  ctx: canvas.getContext('2d'),
  isMoving: false
};

for (let f = 0; f < 3; f++) {
    var item = {
        x: (Math.random() * 200),
        y: (Math.random() * 100),
        w: 50,
        h: 50
    };

    context.collection.push(item);
}

drawAll(context);

Обработчик события касания:

context.canvas.addEventListener("mousedown", function (e) { onTouchHandler(e, context) }, false)
context.canvas.addEventListener("mousemove", function (e) { onTouchHandler(e, context) }, false);
context.canvas.addEventListener("mouseup", function (e) { onTouchHandler(e, context) }, false);

function onTouchHandler(e, context) {
    var touch = getTouchCoordinates(e.pageX, e.pageY, context.canvas);

    switch (e.type) {
        case 'mousedown':
            context.isMoving = true;
            break;
        case 'mousemove':
            if(context.isMoving === true){
                console.log(touch);

                //TODO: move all objects by the cursor...
                for (let f = 0; f < context.collection.length; f++) {
                    var item = context.collection[f];
                }

                //drawAll(context);
            }
            break;
        case 'mouseup':
            context.isMoving = false;
            break;
        default:
            break;
    }
}

Рисуем прямоугольники:

function drawAll(context){
  var canvas = context.canvas,
      ctx = context.ctx,
      shapes = context.collection;

  clearAll(ctx, canvas);

  for (let x = 0; x < shapes.length; x++) {
      var element = shapes[x];
      ctx.rect(element.x, element.y, element.w, element.h);
      ctx.stroke();
  }

}

Очистить ректы:

function clearAll(ctx, canvas){
  ctx.clearRect(0, 0, canvas.width, canvas.height);
}

Сенсорный х, у:

function getTouchCoordinates(pageX, pageY, canvas) {
    var element = canvas,
        offsetX = 0,
        offsetY = 0,
        currentX,
        currentY;

    if (element.offsetParent != undefined) {
        do {
            offsetX += element.offsetLeft;
            offsetY += element.offsetTop;
        } while ((element = element.offsetParent))
    }

    currentX = pageX - offsetX;
    currentY = pageY - offsetY;

    return {
        x: currentX,
        y: currentY
    }
}

Ответы [ 2 ]

0 голосов
/ 03 июня 2019

Я разобрался с ответом.

  1. "mousedown" - используется для хранения начальных x, y мыши
  2. "mousemove" - ​​используется для перемещения всего участка холста только для имитации движения прямоугольников и сохранения смещения (x, y)
  3. "mouseup" - ключевой момент заключается в том, чтобы использовать сохраненное смещение (x, y) и установить положения прямоугольников, после этого сбросить позицию холста и перерисовать прямоугольники с новыми значениями.

Может быть, есть более элегантный способ сделать это, но сейчас это поможет:)

0 голосов
/ 01 июня 2019

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

var context = {
  collection: [],
  canvas: document.getElementById('canvas'),
  ctx: canvas.getContext('2d'),
  isMoving: false
};

// rectangle positions
for (let f = 0; f < 3; f++) {
    var item = {
        x: (Math.random() * 200),
        y: (Math.random() * 100),
        w: 50,
        h: 50
    };

    context.collection.push(item);
}

// listen
context.canvas.addEventListener("mousemove",  (e) => onMoveHandler(e));

// Draw
drawAll();

function onMoveHandler(e) {
    //console.log(e.clientX, e.clientY)

    for (let f = 0; f < context.collection.length; f++) {
        var item = context.collection[f];

        var xdifference = item.x - e.pageX
        item.x = (xdifference < 0) ? item.x + 1 : item.x -1

        var ydifference = item.y - e.pageY
        item.y = (ydifference < 0) ? item.y + 1 : item.y -1
    }
    drawAll()
}

function drawAll(){

  // clear all 
  clearAll();

  for (let x = 0; x < context.collection.length; x++) {
      var element = context.collection[x];
      context.ctx.rect(element.x, element.y, element.w, element.h);
      context.ctx.stroke();
  }

}

function clearAll(){
  context.ctx.clearRect(0, 0, context.canvas.width, context.canvas.height);
}

Если вам нужно более «естественное» движение к мышке, вы можете рассчитать разницу x и y, используя теорему Пифагора:

var xdifference = e.pageX - item.x
var ydifference = e.pageY - item.y

let distance = Math.sqrt(xdifference * xdifference + ydifference * ydifference)
item.x += (xdifference / distance)
item.y += (ydifference / distance)

В примере с плунжером он не точен на 100%, потому что смещение по оси x, y элемента на странице не используется в вычислениях:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...