나는 어떻게 얻을 수의 좌표를 클릭하면 캔버스를 받으려면 어떻게 해야 합니까?

StackOverflow https://stackoverflow.com/questions/55677

  •  09-06-2019
  •  | 
  •  

문제

What's 는 가장 간단한 방법으로 추가 매개하는 캔버스에 요소를 반환하는 x,y 좌표를 클릭(상대적으로 캔버스소)?

더 레거시 브라우저 호환성 필요,Safari,Opera,Firefox 할 것입니다.

도움이 되었습니까?

해결책

편집 2018: 이 대답은 꽤 오래 된 그리고 그것을 사용하여 확인에 대한 오래된 브라우저는 더 이상 필요하지 않습으로 clientXclientY 속성 작업에서 현재 모든 브라우저입니다.당신이를 확인 할 수 있습니다 Patriques 응답 간단한,최근 솔루션입니다.

원래는 대답한다:
로에서 설명하는 문서 내가 찾은 그 당시에 존재하지만 더 이상:

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;

완벽하게 작동됩니다.

다른 팁

업데이트 (5/5/16): patriques'응답 대신 사용해야 합니다,그것은 모두 더 간단하고 신뢰할 수 있습니다.


부터 캔버스지 않는 항상 스타일을 상대하는 전체 페이지 canvas.offsetLeft/Top 지 않는 항상 당신이 필요합니다.이 반환됩니다 숫자의 픽셀 그것은 오프셋에 상대적으로 offsetParent 요소가 될 수 있는 뭔가 div 요소를 포함하는 캔버스 position: relative 스타일 적용됩니다.에 대한 계정이 필요하신 루프를 통해의 체인 offsetParents 을 시작으로 캔버스 요소에 자체입니다.이 코드는 나를 위해 완벽하게 작동에서 테스트,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;

는 경우 다음과 같은 단순하지만 여전히 원하는 크로스 브라우저능 이 솔루션은데 저에게는 효과가 좋았습니다.이것은 단순화@Aldekeins 솔루션 없이 jQuery.

function getCursorPosition(canvas, event) {
    var rect = canvas.getBoundingClientRect();
    var x = event.clientX - rect.left;
    var y = event.clientY - rect.top;
    console.log("x: " + x + " y: " + y);
}

현대적인 브라우저 처리한다.크롬,IE9,파이어폭스 지원인 offsetx/Y 다음과 같이 전달,이벤트에서 클릭 처리기입니다.

function getRelativeCoords(event) {
    return { x: event.offsetX, y: event.offsetY };
}

가장 현대적인 브라우저도 지원 layerX/Y,그러나 크롬과 IE 사용 layerX/Y 에 대한 절대 오프셋의 클릭을 포함하여 페이지 여백,패딩,etc.Firefox 에서 layerX/Y 인 offsetx/Y 는 해당하지만,오프셋지 않는 이전에 존재합니다.그래서,와의 호환성을 위해 약간 오래된 브라우저를 사용할 수 있습니다:

function getRelativeCoords(event) {
    return { x: event.offsetX || event.layerX, y: event.offsetY || event.layerY };
}

에 따르면 신선한 QuirksmodeclientXclientY 방법은 사용할 수 있습니다 모든 주요 브라우저에서.그래서 여기에,그것은 좋은 일하는 코드에서 작동하는 스크롤 div 페이지롤:

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().

나는 전체 demostration 에서 작동하는 모든 브라우저의 전체 소스 코드 솔루션은 이 문제의: 좌표의 마우스 클릭이 캔버스에서 Javascript.데모를 시도하 코드를 복사하고 붙여넣을 텍스트 편집기입니다.다음으로 저장 example.html 그리고,마지막으로,파일을 열고 브라우저입니다.

여기에 작은 수정 라이언 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}
}

조심을 하는 동안 좌표 변환;거기에 여러 비 크로스 브라우저를 반환되는 값에는 이벤트를 클릭합니다.사용 clientX 및 clientY 혼자가 충분하지 않은 경우 브라우저 창을 스크롤(에서 확인 Firefox3.5 과 크롬 3.0).

이 쿼크 모드 문서에서 더 정확한 기능을 사용할 수 있는 하나 pageX 또는 pageY 또는 조합의 clientX 와 문서입니다.체.scrollLeft 및 clientY 와 문서입니다.체.scrollTop 계산을 클릭 좌표계에 상대적인 문서를 기원합니다.

업데이트:또한,offsetLeft 및 offsetTop 를 기준으로 패딩 크기의 요소가 아닌 내부 크기입니다.캔버스와 padding:스타일 적용되지 않습 보고서 왼쪽 상단의 컨텐츠 영역으로 offsetLeft.거기에 다양한 솔루션이 이 문제를;단순한 하나의 수를 명확한 모든 테두리,패딩,etc.스타일스 캔버스에서 자체는 대신 그들을 적용하게 들어있는 상자 캔버스입니다.

내가 무엇인지의 포인트는 이 모든 답변 루프를 통해 상위 요소 고 온갖 종류의 이상한 재료.

HTMLElement.getBoundingClientRect 방법은 설계를 처리하는 실제 위치를 화면의 어떤 요소입니다.이 포함되어 있 스크롤,그래서 물건처럼 scrollTop 이 필요하지 않:

