캔버스에서 더 많은 커서 위치를 얻는 방법

고바 야키 터널

이것은 내 코드입니다.

const canvas = document.getElementById("game");
const ctx = canvas.getContext("2d");

let cursorPositions = [];

function getCursorPosition(e) {
  let r = canvas.getBoundingClientRect();
  if (cursorPositions.length < 100) {
    cursorPositions.push({
      x: e.clientX - r.left,
      y: e.clientY - r.top
    });
  } else {
    for (let i = 0; i < cursorPositions.length - 1; i++)
      cursorPositions[i] = cursorPositions[i + 1];
    cursorPositions[99] = {
      x: e.clientX - r.left,
      y: e.clientY - r.top
    };
  }
  console.log(cursorPositions.length);
}

function draw() {
  ctx.canvas.width = window.innerWidth;
  ctx.canvas.height = window.innerHeight;

  ctx.fillStyle = "#000000";
  ctx.fillRect(0, 0, canvas.width, canvas.height);

  for (let i = 0; i < cursorPositions.length; i++) {
    ctx.fillStyle = "#ffffff";
    ctx.beginPath();
    ctx.arc(cursorPositions[i].x, cursorPositions[i].y, 1, 0, 2 * Math.PI);
    ctx.closePath();
    ctx.fill();
  }
}

function loop() {
  draw();
  requestAnimationFrame(loop);
}

loop();

document.addEventListener("mousemove", function(e) {
  getCursorPosition(e);
});
<canvas id="game"></canvas>

그리고 출력 :

출력 캔버스 이미지

이 출력에서는 커서를 다른 속도로 움직 였고 먼 위치에 점이 그려졌습니다.

연속적인 곡선이 그려 지도록 커서 속도에 관계없이 커서 위치를 더 자주 얻고 싶습니다.

칸막이

두 점 사이에 선형 보간을 사용할 수 있습니다. dl두 점 사이의 최대 거리 라고

고려 A하고B

A---x---x---B

목표는 [A; B]x가 규칙적인 방식으로 간격을두고 있지만 다음보다 작게 분리 되도록 세분화 하는 것입니다.dl

아래 기능에서


function interpolate(a, b, dl) {
  const n = d(a,b)/dl
  const nPoints = Math.ceil(n)-1 //1.5 one point middle, 2, one point middle too
  const dx = (b.x - a.x) / (nPoints + 1)
  const dy = (b.y - a.y) / (nPoints + 1)
  const arr = new Array(nPoints)
  for(let i = 1; i <= nPoints; ++i){
    const x = a.x + i*dx
    const y = a.y + i*dy
    arr[i-1] = { x, y }
  }
  return arr
}

interpolate는 그렇게합니다.

유일하게 감동적인 부분은

const nPoints = Math.ceil(n)-1
if n == 1+0.x, we must add only one point between A and B
if n == 2, we must add only one point
if n == 2+0.x, we must add two points

dxdy변수 위에 단순히 증가를 정의 x하고 y, 계산에 대한 각각 x의 포인트

const canvas = document.getElementById("game");
const ctx = canvas.getContext("2d");

let cursorPositions = [];

function getCursorPosition(e){
    let r = canvas.getBoundingClientRect();
    if(cursorPositions.length < 100){
        cursorPositions.push({
            x: e.clientX - r.left,
            y: e.clientY - r.top
        });
    }else{
        for(let i=0; i<cursorPositions.length-1; i++)
            cursorPositions[i] = cursorPositions[i+1];
        cursorPositions[99] = {
            x: e.clientX - r.left,
            y: e.clientY - r.top
        };
    }
}

