首页 > 解决方案 > 一种用于在画布中的正方形或三角形等封闭路径上为点设置动画的算法?

问题描述

如何在闭合路径上为点设置动画。对于下面的示例,我可以对其进行像素推送,但我想知道是否有更好的数学(y)解决方案用于在路径上设置动画。

代码沙盒

注意:我使用 actx.drawImg()来表示该点,因为我希望该点沿路径旋转(代码下方的图像)。

import "./styles.scss";
import o from "./letters/0.svg";

const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const arena = 500;
const margin = 60;
const edge = arena - margin;

let data = [o];
var imgEls = [];

function drawArena() {
  ctx.beginPath();
  ctx.lineWidth = "3";
  ctx.strokeStyle = "DeepSkyBlue";
  const origin = [margin, margin];
  ctx.moveTo(...origin);
  ctx.lineTo(edge, margin);
  ctx.lineTo(edge, edge);
  ctx.lineTo(margin, edge);
  ctx.lineTo(...origin);
  ctx.stroke();
}

function loadImages() {
  return data.map((item, i) => {
    return new Promise((res, rej) => {
      let img = new Image();
      let svg = new Blob([item], { type: "image/svg+xml" });
      let url = window.URL.createObjectURL(svg);
      img.onload = () => {
        imgEls.push(img);

        window.URL.revokeObjectURL(url);
        console.log("loaded");
        res(img);
      };
      img.src = url;
    });
  });
}

Promise.all(loadImages()).then(() => {
  // window.requestAnimationFrame(draw);
  draw();
});

function draw(t) {
  // window.requestAnimationFrame(draw);
  drawArena();
  imgEls.forEach((img, index) => {
    const offset = index * img.width;
    const x = margin + offset;
    const y = margin - img.height;

    ctx.drawImage(img, x, y);
  });
}

在此处输入图像描述

标签: javascriptalgorithmanimationcanvas

解决方案


如果您只是在 2 点之间进行跟踪;您正在寻找线性插值。

这是什么

在数学中,线性插值是一种使用线性多项式在已知数据点的离散集合范围内构造新数据点的曲线拟合方法。

P5js 中的演示

和一个简单的 JS 实现

function lerp(v0, v1, t) {
    return v0*(1-t)+v1*t
}

通过https://github.com/mattdesl/lerp/blob/master/index.js

在复杂路径上的跟踪显然更加复杂。如果您需要该功能,请告诉我,我会看看我能找到什么。


推荐阅读