在 HTML5 canvas 上反转 X 和 Y 坐标
Invert X and Y coordinates on HTML5 canvas
我正在开发一个界面,上面有一个 HTML5 canvas,当你 select 一个位置时,我需要反转 X 和 Y 坐标。我认为从 selected X 位置减去 canvas 的宽度,并从 selected Y 位置减去 canvas 的高度会反转坐标,但它正在做一些非常奇怪的事情。
点击canvas左上角时记录的X和Y坐标是X:324,Y:483
,但理论上应该是X:650,Y:587
,当你点击在右下角,记录的坐标是 X:-325,Y:-103
,而理论上它们应该是 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>
我认为问题的出现是因为 offsetX 和 offsetY 与被点击的项目相关联。在这种情况下,无论 "element" 是什么。如果点击事件直接绑定到 canvas,我认为您的代码会起作用。
尝试将事件绑定到 canvas 本身,或者使用具有点击行为的元素的位置和 canvas 的位置来进行更正数学运算。
- 首先通过从客户端坐标
中减去元素的位置,使 x 和 y 相对于 canvas 元素本身
- 然后减去调整后的xfromwidth,yfromheight
- 如果需要绝对位置,请加回偏移量
修改示例:
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}
<canvas id="field" width=500 height=180></canvas>
我正在开发一个界面,上面有一个 HTML5 canvas,当你 select 一个位置时,我需要反转 X 和 Y 坐标。我认为从 selected X 位置减去 canvas 的宽度,并从 selected Y 位置减去 canvas 的高度会反转坐标,但它正在做一些非常奇怪的事情。
点击canvas左上角时记录的X和Y坐标是X:324,Y:483
,但理论上应该是X:650,Y:587
,当你点击在右下角,记录的坐标是 X:-325,Y:-103
,而理论上它们应该是 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>
我认为问题的出现是因为 offsetX 和 offsetY 与被点击的项目相关联。在这种情况下,无论 "element" 是什么。如果点击事件直接绑定到 canvas,我认为您的代码会起作用。
尝试将事件绑定到 canvas 本身,或者使用具有点击行为的元素的位置和 canvas 的位置来进行更正数学运算。
- 首先通过从客户端坐标 中减去元素的位置,使 x 和 y 相对于 canvas 元素本身
- 然后减去调整后的xfromwidth,yfromheight
- 如果需要绝对位置,请加回偏移量
修改示例:
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}
<canvas id="field" width=500 height=180></canvas>