캔버스에서 재귀 lineTo 호출에서 애니메이션을 어떻게 만들 수 있습니까?

Zeyad Etman

캔버스에 hilbert 곡선을 생성하는이 코드 ctx.lineTo는 호출 될 때마다 애니메이션을 만들려고합니다 . 내가 사용하는 많은 솔루션을 시도 setInterval하고를 requestAnimationFrame하지만 그들 중 누구도 작동하지 않습니다.

다음은 코드입니다.

const bw = 904;
const bh = 820;
const pixelX = 10;

const canvas = document.getElementById("board");
canvas.setAttribute("width", bw);
canvas.setAttribute("height", bh);

const ctx = canvas.getContext("2d");
const hilbertCurve = (x, y, Xi, Xj, Yi, Yj, n) => {
  if (n < 0) {
    ctx.lineTo(x + (Xi + Yi) / 2, y + (Xj + Yj) / 2);
  } else {
    hilbertCurve(x, y, Yi / 2, Yj / 2, Xi / 2, Xj / 2, n - 1);
    hilbertCurve(x + Xi / 2, y + Xj / 2, Xi / 2, Xj / 2, Yi / 2, Yj / 2, n - 1);
    hilbertCurve(
      x + Xi / 2 + Yi / 2,
      y + Xj / 2 + Yj / 2,
      Xi / 2,
      Xj / 2,
      Yi / 2,
      Yj / 2,
      n - 1
    );
    hilbertCurve(
      x + Xi / 2 + Yi,
      y + Xj / 2 + Yj,
      -Yi / 2,
      -Yj / 2,
      -Xi / 2,
      -Xj / 2,
      n - 1
    );
  }
};

function draw() {
  ctx.beginPath();
  hilbertCurve(0, 0, bw, 0, 0, bh, 7);
  ctx.strokeStyle = "red";
  ctx.stroke();
}

function init() {
  window.requestAnimationFrame(draw);
}

init();
<canvas id="board"></canvas>

카이도

한 가지 쉬운 해결책은 stroke-dash-arraySVG에 익숙한 사람들이 이미 알고 있는 트릭 을 사용하는 것입니다.
경로를 정의하고를 경로 stroke-dash-array의 길이로 설정 한 다음 반복 할 때마다을 늘려 stroke-dash-offset계속 그려지는 것처럼 보이게합니다.

이 솔루션의 가장 큰 문제는 경로의 길이를 파악할 수 있어야한다는 것입니다.

불행히도 어떤 이유인지 모르겠 기 때문에 Path2D 인터페이스는 그렇게 할 수있는 쉬운 방법을 제공하지 않습니다. 반면 SVGGeometryElement에는 매우 편리한 getTotalLength()메서드가 있습니다. Path2d 및 svg <path> 요소는 동일한 문자열 경로 정의를 허용 할 수 있으므로 hilbertCurve함수가 문자열 정의를 반환하도록 만든 다음이 문자열을 svg <path> 및 컨텍스트의 Path2D 개체 드로어 블 모두에 사용할 수 있습니다.

const bw = 904;
const bh = 820;
const pixelX = 10;

let path_as_string = "" + hilbertCurve( 0, 0, bw, 0, 0, bh, 7).replace('L', 'M');

const path = new Path2D( path_as_string );
const speed = 5;
const totalLength = getPathLength( path_as_string );

let offset = 0;
const canvas = document.getElementById("board");
canvas.setAttribute("width", bw);
canvas.setAttribute("height", bh);

const ctx = canvas.getContext("2d");
function hilbertCurve( x, y, Xi, Xj, Yi, Yj, n ) {
  if (n < 0) {
    return "L" + (x + (Xi + Yi) / 2) + "," + (y + (Xj + Yj) / 2);
  } else {
    return (
      hilbertCurve(x, y, Yi / 2, Yj / 2, Xi / 2, Xj / 2, n - 1) +
      hilbertCurve(x + Xi / 2, y + Xj / 2, Xi / 2, Xj / 2, Yi / 2, Yj / 2, n - 1) +
      hilbertCurve(
        x + Xi / 2 + Yi / 2,
        y + Xj / 2 + Yj / 2,
        Xi / 2,
        Xj / 2,
        Yi / 2,
        Yj / 2,
        n - 1
      ) +
      hilbertCurve(
        x + Xi / 2 + Yi,
        y + Xj / 2 + Yj,
        -Yi / 2,
        -Yj / 2,
        -Xi / 2,
        -Xj / 2,
        n - 1
      )
    );
  }
};

