Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Canvas的4个渲染上下文 #16

Open
akira-cn opened this issue Aug 15, 2019 · 1 comment
Open

Canvas的4个渲染上下文 #16

akira-cn opened this issue Aug 15, 2019 · 1 comment

Comments

@akira-cn
Copy link
Owner

做前端的同学应该都知道,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中讨论。

@HypnosNova
Copy link

还有webgpu上下文

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants