Advertisement
Sonnet_Songbird

DrawPath.js

May 12th, 2024
701
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JavaScript 4.57 KB | Source Code | 0 0
  1. // const canvas = document.getElementById("canvasView");
  2. // const ctx = canvas.getContext("2d"); 필요.
  3. // 캔버스에 대해 전처리 알고리즘이 필요하면 const canvasPostprocessing = () => {}
  4.  
  5. //
  6.  
  7.  
  8. const clearCanvas = function (canvas) {
  9.     const ctx = canvas.getContext('2d');
  10.     ctx.clearRect(0, 0, canvas.width, canvas.height);
  11.     if (typeof canvasPostprocessing !== 'undefined') {
  12.         canvasPostprocessing(canvas);
  13.     }
  14. }
  15.  
  16. const findPath = function () {
  17.     // 각 정점간의 연결을 나타내는 path를 시작점에서부터 끝점까지 순서대로 담은 배열을 반환
  18. };
  19.  
  20. const drawPath = function () {
  21.     const path = findPath();
  22.     if (path.length === 0) {
  23.         return false;
  24.     }
  25.  
  26.     drawRouteAnimated(path, "red", 3, (500 + path.length * 200)); // path배열, 색상, 두께, duration
  27.     return true;
  28. };
  29.  
  30.  
  31. //offset은 캔버스 객체의 데이터셋에 담아서 설정
  32. const toCoordinate = function () {
  33.     const position = ("")//path를 통해 정점을 가리키는 매개면수를 받아 좌표 정보를 가진 정점을 찾아옴
  34.     let offsetX = 0;
  35.     let offsetY = 0;
  36.     if (canvas.dataset.offsetX) {
  37.         offsetX = canvas.dataset.offsetX;
  38.     }
  39.     if (canvas.dataset.offsetY) {
  40.         offsetY = canvas.dataset.offsetY;
  41.     }
  42.     return position ? {x: position.x + Number(offsetX), y: position.y + Number(offsetY)} : null;
  43.     //정점의 좌표 정보(예시에선 position.x / position.y가 존재한다고 간주)에 offSet을 더함.
  44. };
  45.  
  46. const drawAllRoutes = function () {
  47.     clearCanvas(canvas);
  48.     navRepo2D.pathRepo.forEach(function (route) {
  49.         drawRoute([route.posA, route.posB], "black", 1);
  50.     });
  51. };
  52. const drawRoute = function (path, color, width) {
  53.     ctx.strokeStyle = color;
  54.     ctx.lineWidth = width;
  55.  
  56.     ctx.beginPath();
  57.     for (let i = 0; i < path.length - 1; i++) {
  58.         const startPos = toCoordinate(path[i]);
  59.         const endPos = toCoordinate(path[i + 1]);
  60.         if (startPos && endPos) {
  61.             ctx.moveTo(startPos.x, startPos.y);
  62.             ctx.lineTo(endPos.x, endPos.y);
  63.         }
  64.     }
  65.     ctx.stroke();
  66. };
  67.  
  68. const drawPartialRoute = function (startPos, endPos, color, width, partialLength) {
  69.     const segmentLength = Math.sqrt((endPos.x - startPos.x) ** 2 + (endPos.y - startPos.y) ** 2);
  70.     const ratio = partialLength / segmentLength;
  71.     const partialEndX = startPos.x + (endPos.x - startPos.x) * ratio;
  72.     const partialEndY = startPos.y + (endPos.y - startPos.y) * ratio;
  73.     ctx.strokeStyle = color;
  74.     ctx.lineWidth = width;
  75.     ctx.beginPath();
  76.     ctx.moveTo(startPos.x, startPos.y);
  77.     ctx.lineTo(partialEndX, partialEndY);
  78.     ctx.stroke();
  79. };
  80.  
  81. const drawRouteAnimated = function (path, color, width, duration) {
  82.     let startTime = null;
  83.     const totalLength = calcLength(path);
  84.     const animateDraw = function (currentTime) {
  85.         if (!startTime) startTime = currentTime;
  86.         let progress = Math.min(1, (currentTime - startTime) / duration);
  87.         const partialLength = progress * totalLength;
  88.  
  89.         clearCanvas(canvas);
  90.         if (!canvas.dataset.noAllRoutes) {
  91.             drawAllRoutes();
  92.         }
  93.         let remainingLength = partialLength;
  94.         for (let i = 0; i < path.length - 1; i++) {
  95.             const startPos = toCoordinate(path[i]);
  96.             const endPos = toCoordinate(path[i + 1]);
  97.             const segmentLength = calcLength([path[i], path[i + 1]]);
  98.             if (remainingLength >= segmentLength) {
  99.                 drawPartialRoute(startPos, endPos, color, width, segmentLength);
  100.                 remainingLength -= segmentLength;
  101.             } else {
  102.                 const ratio = remainingLength / segmentLength;
  103.                 const partialEndPos = {
  104.                     x: startPos.x + (endPos.x - startPos.x) * ratio,
  105.                     y: startPos.y + (endPos.y - startPos.y) * ratio
  106.                 };
  107.                 drawPartialRoute(startPos, partialEndPos, color, width, remainingLength);
  108.                 break;
  109.             }
  110.         }
  111.         if (progress < 1) {
  112.             requestAnimationFrame(animateDraw);
  113.         }
  114.     };
  115.     requestAnimationFrame(animateDraw);
  116. };
  117.  
  118. const calcLength = function (path) {
  119.     let totalLength = 0;
  120.     for (let i = 0; i < path.length - 1; i++) {
  121.         const startPos = toCoordinate(path[i]);
  122.         const endPos = toCoordinate(path[i + 1]);
  123.         if (startPos && endPos) {
  124.             totalLength += Math.sqrt((endPos.x - startPos.x) ** 2 + (endPos.y - startPos.y) ** 2);
  125.         }
  126.     }
  127.     return totalLength;
  128. };
  129.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement