Invert X and Y coordinates on HTML5 canvas

[亡魂溺海] 提交于 2020-01-16 12:04:13

问题


I am working on an interface that has a HTML5 canvas on it, and I need to invert the X and Y coordinates when you select a position. I thought that subtracting the width of the canvas from the selected X position, and subtracting the height of the canvas from the selected Y position would invert the coordinates, but it is doing some very weird things.

The X and Y coords that log when you click in the top left corner of the canvas are X:324,Y:483 but theoretically, they should be X:650,Y:587, and when you click in the bottom right corner, the logged coordinates are X:-325,Y:-103 when they theoretically should be X:0,Y:0. As a side note, I do know that the dot that appears when you click is using the inverted coordinates, and that is fine.

Any help is appreciated especially if I am doing something horribly wrong. Thanks!

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>

回答1:


  • First make the x and y relative to the canvas element itself by subtracting the position of the element from the client coordinates
  • Then subtract the adjusted x from width, y from height
  • If you need an absolute position, add back the offsets

Example modification:

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...
});

Live demo:

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}
<canvas id="field" width=500 height=180></canvas>



回答2:


I think the problem is arising because offsetX and offsetY are tied to the item that was clicked. In this case whatever "element" is. If the click event were tied directly to the canvas I think your code would work.

Try binding the event to the canvas itself or use the position of the element with the click behavior and the position of the canvas to do corrective math.



来源:https://stackoverflow.com/questions/28574628/invert-x-and-y-coordinates-on-html5-canvas

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!