캔버스 요소에서 마우스 클릭 좌표를 가져오려면 어떻게 해야 합니까?
클릭 이벤트 핸들러를 캔버스 요소에 추가하여 클릭의 x좌표와 y좌표를 반환하는 가장 간단한 방법은 무엇입니까?
레거시 브라우저 호환성은 필요 없습니다.Safari, Opera 및 Firefox라면 충분합니다.
단순함을 원하면서도 크로스 브라우저 기능을 원하신다면 이 솔루션이 가장 적합하다는 것을 알게 되었습니다.이것은 jQuery를 사용하지 않고 @Aldekein의 솔루션을 단순화한 것입니다.
function getCursorPosition(canvas, event) {
const rect = canvas.getBoundingClientRect()
const x = event.clientX - rect.left
const y = event.clientY - rect.top
console.log("x: " + x + " y: " + y)
}
const canvas = document.querySelector('canvas')
canvas.addEventListener('mousedown', function(e) {
getCursorPosition(canvas, e)
})
업데이트 (5/5/16): 패트리큐의 답변이 보다 심플하고 신뢰성이 높기 때문에 대신 사용되어야 합니다.
는 반드시 페이지 을 하는 것은 에, 「화면」은 「화면」을 참조해 .canvas.offsetLeft/Top
꼭 필요한 것을 돌려주는 것은 아닙니다.합니다. 이은 OffsetParent 요소에서 OffsetParent가 됩니다. OffsetParent는 OffsetParent가 됩니다.div
있는 position: relative
이치노이를 설명하려면 다음 체인을 통해 루프해야 합니다.offsetParent
s, 캔버스 요소부터 시작합니다.이 코드는 Firefox와 Safari에서 테스트된 나에게 완벽하게 작동하지만 모든 사람에게 작동합니다.
function relMouseCoords(event){
var totalOffsetX = 0;
var totalOffsetY = 0;
var canvasX = 0;
var canvasY = 0;
var currentElement = this;
do{
totalOffsetX += currentElement.offsetLeft - currentElement.scrollLeft;
totalOffsetY += currentElement.offsetTop - currentElement.scrollTop;
}
while(currentElement = currentElement.offsetParent)
canvasX = event.pageX - totalOffsetX;
canvasY = event.pageY - totalOffsetY;
return {x:canvasX, y:canvasY}
}
HTMLCanvasElement.prototype.relMouseCoords = relMouseCoords;
마지막 줄은 캔버스 요소를 기준으로 마우스 좌표를 얻는 데 편리합니다.유용한 좌표를 얻으려면
coords = canvas.relMouseCoords(event);
canvasX = coords.x;
canvasY = coords.y;
2018년 편집:이 답변은 매우 오래되어 더 이상 필요하지 않은 오래된 브라우저에 대한 체크를 사용합니다.clientX
★★★★★★★★★★★★★★★★★」clientY
속성은 현재 모든 브라우저에서 작동합니다.보다 심플하고 최신의 솔루션에 대해서는, Patriques Answer를 참조해 주세요.
★★★★
기사에 기재되어 있는 바와 같이, 그 당시 발견되었지만, 현재는 존재하지 않습니다.
var x;
var y;
if (e.pageX || e.pageY) {
x = e.pageX;
y = e.pageY;
}
else {
x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
x -= gCanvasElement.offsetLeft;
y -= gCanvasElement.offsetTop;
나한테는 완벽하게 잘 작동했어.
최신 브라우저가 이 문제를 해결해 드립니다.Chrome, IE9 및 Firefox는 다음과 같이 OffsetX/Y를 지원하며 클릭 핸들러에서 이벤트를 전달합니다.
function getRelativeCoords(event) {
return { x: event.offsetX, y: event.offsetY };
}
또한 대부분의 최신 브라우저는 레이어X/Y를 지원하지만 Chrome과 IE는 여백, 패딩 등을 포함한 페이지 클릭의 절대 오프셋을 위해 레이어X/Y를 사용합니다.Firefox에서는 레이어X/Y와 오프셋X/Y가 동일하지만 이전에는 오프셋이 존재하지 않았습니다.따라서 약간 오래된 브라우저와의 호환성을 위해 다음을 사용할 수 있습니다.
function getRelativeCoords(event) {
return { x: event.offsetX || event.layerX, y: event.offsetY || event.layerY };
}
새로운 Quirksmode에 따르면clientX
★★★★★★★★★★★★★★★★★」clientY
메서드는 모든 주요 브라우저에서 지원됩니다.기기있있있있다다 스크롤바가 있는 페이지의 스크롤 디바로 동작하는 좋은 코드가 있습니다.
function getCursorPosition(canvas, event) {
var x, y;
canoffset = $(canvas).offset();
x = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft - Math.floor(canoffset.left);
y = event.clientY + document.body.scrollTop + document.documentElement.scrollTop - Math.floor(canoffset.top) + 1;
return [x,y];
}
여기에는 다음에 대한 jQuery도 필요합니다.$(canvas).offset()
.
그래서 이것은 둘 다 간단하지만 보이는 것보다 조금 더 복잡한 주제입니다.
먼저, 여기에는 보통 혼합된 질문이 있습니다.
요소 상대 마우스 좌표를 가져오는 방법
2D Canvas API 또는 WebGL용 캔버스 픽셀 마우스 좌표를 가져오는 방법
그래서, 대답들
요소 상대 마우스 좌표를 가져오는 방법
요소가 캔버스이며 요소의 상대 마우스 좌표를 가져올지 여부는 모든 요소에 대해 동일합니다.
"캔버스 관련 마우스 좌표를 얻는 방법" 질문에는 두 가지 간단한 답변이 있습니다.
답변 사용#1offsetX
★★★★★★★★★★★★★★★★★」offsetY
canvas.addEventListner('mousemove', (e) => {
const x = e.offsetX;
const y = e.offsetY;
});
Chrome, Firefox, Safari. 모든 값과 offsetX
★★★★★★★★★★★★★★★★★」offsetY
CSS の c c c c c c c c 。
「 」의 가장 큰 offsetX
★★★★★★★★★★★★★★★★★」offsetY
2019/05년 현재 터치 이벤트에는 존재하지 않기 때문에 iOS Safari에서는 사용할 수 없습니다.그것들은 Chrome과 Firefox에 존재하는 포인터 이벤트 상에 존재하지만 Safari가 동작하고 있는 것은 분명하지만 Safari는 동작하고 있는 것 같습니다.
또 다른 문제는 이벤트가 캔버스에 있어야 한다는 것입니다.다른 요소나 창에 배치하면 나중에 캔버스를 기준으로 선택할 수 없습니다.
답변 사용 #2clientX
,clientY
★★★★★★★★★★★★★★★★★」canvas.getBoundingClientRect
경우 은 CSS를 호출하는 입니다.canvas. getBoundingClientRect()
을 clientX
★★★★★★★★★★★★★★★★★」top
부터에서clientY
in에서와 같이로
canvas.addEventListener('mousemove', (e) => {
const rect = canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
});
이것은 CSS 변환이 없는 한 동작합니다.터치 이벤트에서도 사용할 수 있으므로 Safari iOS에서도 사용할 수 있습니다.
canvas.addEventListener('touchmove', (e) => {
const rect = canvas. getBoundingClientRect();
const x = e.touches[0].clientX - rect.left;
const y = e.touches[0].clientY - rect.top;
});
2D Canvas API의 캔버스 픽셀 마우스 좌표를 가져오는 방법
이를 위해서는 위에서 얻은 값을 사용하여 캔버스가 표시되는 크기에서 캔버스 자체의 픽셀 수로 변환해야 합니다.
A함께와canvas.getBoundingClientRect
그리고 그리고.clientX
그리고 그리고.clientY
canvas.addEventListener('mousemove', (e) => {
const rect = canvas.getBoundingClientRect();
const elementRelativeX = e.clientX - rect.left;
const elementRelativeY = e.clientY - rect.top;
const canvasRelativeX = elementRelativeX * canvas.width / rect.width;
const canvasRelativeY = elementRelativeY * canvas.height / rect.height;
});
또는또는 을 사용하여offsetX
그리고 그리고.offsetY
canvas.addEventListener('mousemove', (e) => {
const elementRelativeX = e.offsetX;
const elementRelativeY = e.offsetY;
const canvasRelativeX = elementRelativeX * canvas.width / canvas.clientWidth;
const canvasRelativeY = elementRelativeY * canvas.height / canvas.clientHeight;
});
주의: 어떤 경우에도 캔버스에 패딩이나 테두리를 추가하지 마십시오. 그렇게 하면 코드가 엄청나게 복잡해집니다. 테두리 또는 패딩이 다른 요소에서 캔버스를 둘러싸고 외부 요소에 패딩 및/또는 테두리를 추가하는 대신,
예 의 작업을 사용하여 일하는 것 예event.offsetX
,,event.offsetY
[...document.querySelectorAll('canvas')].forEach((canvas) => {
const ctx = canvas.getContext('2d');
ctx.canvas.width = ctx.canvas.clientWidth;
ctx.canvas.height = ctx.canvas.clientHeight;
let count = 0;
function draw(e, radius = 1) {
const pos = {
x: e.offsetX * canvas.width / canvas.clientWidth,
y: e.offsetY * canvas.height / canvas.clientHeight,
};
document.querySelector('#debug').textContent = count;
ctx.beginPath();
ctx.arc(pos.x, pos.y, radius, 0, Math.PI * 2);
ctx.fillStyle = hsl((count++ % 100) / 100, 1, 0.5);
ctx.fill();
}
function preventDefault(e) {
e.preventDefault();
}
if (window.PointerEvent) {
canvas.addEventListener('pointermove', (e) => {
draw(e, Math.max(Math.max(e.width, e.height) / 2, 1));
});
canvas.addEventListener('touchstart', preventDefault, {passive: false});
canvas.addEventListener('touchmove', preventDefault, {passive: false});
} else {
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mousedown', preventDefault);
}
});
function hsl(h, s, l) {
return `hsl(${h * 360 | 0},${s * 100 | 0}%,${l * 100 | 0}%)`;
}
.scene {
width: 200px;
height: 200px;
perspective: 600px;
}
.cube {
width: 100%;
height: 100%;
position: relative;
transform-style: preserve-3d;
animation-duration: 16s;
animation-name: rotate;
animation-iteration-count: infinite;
animation-timing-function: linear;
}
@keyframes rotate {
from { transform: translateZ(-100px) rotateX( 0deg) rotateY( 0deg); }
to { transform: translateZ(-100px) rotateX(360deg) rotateY(720deg); }
}
.cube__face {
position: absolute;
width: 200px;
height: 200px;
display: block;
}
.cube__face--front { background: rgba(255, 0, 0, 0.2); transform: rotateY( 0deg) translateZ(100px); }
.cube__face--right { background: rgba(0, 255, 0, 0.2); transform: rotateY( 90deg) translateZ(100px); }
.cube__face--back { background: rgba(0, 0, 255, 0.2); transform: rotateY(180deg) translateZ(100px); }
.cube__face--left { background: rgba(255, 255, 0, 0.2); transform: rotateY(-90deg) translateZ(100px); }
.cube__face--top { background: rgba(0, 255, 255, 0.2); transform: rotateX( 90deg) translateZ(100px); }
.cube__face--bottom { background: rgba(255, 0, 255, 0.2); transform: rotateX(-90deg) translateZ(100px); }
<div class="scene">
<div class="cube">
<canvas class="cube__face cube__face--front"></canvas>
<canvas class="cube__face cube__face--back"></canvas>
<canvas class="cube__face cube__face--right"></canvas>
<canvas class="cube__face cube__face--left"></canvas>
<canvas class="cube__face cube__face--top"></canvas>
<canvas class="cube__face cube__face--bottom"></canvas>
</div>
</div>
<pre id="debug"></pre>
예 의 작업을 사용하여 일하는 것 예canvas.getBoundingClientRect
그리고 그리고.event.clientX
그리고 그리고.event.clientY
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
ctx.canvas.width = ctx.canvas.clientWidth;
ctx.canvas.height = ctx.canvas.clientHeight;
let count = 0;
function draw(e, radius = 1) {
const rect = canvas.getBoundingClientRect();
const pos = {
x: (e.clientX - rect.left) * canvas.width / canvas.clientWidth,
y: (e.clientY - rect.top) * canvas.height / canvas.clientHeight,
};
ctx.beginPath();
ctx.arc(pos.x, pos.y, radius, 0, Math.PI * 2);
ctx.fillStyle = hsl((count++ % 100) / 100, 1, 0.5);
ctx.fill();
}
function preventDefault(e) {
e.preventDefault();
}
if (window.PointerEvent) {
canvas.addEventListener('pointermove', (e) => {
draw(e, Math.max(Math.max(e.width, e.height) / 2, 1));
});
canvas.addEventListener('touchstart', preventDefault, {passive: false});
canvas.addEventListener('touchmove', preventDefault, {passive: false});
} else {
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mousedown', preventDefault);
}
function hsl(h, s, l) {
return `hsl(${h * 360 | 0},${s * 100 | 0}%,${l * 100 | 0}%)`;
}
canvas { background: #FED; }
<canvas width="400" height="100" style="width: 300px; height: 200px"></canvas>
<div>canvas deliberately has differnt CSS size vs drawingbuffer size</div>
이 문제의 해결책의 완전한 소스 코드를 사용하여 모든 브라우저에서 동작하는 완전한 디스테스트레이션을 실행했습니다.Javascript에서 Canvas를 마우스 좌표로 클릭.데모를 시도하려면 코드를 복사하여 텍스트 편집기에 붙여넣습니다.그런 다음 example.html로 저장하고 마지막으로 브라우저에서 파일을 엽니다.
폭(%)이 가변적인 캔버스에 대한 Ryan Artecona의 답변은 다음과 같습니다.
HTMLCanvasElement.prototype.relMouseCoords = function (event) {
var totalOffsetX = 0;
var totalOffsetY = 0;
var canvasX = 0;
var canvasY = 0;
var currentElement = this;
do {
totalOffsetX += currentElement.offsetLeft;
totalOffsetY += currentElement.offsetTop;
}
while (currentElement = currentElement.offsetParent)
canvasX = event.pageX - totalOffsetX;
canvasY = event.pageY - totalOffsetY;
// Fix for variable canvas width
canvasX = Math.round( canvasX * (this.width / this.offsetWidth) );
canvasY = Math.round( canvasY * (this.height / this.offsetHeight) );
return {x:canvasX, y:canvasY}
}
좌표 변환을 수행할 때는 주의해야 합니다.클릭 이벤트에서 여러 개의 브라우저 이외의 값이 반환됩니다.브라우저 창이 스크롤된 경우(Firefox 3.5 및 Chrome 3.0에서 확인됨) clientX 및 clientY만으로는 충분하지 않습니다.
이 퀴크 모드 기사에서는 pageX 또는 pageY 중 하나를 사용하거나 document.body.scrollLeft 및 clientY와 document.body.scrollTop을 조합하여 문서 원본에 대한 클릭 좌표를 계산할 수 있는 보다 정확한 함수를 제공합니다.
업데이트: 또한 offset Left 및 offset Top은 내부 크기가 아니라 요소의 패딩 크기에 상대적입니다.padding: style이 적용된 캔버스는 콘텐츠 영역의 왼쪽 상단을 offsetLeft로 보고하지 않습니다.이 문제에는 다양한 해결책이 있습니다.가장 간단한 방법은 캔버스 자체의 모든 테두리, 패딩 등의 스타일을 지우고 캔버스가 들어 있는 상자에 적용하는 것입니다.
이 모든 답변들이 부모들의 요소들을 순환하며 이상한 것들을 하는 것이 무슨 의미가 있는지 잘 모르겠다.
그 그HTMLElement.getBoundingClientRect
방법 어떤 요소의 실제 화면 위치 처리하도록 설계되어 있다.방법은 모든 요소의 실제 화면 위치를 처리하도록 설계되었습니다.이건포함되어 있습니다 스크롤도 여기에는과 같은 물건 스크롤을 포함한다.scrollTop
는 불필요합니다.
(MDN에서) 뷰포트 영역(또는 다른 스크롤 가능 요소)에서 수행된 스크롤 양은 경계 직사각형을 계산할 때 고려됩니다.
일반 이미지
가장 간단한 접근법이 이미 여기에 게시되어 있습니다.이는 와일드 CSS 규칙이 포함되지 않는 한 유효합니다.
늘어난 캔버스/이미지 처리
이미지 픽셀의 폭과 CSS의 폭이 일치하지 않을 경우 픽셀 값에 다음과 같은 비율을 적용해야 합니다.
/* Returns pixel coordinates according to the pixel that's under the mouse cursor**/
HTMLCanvasElement.prototype.relativeCoords = function(event) {
var x,y;
//This is the current screen rectangle of canvas
var rect = this.getBoundingClientRect();
var top = rect.top;
var bottom = rect.bottom;
var left = rect.left;
var right = rect.right;
//Recalculate mouse offsets to relative offsets
x = event.clientX - left;
y = event.clientY - top;
//Also recalculate offsets of canvas is stretched
var width = right - left;
//I use this to reduce number of calculations for images that have normal size
if(this.width!=width) {
var height = bottom - top;
//changes coordinates by ratio
x = x*(this.width/width);
y = y*(this.height/height);
}
//Return as an array
return [x,y];
}
캔버스에 테두리가 없는 한 늘어난 이미지(jsFiddle)에 사용할 수 있습니다.
CSS 경계 처리
캔버스에 두꺼운 테두리가 있으면 일이 조금 복잡해집니다.말 그대로 테두리 직사각형에서 테두리를 빼야 합니다.이것은 .getComputedStyle을 사용하여 수행할 수 있습니다.이 답변은 프로세스를 설명합니다.
그 후 기능이 약간 성장합니다.
/* Returns pixel coordinates according to the pixel that's under the mouse cursor**/
HTMLCanvasElement.prototype.relativeCoords = function(event) {
var x,y;
//This is the current screen rectangle of canvas
var rect = this.getBoundingClientRect();
var top = rect.top;
var bottom = rect.bottom;
var left = rect.left;
var right = rect.right;
//Subtract border size
// Get computed style
var styling=getComputedStyle(this,null);
// Turn the border widths in integers
var topBorder=parseInt(styling.getPropertyValue('border-top-width'),10);
var rightBorder=parseInt(styling.getPropertyValue('border-right-width'),10);
var bottomBorder=parseInt(styling.getPropertyValue('border-bottom-width'),10);
var leftBorder=parseInt(styling.getPropertyValue('border-left-width'),10);
//Subtract border from rectangle
left+=leftBorder;
right-=rightBorder;
top+=topBorder;
bottom-=bottomBorder;
//Proceed as usual
...
}
나는 이 최종 기능을 혼란스럽게 할 만한 것이 생각나지 않는다.JsFiddle에서 만나요.
메모들
에 들지 않는 prototype
그냥 s, ㄴㄴ데, ㄴ데 하다로 .(canvas, event)
any (「」를 해 주세요)this
canvas
를 참조해 주세요.
여기 아주 좋은 튜토리얼이 있습니다.
http://www.html5canvastutorials.com/advanced/html5-canvas-mouse-coordinates/
<canvas id="myCanvas" width="578" height="200"></canvas>
<script>
function writeMessage(canvas, message) {
var context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
context.font = '18pt Calibri';
context.fillStyle = 'black';
context.fillText(message, 10, 25);
}
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
canvas.addEventListener('mousemove', function(evt) {
var mousePos = getMousePos(canvas, evt);
var message = 'Mouse position: ' + mousePos.x + ',' + mousePos.y;
writeMessage(canvas, message);
}, false);
이게 도움이 되길 바래!
2016년 jQuery를 사용하여 캔버스에 대한 클릭 좌표를 얻으려면 다음을 수행합니다.
$(canvas).click(function(jqEvent) {
var coords = {
x: jqEvent.pageX - $(canvas).offset().left,
y: jqEvent.pageY - $(canvas).offset().top
};
});
이것은 캔버스 오프셋()과 jqEvent.pageX/Y 모두 스크롤 위치에 관계없이 문서에 상대적이기 때문에 작동합니다.
캔버스의 배율이 조정된 경우 이러한 좌표는 캔버스의 논리 좌표와 동일하지 않습니다.이러한 기능을 이용하려면 , 다음의 조작도 실시합니다.
var logicalCoords = {
x: coords.x * (canvas.width / $(canvas).width()),
y: coords.y * (canvas.height / $(canvas).height())
}
이 링크를 추천합니다.http://miloq.blogspot.in/2011/05/coordinates-mouse-click-canvas.html
<style type="text/css">
#canvas{background-color: #000;}
</style>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", init, false);
function init()
{
var canvas = document.getElementById("canvas");
canvas.addEventListener("mousedown", getPosition, false);
}
function getPosition(event)
{
var x = new Number();
var y = new Number();
var canvas = document.getElementById("canvas");
if (event.x != undefined && event.y != undefined)
{
x = event.x;
y = event.y;
}
else // Firefox method to get the position
{
x = event.clientX + document.body.scrollLeft +
document.documentElement.scrollLeft;
y = event.clientY + document.body.scrollTop +
document.documentElement.scrollTop;
}
x -= canvas.offsetLeft;
y -= canvas.offsetTop;
alert("x: " + x + " y: " + y);
}
</script>
프로토타입에서 위의 Ryan Artecona에서 설명한 대로 cumulativeOffset()을 사용하여 재귀 합계를 수행합니다.
http://www.prototypejs.org/api/element/cumulativeoffset
다음 작업을 수행할 수 있습니다.
var canvas = yourCanvasElement;
var mouseX = (event.clientX - (canvas.offsetLeft - canvas.scrollLeft)) - 2;
var mouseY = (event.clientY - (canvas.offsetTop - canvas.scrollTop)) - 2;
그러면 마우스 포인터의 정확한 위치를 알 수 있습니다.
http://jsbin.com/ApuJOSA/1/edit?html,output 에 있는 데모를 참조해 주세요.
function mousePositionOnCanvas(e) {
var el=e.target, c=el;
var scaleX = c.width/c.offsetWidth || 1;
var scaleY = c.height/c.offsetHeight || 1;
if (!isNaN(e.offsetX))
return { x:e.offsetX*scaleX, y:e.offsetY*scaleY };
var x=e.pageX, y=e.pageY;
do {
x -= el.offsetLeft;
y -= el.offsetTop;
el = el.offsetParent;
} while (el);
return { x: x*scaleX, y: y*scaleY };
}
pdf 위에 캔버스가 있는 어플리케이션을 만들고 있었습니다.예를 들어 pdf-in 및 zooming과 같은 많은 캔버스의 크기를 조정해야 했습니다.PDF의 크기를 조정하기 위해 캔버스의 크기를 조정해야 했습니다.StackOverflow에서 많은 답변을 확인했지만 최종적으로 프로블을 해결할 수 있는 완벽한 솔루션을 찾을 수 없었습니다.m.
rxjs와 angular 6을 사용하고 있었는데 최신 버전에 대한 답변을 찾을 수 없었습니다.
여기에 rxjs를 이용하여 캔버스 위에 그림을 그리는 모든 사람에게 도움이 되는 코드 조각이 있습니다.
private captureEvents(canvasEl: HTMLCanvasElement) {
this.drawingSubscription = fromEvent(canvasEl, 'mousedown')
.pipe(
switchMap((e: any) => {
return fromEvent(canvasEl, 'mousemove')
.pipe(
takeUntil(fromEvent(canvasEl, 'mouseup').do((event: WheelEvent) => {
const prevPos = {
x: null,
y: null
};
})),
takeUntil(fromEvent(canvasEl, 'mouseleave')),
pairwise()
)
})
)
.subscribe((res: [MouseEvent, MouseEvent]) => {
const rect = this.cx.canvas.getBoundingClientRect();
const prevPos = {
x: Math.floor( ( res[0].clientX - rect.left ) / ( rect.right - rect.left ) * this.cx.canvas.width ),
y: Math.floor( ( res[0].clientY - rect.top ) / ( rect.bottom - rect.top ) * this.cx.canvas.height )
};
const currentPos = {
x: Math.floor( ( res[1].clientX - rect.left ) / ( rect.right - rect.left ) * this.cx.canvas.width ),
y: Math.floor( ( res[1].clientY - rect.top ) / ( rect.bottom - rect.top ) * this.cx.canvas.height )
};
this.coordinatesArray[this.file.current_slide - 1].push(prevPos);
this.drawOnCanvas(prevPos, currentPos);
});
}
캔버스를 확대/축소하는 방법에 관계없이 캔버스의 크기를 기준으로 마우스 좌표를 수정하는 스니펫입니다.
const prevPos = {
x: Math.floor( ( res[0].clientX - rect.left ) / ( rect.right - rect.left ) * this.cx.canvas.width ),
y: Math.floor( ( res[0].clientY - rect.top ) / ( rect.bottom - rect.top ) * this.cx.canvas.height )
};
const currentPos = {
x: Math.floor( ( res[1].clientX - rect.left ) / ( rect.right - rect.left ) * this.cx.canvas.width ),
y: Math.floor( ( res[1].clientY - rect.top ) / ( rect.bottom - rect.top ) * this.cx.canvas.height )
};
다음은 상기 Ryan Artecona 솔루션의 몇 가지 수정 사항입니다.
function myGetPxStyle(e,p)
{
var r=window.getComputedStyle?window.getComputedStyle(e,null)[p]:"";
return parseFloat(r);
}
function myGetClick=function(ev)
{
// {x:ev.layerX,y:ev.layerY} doesn't work when zooming with mac chrome 27
// {x:ev.clientX,y:ev.clientY} not supported by mac firefox 21
// document.body.scrollLeft and document.body.scrollTop seem required when scrolling on iPad
// html is not an offsetParent of body but can have non null offsetX or offsetY (case of wordpress 3.5.1 admin pages for instance)
// html.offsetX and html.offsetY don't work with mac firefox 21
var offsetX=0,offsetY=0,e=this,x,y;
var htmls=document.getElementsByTagName("html"),html=(htmls?htmls[0]:0);
do
{
offsetX+=e.offsetLeft-e.scrollLeft;
offsetY+=e.offsetTop-e.scrollTop;
} while (e=e.offsetParent);
if (html)
{
offsetX+=myGetPxStyle(html,"marginLeft");
offsetY+=myGetPxStyle(html,"marginTop");
}
x=ev.pageX-offsetX-document.body.scrollLeft;
y=ev.pageY-offsetY-document.body.scrollTop;
return {x:x,y:y};
}
먼저, 다른 사람들이 말했듯이 캔버스 요소의 위치를 파악할 수 있는 기능이 필요합니다.여기 이 페이지의 다른 방법(IMHO)보다 조금 더 우아한 방법이 있습니다.임의의 요소를 전달하여 문서에서 해당 위치를 얻을 수 있습니다.
function findPos(obj) {
var curleft = 0, curtop = 0;
if (obj.offsetParent) {
do {
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
} while (obj = obj.offsetParent);
return { x: curleft, y: curtop };
}
return undefined;
}
이제 상대적인 커서의 현재 위치를 계산합니다.
$('#canvas').mousemove(function(e) {
var pos = findPos(this);
var x = e.pageX - pos.x;
var y = e.pageY - pos.y;
var coordinateDisplay = "x=" + x + ", y=" + y;
writeCoordinateDisplay(coordinateDisplay);
});
일반적인 것을 분리한 것에 주의해 주세요.findPos
이벤트 처리 코드에서 기능합니다.(필요한 대로).각각 1개의 태스크로 기능을 유지하도록 노력해야 합니다.)
" " 값의 값offsetLeft
★★★★★★★★★★★★★★★★★」offsetTop
이다.offsetParent
일 수 div
노드(또는 그 이외의 것)를 지정합니다.를 가 없는 canvas
입니다.body
을 사용하다그렇기 때문에 다른 일을 하기 전에 캔버스의 위치를 결정해야 합니다.
사사e.pageX
★★★★★★★★★★★★★★★★★」e.pageY
문서에 상대적인 커서 위치를 제공합니다.그래서 우리는 캔버스의 오프셋을 그 값에서 빼서 진정한 위치에 도달합니다.
위치 요소에 대한 대안은 다음과 같은 값을 직접 사용하는 것입니다.e.layerX
★★★★★★★★★★★★★★★★★」e.layerY
은 두 이 떨어집니다.
- 또한 이러한 값은 이벤트가 위치 요소 내에서 발생하지 않을 때 문서 전체에 상대적입니다.
- 그것들은 어떤 기준에도 속하지 않습니다.
ThreeJS r77
var x = event.offsetX == undefined ? event.layerX : event.offsetX;
var y = event.offsetY == undefined ? event.layerY : event.offsetY;
mouse2D.x = ( x / renderer.domElement.width ) * 2 - 1;
mouse2D.y = - ( y / renderer.domElement.height ) * 2 + 1;
여러 가지 방법을 시도해 본 후.이건 나한테 효과가 있었어.다른 사람에게 도움이 될 수 있으니 글을 올리세요.여기서부터 맡겠습니다.
다음은 심플한 솔루션입니다(경계선/스크롤링에서는 사용할 수 없습니다).
function click(event) {
const bound = event.target.getBoundingClientRect();
const xMult = bound.width / can.width;
const yMult = bound.height / can.height;
return {
x: Math.floor(event.offsetX / xMult),
y: Math.floor(event.offsetY / yMult),
};
}
이봐, 이건 도조야. 내가 이미 프로젝트를 위해 코드를 넣은거니까.
dojo vanilla 이외의 JavaScript로 다시 변환하는 방법은 매우 명확해야 합니다.
function onMouseClick(e) {
var x = e.clientX;
var y = e.clientY;
}
var canvas = dojo.byId(canvasId);
dojo.connect(canvas,"click",onMouseClick);
도움이 됐으면 좋겠다.
언급URL : https://stackoverflow.com/questions/55677/how-do-i-get-the-coordinates-of-a-mouse-click-on-a-canvas-element
'source' 카테고리의 다른 글
MySQL에서 하나를 제외한 모든 열을 선택하시겠습니까? (0) | 2022.10.02 |
---|---|
matplotlib Python 설치 문제 (0) | 2022.10.02 |
MySQL의 JSON에는 BLOB 또는 텍스트를 사용해야 합니까? (0) | 2022.10.02 |
tailwindcss @apply 디렉티브가 vue 구성 요소 내에서 작동하지 않음 (0) | 2022.10.02 |
간단한 PHP 개발 서버가 있습니까? (0) | 2022.10.02 |