(에서 반) 의 양 스크롤 수행되었습니다 뷰포트의 지역(또는 어떤 스크롤 다른 요소)할 때 계정에 컴퓨팅 경계 직사각형

일반 이미지

매우 간단한 접근 방식 이미곳을 클릭하시면 됩니다.이것은 올바른 만큼 no 야생 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.

Notes

만약 당신이 좋아하지 않을 수정 원 prototypes,변경 기능과 (canvas, event) (대체 thiscanvas).

여기에 매우 좋은 튜토리얼

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

희망이 도움이 됩니다!

JQuery 를 사용하고,2016 년을 얻을 클릭해 상대적인 좌표를 캔버스,난:

$(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>

에 시제품을 사용 cumulativeOffset()을 재귀적 합계로서 언급된 라이언 Artecona 니다.

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 출력 .

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

그래서 이것은 모두 단순하지만 약간 더 복잡한 주제 보다는 것입니다.

첫째로 떨어져 있는 일반적으로 융 여기 질문

  1. 을 얻는 방법을 기준으로 요소 마우스 좌표

  2. 을 얻는 방법은 캔버스의 픽셀 마우스 좌표 2D 캔버스 API 또는 WebGL

그래서,답변

을 얻는 방법을 기준으로 요소 마우스 좌표

는지 여부 요소가 캔버스에 점점 요소의 상대적인 마우스의 좌표가 동일한 모든 요소입니다.

거기에는 2 개의 간단한"라는 질문에 답을 얻는 방법을 캔버스에 상대적인 마우스 좌표"

간단한 대답#1 사용 offsetXoffsetY

canvas.addEventListner('mousemove', (e) => {
  const x = e.offsetX;
  const y = e.offsetY;
});

이 대답을 작품에서는 Chrome,Firefox,Safari.과 달리 다른 모든 이벤트 값 offsetXoffsetY 을 CSS 변환 있습니다.

의 가장 큰 문제 offsetXoffsetY 이의 2019/05 그들은 존재하지 않는 터치에 대한 이벤트와 함께 사용할 수 없습니다 iOS 습니다.그들은 존재에서 포인터 이벤트에 존재하는 Chrome 및 Firefox 그러나지 않지만 사파리 분명히 사파리는 그 작업.

또 다른 문제는 이벤트를 해야 합 캔버스에 자체입니다.는 경우에 당신은 그들을 둘 다른 요소 또는 창에 있지 않은 나중에 선택한 캔버스를 참조하기 쉽습니다.

간단한 대답#2 clientX, clientYcanvas.getBoundingClientRect

는 경우 걱정하지 않 CSS 변환 다음의 간단한 대답은 전화 canvas. getBoundingClientRect() 고 빼 왼쪽에서 clientXtopclientY

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 캔버스 API

이를 위해 우리는 필요하는 가치를 가지고 간 우리가 위에서 변환기로 캔버스가 표시되는 픽셀의 수 캔버스에 자신

canvas.getBoundingClientRectclientXclientY

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

offsetXoffsetY

canvas.addEventListener('mousemove', (e) => {
  const elementRelativeX = e.offsetX;
  const elementRelativeX = e.offsetY;
  const canvasRelativeX = elementRelativeX * canvas.width / canvas.clientWidth;
  const canvasRelativeY = elementRelativeX * 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.getBoundingClientRectevent.clientXevent.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>

Hey,이에 도장,그 원인이 무엇을 했는 코드에서는 이미 이에 대해 프로젝트입니다.

그것은 매우 분명하는 방법을 다시 변환하여 비 dojo 바닐라 JavaScript.

  function onMouseClick(e) {
      var x = e.clientX;
      var y = e.clientY;
  }
  var canvas = dojo.byId(canvasId);
  dojo.connect(canvas,"click",onMouseClick);

는 희망 도움이 됩니다.

여기에는 일부의 수정을 위 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 능 이벤트에서 처리 코드입니다.(그것이 있어야로.우리가 시도해야 우리 기능을 하나의 작업이 각.)

의 값 offsetLeftoffsetTop 상대 offsetParent, 할 수 있는 래퍼 div 노드(또는 그 문제에 대한).이 없을 때 요소 감싸기 canvas 그들은 상대 body, 가 오프셋을 뺄 수 있습니다.이것은 우리가 필요한 이유하의 위치를 결정하는 캔버스 앞에 우리가 아무것도 할 수 있습니다.

신하게 된, e.pageXe.pageY 주의 위치를 기준으로 커서를 문서입니다.그 이유는 우리는 빼 캔버스의 오프셋에서 그 값에 도착하는 진정한 위치.

대체 위치 요소를 직접 사용하는 값의 e.layerXe.layerY.이것은 보다 적게 신뢰할 수 있는 방법에 대해 위의 두 가지 이유:

  1. 이러한 값은 또한 상대적인 문서 전체 이벤트를 받지 않는 장소 내에 위치한 요소
  2. 그들은하지 않은 부분을 어떤 표준

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

나는 응용 프로그램을 만드는 데 캔버스 을 통해 pdf 로,그것의 많은 참여 크기를 조정의 캔버스처럼 확대 pdf 고,차례로서 모든기 PDF 했 크기를 조정하는 캔버스에 적응기의 크기 pdf,갔을 통해 답변을 많은에서 유래,지 않았을 발견한 완벽한 솔루션이는 것이 결국 문제를 해결합니다.

rxjs 고 각 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 )
};
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top