首页 > 解决方案 > 仅清除画布的某些组件

问题描述

我正在创建一个带有画布的轮播滑块。对于每张新照片幻灯片,我想保留前一张,直到新照片完全进来。

我使用 requestAnimationFrame 来做滑动效果。每次,我都需要清除动画的画布。但我想保留以前的图像(绘图)。

这是效果的示例,但我以非常低效的方式进行操作。我的 javascript

window.onload = () => {
  let canvas = document.getElementById("myCanvas");
  let ctx = canvas.getContext("2d");

  let head = canvas.width;
  function draw1() {
    if (head > 0) {
      head = head - 10;
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      ctx.fillStyle = "rgba(0, 255, 255,1)";
      ctx.fillRect(head, 0, canvas.width - head, canvas.height);
      window.requestAnimationFrame(draw1);
    }
  }

  function draw2() {
    if (head > 0) {
      head = head - 10;
      ctx.clearRect(0, 0, canvas.width, canvas.height);

      // Draw the previous canvas again for every update
      ctx.fillStyle = "rgba(0, 255, 255,1)";
      ctx.fillRect(0, 0, canvas.width, canvas.height);

      ctx.fillStyle = "rgba(255, 0, 255,1)";
      ctx.fillRect(head, 0, canvas.width - head, canvas.height);
      window.requestAnimationFrame(draw2);
    }
  }

  function draw3() {
    if (head > 0) {
      head = head - 10;
      ctx.clearRect(0, 0, canvas.width, canvas.height);

      // Draw the previous canvas again for every update
      ctx.fillStyle = "rgba(255, 0, 255,1)";
      ctx.fillRect(0, 0, canvas.width, canvas.height);

      ctx.fillStyle = "rgba(255, 255, 0,1)";
      ctx.fillRect(head, 0, canvas.width - head, canvas.height);
      window.requestAnimationFrame(draw3);
    }
  }
  head = canvas.width;
  draw1();

  setTimeout(() => {
    head = canvas.width;
    draw2();
  }, 2000);

  setTimeout(() => {
    head = canvas.width;
    draw3();
  }, 4000);
};

任何帮助表示赞赏。谢谢。

标签: javascripthtmlcsscanvas

解决方案


对于您的情况,您可以在不清除画布的情况下绘制上一个图像

window.onload = () => {
  let canvas = document.getElementById('myCanvas')
  let ctx = canvas.getContext('2d')
  let head = canvas.width

  function drawImage(current) {
    if (head > 0) {
      head = head - 10
      ctx.drawImage(current, head, 0, canvas.width, canvas.height)
      window.requestAnimationFrame(() => drawImage(current))
    }
  }

  const empty = new Image()

  const img1 = new Image()
  img1.src =
    'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQAegr5NqpnuNQdxthB4Ys5O_uiyEqs-CQp6w&usqp=CAU'


  const img2 = new Image()
  img2.src =
    'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSHFvenDq4nX-LgsmrRPamE9i-NMBkefW7Lzg&usqp=CAU'

  const img3 = new Image()
  img3.src =
    'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSyiU9Jkual4WsPg38vFfxvYgDQlUdzOOecVg&usqp=CAU'

  head = canvas.width

  img1.onload = () => {
    drawImage(img1)
  }

  img2.onload = () => {
    setTimeout(() => {
      head = canvas.width
      drawImage(img2)
    }, 2000)
  }

  img3.onload = () => {
    setTimeout(() => {
      head = canvas.width
      drawImage(img3)
    }, 4000)
  }
}
body {
  display: flex;
  justify-content: center;
  align-items: center;
}

canvas {
  border: 1px solid #000000;
}
<canvas id="myCanvas" width="440" height="160"></canvas>

编辑:

对于透明图像,您可以只清除显示新透明图像的画布部分。所以像:

ctx.clearRect(head, 0, canvas.width - head, canvas.height)

这是一个例子:

window.onload = () => {
  let canvas = document.getElementById('myCanvas')
  let ctx = canvas.getContext('2d')
  let head = canvas.width

  function drawImage(current) {
    if (head > 0) {
      head = head - 10
      ctx.clearRect(head, 0, canvas.width - head, canvas.height)
      ctx.drawImage(current, head, 0, canvas.width, canvas.height)
      window.requestAnimationFrame(() => drawImage(current))
    }
  }

  const empty = new Image()

  const img1 = new Image()
  img1.src = 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQAegr5NqpnuNQdxthB4Ys5O_uiyEqs-CQp6w&usqp=CAU'

  const img2 = new Image()
  img2.src = 'https://api.iconify.design/foundation:social-github.svg'
  const img3 = new Image()
  img3.src = 'https://api.iconify.design/foundation:social-twitter.svg'

  head = canvas.width

  img1.onload = () => {
    drawImage(img1)
  }

  img2.onload = () => {
    setTimeout(() => {
      head = canvas.width
      drawImage(img2)
    }, 2000)
  }

  img3.onload = () => {
    setTimeout(() => {
      head = canvas.width
      drawImage(img3)
    }, 4000)
  }
}
body {
  display: flex;
  justify-content: center;
  align-items: center;
}

canvas {
  border: 1px solid #000000;
}

body {
  display: flex;
  justify-content: center;
  align-items: center;
}

canvas {
  border: 1px solid #000000;
}
<canvas id="myCanvas" width="440" height="170"></canvas>

为了在前一个图像上放置一个透明图像,您可以执行以下操作:

window.onload = () => {
  let canvas = document.getElementById('myCanvas')
  let ctx = canvas.getContext('2d')
  let head = canvas.width

  function drawImage(prev, current) {
    if (head > 0) {
      head = head - 10
      ctx.clearRect(head, 0, canvas.width - head, canvas.height)
      ctx.drawImage(prev, 0, 0, canvas.width, canvas.height)
      ctx.drawImage(current, head, 0, canvas.width, canvas.height)
      window.requestAnimationFrame(() => drawImage(prev, current))
    }
  }

  const empty = new Image()

  const img1 = new Image()
  img1.src = 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQAegr5NqpnuNQdxthB4Ys5O_uiyEqs-CQp6w&usqp=CAU'

  const img2 = new Image()
  img2.src = 'https://api.iconify.design/foundation:social-github.svg'

  const img3 = new Image()
  img3.src = 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSHFvenDq4nX-LgsmrRPamE9i-NMBkefW7Lzg&usqp=CAU'

  const img4 = new Image()
  img4.src = 'https://api.iconify.design/foundation:social-twitter.svg'



  head = canvas.width

  img1.onload = () => {
    drawImage(empty, img1)
  }

  img2.onload = () => {
    setTimeout(() => {
      head = canvas.width
      drawImage(img1, img2)
    }, 2000)
  }

  img3.onload = () => {
    setTimeout(() => {
      head = canvas.width
      drawImage(img2, img3)
    }, 5000);
  }


  img4.onload = () => {
    setTimeout(() => {
      head = canvas.width
      drawImage(img3, img4)
    }, 8000);
  }

}
body {
  display: flex;
  justify-content: center;
  align-items: center;
}

canvas {
  border: 1px solid #000000;
}
<canvas id="myCanvas" width="440" height="170"></canvas>


推荐阅读