function draw() {
  ctx.clearRect(0,0,canvas.width,canvas.height)
  ctx.lineDashOffset = offset;
  ctx.stroke(path);

  offset += speed;
  if( offset < totalLength ) {
    requestAnimationFrame(draw);
  }
}

function init() {
  ctx.strokeStyle = "red";
  ctx.setLineDash( [ 0, totalLength, totalLength ] );
  requestAnimationFrame(draw);
}

init();

// returns the length of a path from a string definition
function getPathLength( path ) {
  const elem = document.createElementNS( 'http://www.w3.org/2000/svg', 'path' );
  elem.setAttribute( 'd', path );
  return elem.getTotalLength();
}
canvas { border: 1px solid; }
The animation starts at the bottom left corner<br>
<canvas id="board"></canvas>

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

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

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

HTML / Javascript에서 재귀 메뉴를 어떻게 만들 수 있습니까?

분류에서Dev

SQL에서 재귀 쿼리를 어떻게 만들 수 있습니까?

분류에서Dev

Haskell에서 재귀 호출을 어떻게 제한 할 수 있습니까?

분류에서Dev

탭했을 때 UICollectionViewCell에서 어떻게이 애니메이션을 만들 수 있습니까?

분류에서Dev

캔버스의 루프에 별 행을 어떻게 만들 수 있습니까?

분류에서Dev

활동을 마치기 전에 어떻게 애니메이션을 만들 수 있습니까?

분류에서Dev

눈송이 애니메이션에서 그림과 움직임을 어떻게 변경하고 더 애니메이션으로 만들 수 있습니까?

분류에서Dev

@ObservedObject에 대한 변경 사항을 어떻게 애니메이션으로 만들 수 있습니까?

분류에서Dev

jquery로 캔버스에 도구를 어떻게 만들 수 있습니까?

분류에서Dev

여러 별칭에 대해 정의 된 재귀 Python 유형을 어떻게 만들 수 있습니까?

분류에서Dev

이 재귀 함수에서 이러한 대괄호의 균형을 어떻게 맞출 수 있습니까?

분류에서Dev

C #에서 버튼을 어떻게 만들 수 있습니까?

분류에서Dev

다른 bin 크기로 히스토그램을 보여주는 R에서 애니메이션을 어떻게 만들 수 있습니까?

분류에서Dev

좌표 만 알고있을 때 Tkinter 캔버스에서 개체를 어떻게 이동할 수 있습니까?

분류에서Dev

C에서 메뉴를 어떻게 만들 수 있습니까?

분류에서Dev

캔버스에 스프라이트를 그리는 함수를 어떻게 만들 수 있습니까?

분류에서Dev

중첩 목록에서 원자가 발생하는 횟수를 계산하는 LISP에서 재귀 함수를 어떻게 만들 수 있습니까?

분류에서Dev

이 Java 메서드의 첫 번째 for 루프를 재귀 호출로 어떻게 수정할 수 있습니까?

분류에서Dev

App Store와 같은 컬렉션 뷰 셀 내에서 UICollectionView 애니메이션을 어떻게 만들 수 있습니까?

분류에서Dev

자바 스크립트에서 50k 이상을 호출하는 재귀 함수를 어떻게 호출 할 수 있습니까?

분류에서Dev

Windows Phone 애플리케이션에서 어떻게 동적 제목을 만들 수 있습니까?

분류에서Dev

Linux 터미널에서 실행할 Javascript 애플리케이션을 어떻게 만들 수 있습니까?

분류에서Dev

mysql에서 피벗을 어떻게 만들 수 있습니까?