function d(a, b){
  return Math.sqrt((b.x - a.x)**2 + (b.y - a.y)**2)
}
function interpolate(a, b, dl) {
  const n = d(a,b)/dl
  const nPoints = Math.ceil(n)-1 //1.5 one point middle, 2, one point middle too
  const dx = (b.x - a.x) / (nPoints + 1)
  const dy = (b.y - a.y) / (nPoints + 1)
  const arr = new Array(nPoints)
  for(let i = 1; i <= nPoints; ++i){
    const x = a.x + i*dx
    const y = a.y + i*dy
    arr[i-1] = { x, y }
  }
  return arr
}
function draw(){
    const dl = 10 // 10px max dist between consecutive points
    ctx.canvas.width = window.innerWidth;
    ctx.canvas.height = window.innerHeight;

    ctx.fillStyle = "#000000";
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    if(cursorPositions.length == 0) return
    cursorPositions.reduce((last, cur) => {
        const n = d(last, cur)/dl
        if(n > 1){
          ctx.fillStyle = "red";
          interpolate(last, cur, dl).forEach(({ x, y }) => {
            ctx.beginPath();
            ctx.arc(x, y, 1, 0, 2 * Math.PI);
            ctx.closePath();
            ctx.fill();   
          })
        }
        ctx.fillStyle = "#ffffff";
        ctx.beginPath();
        ctx.arc(cur.x, cur.y, 1, 0, 2 * Math.PI);
        ctx.closePath();
        ctx.fill();
        return cur
    })
}

function loop(){
    draw();
    requestAnimationFrame(loop);
}

loop();

document.addEventListener("mousemove", function(e){
    getCursorPosition(e);
});
<canvas id="game"></canvas>


그의 게시물 맨 아래에서 질문했듯이 원하는 동작이 곡선 연속적인 곡선을 얻는 것이라면 곡선 을 매끄럽게하는 바람직한 방법은 베 지어 곡선을 사용하는 것 입니다.

아래는 입방체를 적용한 것입니다. 그것은 슬프게도 약간의 랙이있다, 그러나 희망 조금을 최적화하여 어쩌면 더 나은 수

const canvas = document.getElementById("game");
const ctx = canvas.getContext("2d");

let cursorPositions = [];

function getCursorPosition(e){
    let r = canvas.getBoundingClientRect();
    if(cursorPositions.length < 100){
        cursorPositions.push({
            x: e.clientX - r.left,
            y: e.clientY - r.top
        });
    }else{
      //keep the same points for each bezier curve
      cursorPositions.shift()
      cursorPositions.shift()
      cursorPositions.shift()
      cursorPositions.push({
          x: e.clientX - r.left,
          y: e.clientY - r.top
      })
    }
}

function d(a, b){
  return Math.sqrt((b.x - a.x)**2 + (b.y - a.y)**2)
}
function b3([P0, P1, P2, P3]) {
  if(!P0 || !P1 || !P2 || !P3) return []
  function add(...v){
    return v.reduce((acc, P) => {
      acc.x += P.x
      acc.y += P.y
      return acc
    }, { x: 0, y: 0 })
  }
  function s(scale, P){
    return { x: P.x*scale, y: P.y*scale }
  }
  const B = t => add(s((1-t)**3, P0), s(3*t*(1-t)**2, P1), s(3*(1-t)*t**2, P2), s(t**3, P3))
  const nPoints = Math.ceil(d(P0, P1) + d(P1, P2) + d(P2, P3))
  const arr = new Array(nPoints)
  let t = 0
  for(let i = 0; i < nPoints; ++i){
    t += 1/nPoints
    arr[i] = B(t)
  }
  return arr
}
function draw(){
    const dl = 1 // 20px max dist between consecutive points
    ctx.canvas.width = window.innerWidth;
    ctx.canvas.height = window.innerHeight;

    ctx.fillStyle = "#000000";
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    if(cursorPositions.length == 0) return
    cursorPositions.reduce((last, cur, i) => {
        const n = d(last, cur)/dl
        if (n > 1 && i % 3 == 0) {
          ctx.fillStyle = "red";
          b3(cursorPositions.slice(i, i+4), dl).forEach(({ x, y }) => {
            ctx.beginPath();
            ctx.arc(x, y, 1, 0, 2 * Math.PI);
            ctx.closePath();
            ctx.fill();   
          })
        }
        ctx.fillStyle = "#ffffff";
        ctx.beginPath();
        ctx.arc(cur.x, cur.y, 1, 0, 2 * Math.PI);
        ctx.closePath();
        ctx.fill();
        return cur
    })
}

function loop(){
    draw();
    requestAnimationFrame(loop);
}

loop();

document.addEventListener("mousemove", function(e){
    getCursorPosition(e);
});
<canvas id="game"></canvas>

edit2 : 마지막으로 사용 가능한 api ctx.bezierCurveTo사용할 수 있습니다.

const canvas = document.getElementById("game");
const ctx = canvas.getContext("2d");

let cursorPositions = [];

function getCursorPosition(e){
    let r = canvas.getBoundingClientRect();
    if(cursorPositions.length < 100){
        cursorPositions.push({
            x: e.clientX - r.left,
            y: e.clientY - r.top
        });
    }else{
      //keep the same points for each bezier curve
      cursorPositions.shift()
      cursorPositions.shift()
      cursorPositions.shift()
      cursorPositions.push({
          x: e.clientX - r.left,
          y: e.clientY - r.top
      })
    }
}

function d(a, b){
  return Math.sqrt((b.x - a.x)**2 + (b.y - a.y)**2)
}

function draw(){
    const dl = 1 // 20px max dist between consecutive points
    ctx.canvas.width = window.innerWidth;
    ctx.canvas.height = window.innerHeight;

    ctx.fillStyle = "#000000";
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    ctx.strokeStyle = 'white'
    if(cursorPositions.length == 0) return
    cursorPositions.reduce((last, cur, i) => {
        const n = d(last, cur)/dl
        if (n > 1 && i % 3 == 0) {
          const [P0, P1, P2, P3] = cursorPositions.slice(i, i+4)
          if(!P3) return cur
          ctx.beginPath();
          ctx.moveTo(P0.x, P0.y)
          ctx.bezierCurveTo(P1.x, P1.y, P2.x, P2.y, P3.x, P3.y)
          ctx.stroke();   
          ctx.closePath();
        }
        ctx.fillStyle = "#ffffff";
        ctx.beginPath();
        ctx.arc(cur.x, cur.y, 1, 0, 2 * Math.PI);
        ctx.closePath();
        ctx.fill();
        return cur
    })
}
function loop(){
    draw();
    requestAnimationFrame(loop);
}

loop();

document.addEventListener("mousemove", function(e){
    getCursorPosition(e);
});
<canvas id="game"></canvas>

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

나무 또는 더 많은 캔버스를 서로 위에 놓는 방법은 무엇입니까?

분류에서Dev

버텍스 쉐이더에서 변형되지 않은 위치를 얻는 방법은 무엇입니까?

분류에서Dev

SRCSRV에서 더 많은 정보를 얻는 방법은 무엇입니까?

분류에서Dev

RSS URL에서 더 많은 피드를 얻는 방법은 무엇입니까?

분류에서Dev

Apache Drill에서 더 많은 오류 세부 정보를 얻는 방법

분류에서Dev

캔버스 상단의 이미지에 대해 마우스 커서 주위에 호버 효과를 얻는 방법은 무엇입니까?

분류에서Dev

kineticjs에서 캔버스 객체를 얻는 방법은 무엇입니까?

분류에서Dev

캔버스 커서 클릭 좌표를 얻는 방법

분류에서Dev

많은 <p>에서 특정 가치를 얻는 방법

분류에서Dev

svg에서 마커 끝 위치를 얻는 방법은 무엇입니까?

분류에서Dev

정보가없는 Windows 8 BSOD에서 더 많은 정보를 얻는 방법은 무엇입니까?

분류에서Dev

Visual Studio에서 더 많은 CPU를 사용하는 방법

분류에서Dev

더 많은 공간을 만들지 않고 캔버스에 div를 오버레이하는 방법

분류에서Dev

배열보다 더 많은 임의의 요소를 배열에서 얻는 방법은 무엇입니까?

분류에서Dev

GCP 함수에서 더 많은 정보를 제공하는 충돌 로그를 얻는 방법

분류에서Dev

루프 내에서 HTML5 캔버스를 렌더링하는 방법

분류에서Dev

Rich : Editor Richfaces by JavaScript에서 커서 위치를 얻는 방법

분류에서Dev

Android : 스피너에서 정수를 얻는 더 좋은 방법

분류에서Dev

변환 된 HTML5 캔버스에서 마우스 위치를 얻는 방법

분류에서Dev

더 큰 jframe에 작은 캔버스를 중앙에 배치하는 방법

분류에서Dev

SwiftUI에서 실제 뷰 렌더링 크기와 위치를 얻는 방법은 무엇입니까?

분류에서Dev

Ace Editor에서 커서 위치 (행 또는 열 아님)를 얻는 방법은 무엇입니까?

분류에서Dev

Windows 커널 드라이버에서 장치 인스턴스 경로를 얻는 방법은 무엇입니까?

분류에서Dev

캔버스에서 이미지 크기를 얻는 방법은 무엇입니까?

분류에서Dev

SQL-많은 테이블에서 더 많은 COUNT를 사용하는 방법은 무엇입니까?

분류에서Dev

laravel의 배열에서 많은 레코드를 얻는 방법

분류에서Dev

HTML 캔버스 아크에서 startAngle 및 endAngle에서 더 작은 각도를 찾는 방법은 무엇입니까?

분류에서Dev

커스텀 렌더러에서 버튼 이미지의 이미지 너비를 얻는 방법은 무엇입니까?

분류에서Dev

Bokeh 서버로 마우스 위치를 얻는 방법은 무엇입니까?

Related 관련 기사

  1. 1

    나무 또는 더 많은 캔버스를 서로 위에 놓는 방법은 무엇입니까?

  2. 2

    버텍스 쉐이더에서 변형되지 않은 위치를 얻는 방법은 무엇입니까?

  3. 3

    SRCSRV에서 더 많은 정보를 얻는 방법은 무엇입니까?

  4. 4

    RSS URL에서 더 많은 피드를 얻는 방법은 무엇입니까?

  5. 5

    Apache Drill에서 더 많은 오류 세부 정보를 얻는 방법

  6. 6

    캔버스 상단의 이미지에 대해 마우스 커서 주위에 호버 효과를 얻는 방법은 무엇입니까?

  7. 7

    kineticjs에서 캔버스 객체를 얻는 방법은 무엇입니까?

  8. 8

    캔버스 커서 클릭 좌표를 얻는 방법

  9. 9

    많은 <p>에서 특정 가치를 얻는 방법

  10. 10

    svg에서 마커 끝 위치를 얻는 방법은 무엇입니까?

  11. 11

    정보가없는 Windows 8 BSOD에서 더 많은 정보를 얻는 방법은 무엇입니까?

  12. 12

    Visual Studio에서 더 많은 CPU를 사용하는 방법

  13. 13

    더 많은 공간을 만들지 않고 캔버스에 div를 오버레이하는 방법

  14. 14

    배열보다 더 많은 임의의 요소를 배열에서 얻는 방법은 무엇입니까?

  15. 15

    GCP 함수에서 더 많은 정보를 제공하는 충돌 로그를 얻는 방법

  16. 16

    루프 내에서 HTML5 캔버스를 렌더링하는 방법

  17. 17

    Rich : Editor Richfaces by JavaScript에서 커서 위치를 얻는 방법

  18. 18

    Android : 스피너에서 정수를 얻는 더 좋은 방법

  19. 19

    변환 된 HTML5 캔버스에서 마우스 위치를 얻는 방법

  20. 20

    더 큰 jframe에 작은 캔버스를 중앙에 배치하는 방법

  21. 21

    SwiftUI에서 실제 뷰 렌더링 크기와 위치를 얻는 방법은 무엇입니까?

  22. 22

    Ace Editor에서 커서 위치 (행 또는 열 아님)를 얻는 방법은 무엇입니까?

  23. 23

    Windows 커널 드라이버에서 장치 인스턴스 경로를 얻는 방법은 무엇입니까?

  24. 24

    캔버스에서 이미지 크기를 얻는 방법은 무엇입니까?

  25. 25

    SQL-많은 테이블에서 더 많은 COUNT를 사용하는 방법은 무엇입니까?

  26. 26

    laravel의 배열에서 많은 레코드를 얻는 방법

  27. 27

    HTML 캔버스 아크에서 startAngle 및 endAngle에서 더 작은 각도를 찾는 방법은 무엇입니까?

  28. 28

    커스텀 렌더러에서 버튼 이미지의 이미지 너비를 얻는 방법은 무엇입니까?

  29. 29

    Bokeh 서버로 마우스 위치를 얻는 방법은 무엇입니까?

뜨겁다태그

보관