【前端冷知识】你了解Canvas的渲染上下文吗?

本文深入探讨了HTML5 Canvas的不同上下文类型,包括2D、WebGL、WebGL2及BitmapRenderer,详细解释了如何获取这些上下文以及它们各自的支持配置选项。此外,还介绍了离屏Canvas和BitmapImage在高性能渲染中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

做前端的同学应该都知道,Canvas是浏览器中很重要的一个绘图元素,使用它可以绘制2D图形或者3D图形,要绘制2D或3D图形时,需要获取不同的上下文,最常用的两个上下文是2d上下文webgl上下文

 
  

const canvas = document.querySelector('canvas');

const context = canvas.getContext('2d'); // 获取2d上下文

 
  

const canvas = document.querySelector('canvas');

const context = canvas.getContext('webgl'); // 获取webgl上下文

如上面代码所示,最常用的上下文是这两个,不过这里有些细节需要注意。

?? 首先,一个canvas对象只能获取一种类型的上下文,以第一次调用getContext获取的上下文为准。

 
  

const canvas = document.querySelector('canvas');

const context = canvas.getContext('webgl'); // 获取webgl上下文

const context2 = canvas.getContext('2d');


console.log(context); // WebGLRenderingContext

console.log(context2); // null

上面的代码,canvas对象已经获取过webgl上下文,再获取2d上下文,就会返回null。

?? getContext获取上下文有第二个参数,可以传配置项,webgl和2d上下文的配置项不同。

2d上下文可以配置的参数如下:

  • alpha: boolean值,表明canvas包含一个alpha通道. 如果设置为false, 浏览器将认为canvas背景总是不透明的, 这样可以加速绘制透明的内容和图片.

webgl上下文可配置的参数如下:

  • alpha: boolean值,表明canvas包含一个alpha缓冲区,默认true。

  • antialias: boolean值,表明是否开启抗锯齿,默认true。

  • depth: boolean值,表明绘制缓冲区包含一个深度至少为16位的缓冲区,默认true。

  • failIfMajorPerformanceCaveat: boolean值,表明在一个系统性能低的环境是否创建该上下文的,默认false。

  • powerPreference: 指示浏览器在运行WebGL上下文时使用相应的GPU电源配置。可能值如下:

    • "default":自动选择,默认值。

    • "high-performance": 高性能模式。

    • "low-power": 节能模式。

  • premultipliedAlpha: boolean值,表明排版引擎讲假设绘制缓冲区包含预混合alpha通道,默认true。

  • preserveDrawingBuffer: boolean值,如果这个值为true缓冲区将不会被清除,会保存下来,直到被清除或被使用者覆盖,默认false。

  • stencil: boolean值,表明绘制缓冲区包含一个深度至少为8位的模版缓冲区,默认false。

?? 最新的chrome中还支持一个属性 desynchronized,它可以创建低延时渲染上下文。

实际上,除了webgl和2d上下文外,canvas还支持另外两种上下文,分别是:

  • webgl2 上下文,这个上下文是一个WebGL2RenderingContext渲染对象,它与webgl上下文的区别是,webgl版本基于OpenGL ES2.0,而webgl2版本基于OpenGL ES 3.0。

  • bitmaprenderer 上下文,它创建一个ImageBitmapRenderingContext渲染对象,可以将ImageBitmap对象的内容传入canvas中。

webgl2比webgl多了一些OpenGL ES 3.0实现的强大功能,它们不但性能更好而且使用更简单。所以如果你的绘图在高级浏览器上运行,可以使用webgl2代替webgl渲染。

如果你只是想要处理图片内容,你可以创建bitmaprenderer上下文,它提供transferFromImageBitmap()方法,可以将ImageBitmap的内容传入。

 
  

function loadImage(src) {

  const image = new Image();

  return new Promise((resolve) => {

    image.onload = function() {

      resolve(image);

    }

    image.src = src;

  });

}


(async function() {

  const image = await loadImage(url);

  const bitmap = createImageBitmap(image, 0, 0, 32, 32);

  const canvas = document.querySelector('canvas');

  const context = canvas.getContext('bitmaprenderer');

  context.transferFromImageBitmap(bitmap);

  ...

}());

?? 因为bitmaprenderer是可以用于worker上下文中的,所以这是一种快速让位图数据在worker和主线程中通讯的方式。

以上是canvas的4个上下文,现在新的标准支持的canvas除了原有的canvas元素,还支持离屏canvas(OffscreenCanvas),使用这些上下文和BitmapImage能够高性能地完成很多复杂的渲染,后续我们的文章中有机会再一一讨论。

关于canvas的渲染上下文,你还有什么想法,欢迎在issue中讨论。

关于奇舞周刊

《奇舞周刊》是360公司专业前端团队「奇舞团」运营的前端技术社区。关注公众号后,直接发送链接到后台即可给我们投稿。

640?wx_fmt=png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值