분류에서Dev

MongoDB에서 문서를 어떻게 만들 수 있습니까?

분류에서Dev

거북이에서 버튼을 어떻게 만들 수 있습니까?

분류에서Dev

React에서 객체 배열에 대한 조건부 축소 호출을 어떻게 만들 수 있습니까?

분류에서Dev

간격을두고 호출 할 서비스에 대한 재귀 호출을 어떻게 코딩 할 수 있습니까?

분류에서Dev

재귀 함수에서 벡터를 어떻게 인쇄 할 수 있습니까?

분류에서Dev

SwiftUI에서 Blue View를 어떻게 만들 수 있습니까?

Related 관련 기사

  1. 1

    HTML / Javascript에서 재귀 메뉴를 어떻게 만들 수 있습니까?

  2. 2

    SQL에서 재귀 쿼리를 어떻게 만들 수 있습니까?

  3. 3

    Haskell에서 재귀 호출을 어떻게 제한 할 수 있습니까?

  4. 4

    탭했을 때 UICollectionViewCell에서 어떻게이 애니메이션을 만들 수 있습니까?

  5. 5

    캔버스의 루프에 별 행을 어떻게 만들 수 있습니까?

  6. 6

    활동을 마치기 전에 어떻게 애니메이션을 만들 수 있습니까?

  7. 7

    눈송이 애니메이션에서 그림과 움직임을 어떻게 변경하고 더 애니메이션으로 만들 수 있습니까?

  8. 8

    @ObservedObject에 대한 변경 사항을 어떻게 애니메이션으로 만들 수 있습니까?

  9. 9

    jquery로 캔버스에 도구를 어떻게 만들 수 있습니까?

  10. 10

    여러 별칭에 대해 정의 된 재귀 Python 유형을 어떻게 만들 수 있습니까?

  11. 11

    이 재귀 함수에서 이러한 대괄호의 균형을 어떻게 맞출 수 있습니까?

  12. 12

    C #에서 버튼을 어떻게 만들 수 있습니까?

  13. 13

    다른 bin 크기로 히스토그램을 보여주는 R에서 애니메이션을 어떻게 만들 수 있습니까?

  14. 14

    좌표 만 알고있을 때 Tkinter 캔버스에서 개체를 어떻게 이동할 수 있습니까?

  15. 15

    C에서 메뉴를 어떻게 만들 수 있습니까?

  16. 16

    캔버스에 스프라이트를 그리는 함수를 어떻게 만들 수 있습니까?

  17. 17

    중첩 목록에서 원자가 발생하는 횟수를 계산하는 LISP에서 재귀 함수를 어떻게 만들 수 있습니까?

  18. 18

    이 Java 메서드의 첫 번째 for 루프를 재귀 호출로 어떻게 수정할 수 있습니까?

  19. 19

    App Store와 같은 컬렉션 뷰 셀 내에서 UICollectionView 애니메이션을 어떻게 만들 수 있습니까?

  20. 20

    자바 스크립트에서 50k 이상을 호출하는 재귀 함수를 어떻게 호출 할 수 있습니까?

  21. 21

    Windows Phone 애플리케이션에서 어떻게 동적 제목을 만들 수 있습니까?

  22. 22

    Linux 터미널에서 실행할 Javascript 애플리케이션을 어떻게 만들 수 있습니까?

  23. 23

    mysql에서 피벗을 어떻게 만들 수 있습니까?

  24. 24

    MongoDB에서 문서를 어떻게 만들 수 있습니까?

  25. 25

    거북이에서 버튼을 어떻게 만들 수 있습니까?

  26. 26

    React에서 객체 배열에 대한 조건부 축소 호출을 어떻게 만들 수 있습니까?

  27. 27

    간격을두고 호출 할 서비스에 대한 재귀 호출을 어떻게 코딩 할 수 있습니까?

  28. 28

    재귀 함수에서 벡터를 어떻게 인쇄 할 수 있습니까?

  29. 29

    SwiftUI에서 Blue View를 어떻게 만들 수 있습니까?

뜨겁다태그

보관