【问题标题】:Invert X and Y coordinates on HTML5 canvas在 HTML5 画布上反转 X 和 Y 坐标
【发布时间】:2015-04-18 22:10:11
【问题描述】:

我正在开发一个上面有 HTML5 画布的界面,当您选择一个位置时,我需要反转 X 和 Y 坐标。我认为从选定的 X 位置减去画布的宽度,从选定的 Y 位置减去画布的高度会反转坐标,但它会做一些非常奇怪的事情。

点击画布左上角时记录的X和Y坐标是X:324,Y:483,但理论上应该是X:650,Y:587,点击右下角时记录的坐标是@ 987654323@,理论上应该是X:0,Y:0。作为旁注,我确实知道单击时出现的点使用的是倒置坐标,这很好。

感谢任何帮助,特别是如果我做错了什么。谢谢!

JS:

window.fires.directive('fieldDirective', ['ScoutService', '$interval', function(ScoutService, $interval) {
    var $scope = this;
    $scope.sServ = ScoutService;
    $interval(function(){
        $scope.col = ScoutService.getAllianceColor();
    },1);
    return {
        restrict: "A",
        link: function(scope, element) {
            element.bind('mousedown', function(event) {
                var canvas = document.getElementById('field');
                var context = canvas.getContext('2d');
                if(event.offsetX !== undefined) {
                    $scope.xPos = 650 - event.offsetX;
                    $scope.yPos = 587 - event.offsetY;
                    $scope.sServ.sendLobCoords(xPos, yPos);
                } else {
                    $scope.xPos = 650 - event.layerX - event.currentTarget.offsetLeft;
                    $scope.yPos = 587 - event.layerY - event.currentTarget.offsetTop;
                    $scope.sServ.sendLobCoords(xPos, yPos);
                }
                console.log('red'+$scope.xPos + ' ' + $scope.yPos);
                canvas.width = canvas.width;
                context.arc($scope.xPos, $scope.yPos, 12, 0, Math.PI*2);
                context.fillStyle = '#FFFF00';
                context.fill();
                context.lineWidth = 3;
                context.strokeStyle = '#B2B200';
                context.stroke();
                context.closePath();
            });
        }
    };
}]);

HTML:

<canvas field-directive id="field" ng-class="{'field-red': sCtrl.fieldColor === 'red', 'field-blue': sCtrl.fieldColor === 'blue'}" width="650" height="587">Your browser does not support the HTML5 Canvas Element.  Please use a supported browser such as Google Chrome 4.0+ or FireFox 2.0+.</canvas>

【问题讨论】:

    标签: javascript angularjs html canvas


    【解决方案1】:

    我认为问题的出现是因为 offsetX 和 offsetY 与被点击的项目相关联。在这种情况下,无论“元素”是什么。如果单击事件直接绑定到画布,我认为您的代码会起作用。

    尝试将事件绑定到画布本身,或者使用具有点击行为的元素的位置和画布的位置来进行校正数学运算。

    【讨论】:

    • 你能告诉我一个将它绑定到画布本身的例子吗?我不知道该怎么做。
    • 希望有更懂 Angular 的人可以指导一下。点的数学是正确的,当元素被定义为画布时,我几乎使相同的代码完美地工作。也许您可以 console.log 元素并查看它是什么。我不能让这段代码独立运行来帮助调试。
    • 好的,当我记录变量element 时,它返回了这个对象:Object { 0: &lt;canvas#field.field-red&gt;, length: 1 },这正是我需要引用的画布。只是为了让我理解当你说'点的数学是正确的......'时,你是指我的数学来反转坐标吗?
    • 是的。我复制粘贴了您的代码并编写了一些 jQuery 来运行它并且它起作用了。
    【解决方案2】:
    • 首先通过从客户端坐标中减去元素的位置,使 x 和 y 相对于画布元素本身
    • 然后减去调整后的xfrom宽度,yfrom高度
    • 如果您需要绝对位置,请添加偏移量

    示例修改:

    element.bind('mousedown', function(event) {
        var canvas = document.getElementById('field');
        var context = canvas.getContext('2d');
    
        // get element position
        var rect = canvas.getBoundingClientRect();
    
        // get inversed coordinates: enable code after comment if abs. pos.
        var ix = canvas.width - (event.clientX - rect.left); // + rect.left
        var iy = canvas.height - (event.clientY - rect.top); // + rect.top
    
        ...update $scope here etc...
    });
    

    现场演示:

    var canvas = document.getElementById('field');
    
    canvas.addEventListener('mousemove', function(event) {
      var canvas = document.getElementById('field');
      var context = canvas.getContext('2d');
    
      // get element position
      var rect = canvas.getBoundingClientRect();
    
      // get inversed coordinates: enable code after comment if abs. pos.
      var ix = canvas.width - (event.clientX - rect.left); // + rect.left
      var iy = canvas.height - (event.clientY - rect.top); // + rect.top
    
      // draw something
      context.clearRect(0, 0, 500, 180);
      context.fillRect(ix - 2, iy - 2, 4, 4);
    });
    canvas {border: 1px solid #007}
    &lt;canvas id="field" width=500 height=180&gt;&lt;/canvas&gt;

    【讨论】:

    • 您的代码 sn-p 非常好,它在我的应用程序中运行良好(在我修复了所有愚蠢的拼写错误之后:P),谢谢!
    • 作为旁注,您留下的评论 enable code after comment if abs. pos. 实际上并没有给出绝对值。您在画布上单击的位置。为了解决这个问题,我没有添加您的建议,而是删除了canvas.width - canvas.height - ,它完美地作为绝对位置。
    • @Burn_E99 啊,我的错。我假设相对于画布的 inverted 坐标的绝对位置。
    猜你喜欢
    • 1970-01-01
    • 2011-10-15
    • 1970-01-01
    • 2023-04-06
    • 2014-02-14
    • 1970-01-01
    • 1970-01-01
    • 2021-05-22
    • 1970-01-01
    相关资源
    最近更新 更多