css - 仅清洁 Canvas 上的局部绘图

标签 css animation canvas

我看到您可以使用 CanvasRenderingContext2D.clearRect 清除部分 Canvas .此函数将根据指定的坐标清除全部/部分 Canvas 。是否可以清除一些前景图,但保留背景图?

在 React 组件内部,我有以下内容

  componentDidMount() {
    this.canvas = this.canvasRef.current;
    this.c = this.canvas.getContext('2d')

    this.canvas.width = window.innerWidth
    this.canvas.height = window.innerHeight

    window.addEventListener('resize', this.resize)

    this.init() 
    this.backgroundGradientAnimate() //draw background gradient
    window.requestAnimationFrame(this.step)

  }

  // generate stars
  init = () => {
    this.stars = []

    for (let i = 0; i < 150; i++) {
      const x = Math.random() * this.canvas.width;
      const y = Math.random() * this.canvas.height
      const r = Math.random() * 3
      this.stars.push(new Star(x, y, r, 'white'))
    }
  }

  draw = (star) => {
    this.c.save()
    this.c.beginPath()
    this.c.arc(star.x, star.y, star.radius, 0, Math.PI * 2, false)
    this.c.fillStyle = this.getRandomColor()
    this.c.fill();
    this.c.closePath();
    this.c.restore()
  }

  starsAnmiate = () => {
    this.stars.forEach(star => this.draw(star))
  }

  // only animate in such time
  step = (elapsedTime) => {
    let delta = elapsedTime - this.lastFrameTime || 0

    window.requestAnimationFrame(this.step)

  if (this.lastFrameTime && delta < 1000) {
    return;
  }

  this.lastFrameTime = elapsedTime

  this.starsAnmiate();
  }

问题是在动画重复播放后,所有的星星都没有消失。有没有办法只清理星星的绘图但保留 backgroundGradient,或者两幅图总是必须同时清理,因为它们位于同一个 Canvas 上?

总的来说,我正在尝试创建这些星星的闪烁效果。当我每次都需要清理/重绘整个 Canvas 以模拟每颗星星的闪烁时,这似乎是一个很大的开销。

[编辑]

  1. 为了优化动画效果,您可以绘制 2 个单独的 Canvas 作为 HERE

最佳答案

有几种方法可以做到这一点,但它们都涉及使用某种变通方法。

从本质上讲,这听起来像是您希望在单个 Canvas 上拥有多个,这样您就可以从其中一个而不是其他中删除。遗憾的是,没有允许您执行此操作的 native 功能。

Canvas 被设置为具有一个(且只有一个)上下文,2D 或 3D。当您在上下文中绘图时,您会更改构成该 Canvas 的各个像素的颜色。 JavaScript 对特定绘图下面的内容没有概念,因为它直接对 Canvas 的每个像素进行更改(您也可以争辩说 JS 甚至没有绘图的概念,但事实并非如此在这里特别相关)。

如果你想拥有多个独立支持删除的层,你可以做以下两件事之一,这两者都有缺点:

  • 将多个 Canvas 元素堆叠在一起并单独修改每个元素。请注意,使用此方法,您将无法一次轻松导出所有 Canvas 的内容。
  • 为每一层维护一个一维像素 Uint8ClampedArray,并使用 ctx.putImageData 按分层顺序直接绘制每个数组。使用类型化数组比原始数组更快,但这种数据结构在概念上有点不稳定。您可以阅读有关此方法的更多信息 herehere .

关于css - 仅清洁 Canvas 上的局部绘图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57631283/

相关文章:

javascript - 将 Overlay 添加到弹出窗口并添加输入类型字段以退出表单

javascript - 如何更改脚本以适合下拉列表?

css - 仅使用 CSS3 在悬停时旋转并在动画后停止?

Delphi如何在TCanvas上快速绘制TColor的二维数组?

html - 在我的网站上,开发人员讨论了如何解决它 [html]

c# - 将连续动画应用到 WPF 中的 Canvas

javascript - 在 Canvas 上逐步绘制线条动画

javascript - 如何在 Adob​​e Animate CC 中使用舞台宽度和高度(Canvas 文档)

javascript - 如何用javascript向服务器发送数据

html - img <a href> 链接延伸到父 div 的整个宽度,而不是仅覆盖 img