【第4章 图像与视频】4.4 离屏 canvas
文章目录
- 前言
- 为什么要使用 offscreenCanvas
- 为什么要使用 OffscreenCanvas
- 如何使用 OffscreenCanvas
- 第一种使用方式
- 第二种使用方式
- 计算时长超过多长时间适合用Web Worker
前言
在 Canvas 开发中,我们经常需要处理复杂的图形和动画,这些操作可能会影响页面的性能和用户体验。为了解决这个问题,现代浏览器引入了 OffscreenCanvas 接口,它允许我们在后台线程(Web Workers)中进行画布操作,从而提高性能和响应速度。
为什么要使用 offscreenCanvas
OffscreenCanvas 是 HTML5 Canvas API 的扩展,它允许在独立的后台线程中执行画布操作,而不会阻塞主线程。这对于处理大型图像、复杂的绘图或者动画非常有用。
为什么要使用 OffscreenCanvas
传统的 Canvas 操作通常是在主线程中执行的,这可能会导致页面在复杂的绘图任务中出现卡顿或者延迟。使用 OffscreenCanvas 可以将这些操作移到后台线程中,这样可以避免阻塞主线程,提升整体的性能和响应速度。
如何使用 OffscreenCanvas
第一种使用方式
transferControlToOffscreen() 将控制转移到一个在主线程或者 web worker 的 OffscreenCanvas 对象上。并且在这个OffscreenCanvas上进行绘制的同时,也会在原始的canvas元素上进行绘制。
/* 主线程 */
const canvas = document.getElementById('mainCanvas')
const offscreen = canvas.transferControlToOffscreen()
const worker = new Worker('worker.js')// 将 OffscreenCanvas 传递给 Worker
worker.postMessage({ canvas: offscreen }, [offscreen])
/* worker线程 */
self.onmessage = function (event) {const offscreenCanvas = event.data.canvasconst ctx = offscreenCanvas.getContext('2d')// 绘制内容ctx.fillStyle = 'red'ctx.fillRect(50, 50, 200, 200)
}
第二种使用方式
/* 主线程 */
const canvas = document.getElementById('mainCanvas')
const ctx = canvas.getContext('2d')const worker = new Worker('./worker2.js')
worker.postMessage({ msg: 'init' })
worker.onmessage = function (e) {// 这里就接受到work 传来的离屏canvas位图ctx.drawImage(e.data.imageBitmap, 0, 0)
}ctx.arc(100, 75, 50, 0, 2 * Math.PI)
ctx.stroke()
/* worker线程 */
let offscreen, ctxfunction init() {offscreen = new OffscreenCanvas(512, 512)ctx = offscreen.getContext('2d')
}
// 绘制图形
function draw() {ctx.clearRect(0, 0, offscreen.width, offscreen.height)for (var i = 0; i < 10000; i++) {for (var j = 0; j < 1000; j++) {ctx.fillRect(i * 3, j * 3, 2, 2)}}const imageBitmap = offscreen.transferToImageBitmap()// 传送给主线程self.postMessage({ imageBitmap }, [imageBitmap])
}// 监听主线程发的信息
self.onmessage = function (e) {if (e.data.msg == 'init') {init()draw()}
}
计算时长超过多长时间适合用Web Worker
原则上,运算时间超过50ms会造成页面卡顿,属于Long task,这种情况就可以考虑使用Web Worker,但还要先考虑通信时长的问题,假如一个运算执行时长为100ms, 但是通信时长为300ms, 用了Web Worker可能会更慢。
计算的运算时长 - 通信时长 > 50ms,推荐使用Web Worker。
通信时长:新建一个web worker时, 浏览器会加载对应的worker.js资源,下图中的Time是这个 js 资源的加载时长。