Firefox 的跳转涉及 CSS 缩放和画布

问题描述 投票:0回答:1

在 Firefox (121.0b9) 中,缩放画布元素时,我注意到轻微的抖动。我在 Safari 或 Chromium 中没有遇到过这种情况。有没有办法在 Firefox 中解决这个问题?

这是一个示例(JSFiddle)。 (如果您使用的是 macOS,请激活“使用带有修饰键的滚动手势进行缩放”以放大右下角。在 JSFiddle 上,当您放大时,请使用“Command + Enter”重新运行。)

<!DOCTYPE html>

<style>
  canvas {
    margin: 100px;
  }
</style>

<canvas width="400" height="400" />

<script>
  window.onload = function () {
    // make canvas
    const elem = document.querySelector("canvas");
    const ctx = elem.getContext("2d");
    ctx.fillStyle = "yellow";
    ctx.fillRect(0, 0, elem.width, elem.height);
    ctx.fillStyle = "black";
    ctx.fillRect(50, 50, 300, 300);

    // scale loop
    const start = performance.now();
    const end = start + 2000;

    const tick = () => {
      const now = performance.now();
      const t = Math.min(1, (now - start) / (end - start));
      const t2 = 1 - Math.pow(2, -10 * t); // easeOutExpo
      elem.style.transform = `scale(${1 - 0.5 * t2})`;
      if (now < end) {
        requestAnimationFrame(tick);
      }
    };

    tick();
  };
</script>

可能相关:https://bugzilla.mozilla.org/show_bug.cgi?id=663776

javascript canvas css-transforms
1个回答
0
投票

你可以试试这个,它确实可以减少晃动

只需将其限制为

3 decimal places
,然后附加
0.0002

它会平滑它并减少任何精细的浮点数废话,您可以调整这些值以满足您的需要,但这应该足够好

const tick = () => {
    const now = performance.now();
    const t = Math.min(1, (now - start) / (end - start));
    const t2 = parseFloat(1 - Math.pow(2, -10 * t).toFixed(3)) + 0.0002;
    elem.style.transform = `scale(${1 - 0.5 * t2})`;
    if (now < end) {
    requestAnimationFrame(tick);
    }
};

代码片段

<!DOCTYPE html>

<style>
  canvas {
    margin: 100px;
  }
</style>

<canvas width="400" height="400" />

<script>
  window.onload = function () {
    // make canvas
    const elem = document.querySelector("canvas");
    const ctx = elem.getContext("2d");
    ctx.fillStyle = "yellow";
    ctx.fillRect(0, 0, elem.width, elem.height);
    ctx.fillStyle = "black";
    ctx.fillRect(50, 50, 300, 300);

    // scale loop
    const start = performance.now();
    const end = start + 2000;

    const tick = () => {
        const now = performance.now();
        const t = Math.min(1, (now - start) / (end - start));
        const t2 = parseFloat(1 - Math.pow(2, -10 * t).toFixed(3)) + 0.0002;
        elem.style.transform = `scale(${1 - 0.5 * t2})`;
        if (now < end) {
        requestAnimationFrame(tick);
        }
    };

    tick();
  };
</script>

© www.soinside.com 2019 - 2024. All rights reserved.