如何在画布鼠标点击中考虑缩放,平移和旋转

时间:2015-08-31 00:51:41

标签: javascript canvas css-transforms

我正在开发一款需要扩展(通过style.width,而不是scale(...)),翻译(translate(x, y))和转动(例如rotate(90deg)}的应用)一个画布元素。然后我需要在画布上计算正确的鼠标点击位置。也就是说,我需要这样做,以便行的末尾实际出现在用户点击的位置。现在,当我尝试合并翻译时,我的计算结果略有不同,您可以通过在下面的演示画布中点击两次来看到。

让我感到困惑的一部分是我应该做哪些顺序来翻译,取消旋转和不缩小以产生正确的结果。

演示代码:



var canvas = document.getElementById("canvas");

var scaleX = 0.5;
var scaleY = 0.5;
var rot = 1;
var dispWidth = (canvas.width * scaleX);
var dispHeight = (canvas.height * scaleY);
var xlateX = Math.floor((dispHeight - dispWidth) / 2);
var xlateY = Math.floor((dispWidth - dispHeight) / 2);

var transform = "translate(" + xlateX + "px, " + xlateY + "px) rotate(" + (rot * 90) + "deg)";
canvas.style.width = dispWidth + "px";
canvas.style.height = dispHeight + "px";
canvas.style.transform = transform;

var context = canvas.getContext("2d");
var stack = [];
canvas.onclick = function (e) {
  
    var rect = canvas.getBoundingClientRect();
    console.log('rect', rect.left, rect.top);
  
    // position within canvas, ignoring scroll
    var x = e.clientX - rect.left;
    var y = e.clientY - rect.top;
    console.log('original', x, y);
  
    // scale
    x /= scaleX;
    y /= scaleY;
    console.log('scaled', x, y);
    
    // translate
    x -= xlateX;
    y -= xlateY;
    console.log('translated', x, y);
    
    var tmp;
    switch (rot % 4) {
        case 1:
            tmp = x;
            x = y;
            y = canvas.height - tmp;
            break;
        case 2:
            y = canvas.height - tmp;
            x = canvas.width - tmp;
            break;
        case 3:
            tmp = y;
            y = x;
            x = canvas.width - tmp;
            break;
        default:
            break;
    }
    console.log('rotated', x, y);
    
    stack.push({x: x, y: y});
    if (stack.length > 1) {
        context.beginPath();
        context.moveTo(stack[0].x, stack[0].y);
        context.lineTo(stack[1].x, stack[1].y);
        context.stroke();
        stack = [];
    }
};

Click once to start a line. Click again to finish it.
<br>
<canvas id="canvas" width="600" height="400" style="border: 1px solid black;"></canvas>
&#13;
&#13;
&#13;

0 个答案:

没有答案