Создание линейной анимации на холсте - PullRequest
0 голосов
/ 06 июля 2018

Я новичок в рисовании на холсте. Я хочу нарисовать модель фотоэлектрической струны и направление потока электронов в тег <canvas>.

Это то, чего я хочу добиться, перерисовывая линии со следующего направления:

enter image description here

Как изначально установить местоположение анимации и нужно ли его обновлять с помощью setTimeout?

Вот что я пытаюсь сделать до сих пор:

var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");

if (canvas.getContext) {
  var ctx = canvas.getContext('2d');
  // drawing code here

  /* First Row */
  ctx.fillStyle = "rgb(2,150,224, 1)";
  ctx.fillRect(50, 50, 50, 50);

  ctx.fillStyle = "rgb(2,150,224, 1)";
  ctx.fillRect(110, 50, 50, 50);

  ctx.fillStyle = "rgb(188,12,50, 1)";
  ctx.fillRect(170, 50, 50, 50);

  ctx.fillStyle = "rgb(2,150,224, 1)";
  ctx.fillRect(230, 50, 50, 50);

  ctx.fillStyle = "rgb(2,150,224, 1)";
  ctx.fillRect(290, 50, 50, 50);

  /* Second Row */
  ctx.fillStyle = "rgb(0,106,160, 1)";
  ctx.fillRect(50, 150, 50, 50);

  ctx.fillStyle = "rgb(0,106,160, 1)";
  ctx.fillRect(110, 150, 50, 50);

  ctx.fillStyle = "rgb(0,106,160, 1)";
  ctx.fillRect(170, 150, 50, 50);

  ctx.fillStyle = "rgb(0,106,160, 1)";
  ctx.fillRect(230, 150, 50, 50);

  ctx.fillStyle = "rgb(0,106,160, 1)";
  ctx.fillRect(290, 150, 50, 50);

  /* Paths */
  ctx.beginPath();
  ctx.lineWidth = "3";
  ctx.strokeStyle = "rgb(34,177,76, 1)";
  ctx.moveTo(0, 75);
  ctx.lineTo(400, 75);
  ctx.stroke();

  ctx.beginPath();
  ctx.lineWidth = "10";
  ctx.strokeStyle = "rgb(34,177,76, 1)";
  ctx.moveTo(400, 75);
  ctx.lineTo(400, 175);
  ctx.stroke();

  ctx.beginPath();
  ctx.lineWidth = "3";
  ctx.strokeStyle = "rgb(34,177,76, 1)";
  ctx.moveTo(0, 175);
  ctx.lineTo(400, 175);
  ctx.stroke();


} else {
  // canvas-unsupported code here
}
/* canvas {
  border: 1px solid #d3d3d3;
} */
<canvas id="myCanvas" width="400" height="400">
Your browser does not support the HTML5 canvas tag.</canvas>

Буду признателен за любую помощь!

1 Ответ

0 голосов
/ 06 июля 2018

Есть много способов оживить это; вот мой подход (выдержка; см. JSFiddle для полного кода):

var lerp = (a, b, t) => a + t * (b - a);
var speed = 0.01;
var time = 0;
var visited = [];
var points = [
  {
    from: { x: 0, y: 75 },
    to: { x: 395, y: 75 }
  },
  {
    from: { x: 395, y: 75 },
    to: { x: 395, y: 175 }
  },
  {
    from: { x: 395, y: 175 },
    to: { x: 0, y: 175 }
  }
];

/* Paths */
ctx.lineWidth = 3;
ctx.strokeStyle = "rgb(34, 177, 76, 1)";

(function update() {
  if (points.length) {
    visited.push({
        x: lerp(points[0].from.x, points[0].to.x, time),
        y: lerp(points[0].from.y, points[0].to.y, time)
    });

    ctx.clearRect(0, 0, canvas.width, canvas.height);
    drawBoxes(ctx);
    ctx.beginPath();
    ctx.moveTo(visited[0].x, visited[0].y)
    visited.forEach(e => ctx.lineTo(e.x, e.y));
    ctx.stroke();

    time += speed;

    if (time >= 1) {
        time = 0;
        points.shift();
    }

    requestAnimationFrame(update);
  }
})();

Идея состоит в том, чтобы сохранить структуру данных всех поворотных точек, затем lerp вдоль пути, рисуя линию вдоль пути. Используйте функцию easing вместо lerp, если вы предпочитаете более «современную» анимацию; Ослабление обычно проще реализовать и может привести к удалению некоторого кода (например, нет необходимости отслеживать начальные точки и время).

Последнее небольшое замечание - ваш исходный код обрезал линию по правому краю холста, поэтому я позволил себе использовать 395 вместо 400 для ширины рисования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...