解决增量矩阵缩放因子相乘时造成的计算错误 导致动画合成时参数不对的问题

原创
10/12 22:49
阅读数 0

之前纯粹是想多了... 以为会很麻烦, 结果就是个映射而已...

 

 

线性

let preP = 0;
let ss = 1;
const size = 100;
const list = [];
const N = 2;
for (let i = 1; i <= size; i++) {
  const p = i / size;
  const ds = N ** (p - preP);
  ss *= ds;
  preP = p;
  list.push(`[${i},${ss}]`);
}
console.log("[" + list.join(",") + "],");

 

二次

let preP = 0;
let ss = 1;
const size = 100;
const list = [];
const N = 2;
for (let i = 1; i <= size; i++) {
  const p = (i / size) ** 2;
  const ds = N ** (p - preP);
  ss *= ds;
  preP = p;
  list.push(`[${i},${ss}]`);
}
console.log("[" + list.join(",") + "],");

 

 

可以看到, 缩放最后的比例已经是准确的了

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="https://unpkg.com/rematrix"></script>
    <script src="./anime.js"></script>
    <style>
      .box {
        width: 50px;
        height: 50px;
        background: deepskyblue;
      }
    </style>
  </head>
  <body>
    <button onclick="move('x')">moveX</button>
    <button onclick="move('y')">moveY</button>
    <button onclick="scale()">scale</button>
    <button onclick="rotate()">rotate</button>
    <br />
    <br />
    <br />
    <div id="box" class="box"></div>
    <script>
      const box = document.getElementById("box");
      const sleep = (n = 16) => new Promise((r) => setTimeout(r, n));

      const doAnime = ({
        targets, // dom
        duration, // 动画持续时间
        getMtx, // 根据百分比获取矩阵
      }) => {
        console.log("doAnime", targets);
        let startTime = performance.now();
        let endTime = duration + startTime;
        let raf;
        const play = (now) => {
          // 如果超时了, 取消
          if (now > endTime) cancelAnimationFrame(raf);
          else raf = requestAnimationFrame(play);

          // 动画执行百分比
          const p = minMax((now - startTime) / duration, 0, 1);
          console.log("now", now, p);

          //执行动画
          const oldMtx =
            getComputedStyle(targets).transform === "none"
              ? "matrix(1, 0, 0, 1, 0, 0)"
              : getComputedStyle(targets).transform;
          const transform = Rematrix.fromString(oldMtx);
          const s = getMtx(p);
          let product = [transform, s].reduce(Rematrix.multiply);
          targets.style.transform = Rematrix.toString(product);
        };
        raf = requestAnimationFrame(play);
      };

      async function move(direction) {
        const distance = 200;
        let s = penner["easeOutBack"]()(0) * distance;
        const config = {
          targets: box,
          duration: 3000,
          getMtx(p) {
            const x = penner["easeOutBack"]()(p) * distance;
            const m =
              direction === "x"
                ? Rematrix.translateX(x - s)
                : Rematrix.translateY(x - s);
            s = x;
            return m;
          },
        };
        doAnime(config);
      }
      async function rotate() {
        const degree = 90;
        let s = penner["easeOutBack"]()(0) * degree;
        const config = {
          targets: box,
          duration: 3000,
          getMtx(p) {
            const x = penner["easeOutBack"]()(p) * degree;
            const m = Rematrix.rotate(x - s);
            s = x;
            return m;
          },
        };
        doAnime(config);
      }

      async function scale() {
        const degree = 2;
        let preX = 0;
        const config = {
          targets: box,
          duration: 3000,
          getMtx(p) {
            const x = penner["easeOutBack"]()(p);
            const ds = degree ** (x - preX);
            console.log(x, preX, s, ds);
            const m = Rematrix.scale(ds);
            preX = x;
            return m;
          },
        };
        doAnime(config);
      }
    </script>
  </body>
</html>

 

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
OSCHINA
登录后可查看更多优质内容
返回顶部
顶部