首页 > 解决方案 > 同时在画布中移动矩形

问题描述

我在 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);
}

触摸 x,y:

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
    }
}

标签: javascriptjquerymathcanvas

解决方案


我已经稍微简化了您的代码,只是为了展示如何移动矩形。我不检查鼠标按下或释放。

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)

在 plunker 示例中,它不是 100% 准确的,因为计算中没有使用页面上元素的 x,y 偏移量:)


推荐阅读