当前位置: 七九推 > IT编程>开发语言>正则 > Canvaskit快速入门教程

Canvaskit快速入门教程

2023年03月17日 正则 我要评论
canvaskit快速开始canvaskit 是一个 wasm 模块,它使用 skia 去绘制画布元素,是一个比canvas api更高级的功能集。一、最小应用这个例子是一个最小的 canvaskit

canvaskit快速开始

canvaskit 是一个 wasm 模块,它使用 skia 去绘制画布元素,是一个比canvas api更高级的功能集。

一、最小应用

这个例子是一个最小的 canvaskit 应用程序,它为一帧绘制一个圆角矩形。它从 unpkg.com 中提取 wasm 二进制文件,但您也可以自己构建和托管它。

<canvas id=foo width=300 height=300></canvas>

<script type="text/javascript"
  src="https://unpkg.com/canvaskit-wasm@0.19.0/bin/canvaskit.js"></script>
<script type="text/javascript">
  
  const ckloaded = canvaskitinit({
    locatefile: (file) => 'https://unpkg.com/canvaskit-wasm@0.19.0/bin/'+file});
  	ckloaded.then((canvaskit) => {
    	const surface = canvaskit.makecanvassurface('foo');
      const paint = new canvaskit.paint();
      paint.setcolor(canvaskit.color4f(0.9, 0, 0, 1.0));
      paint.setstyle(canvaskit.paintstyle.stroke);
      paint.setantialias(true);
      const rr = canvaskit.rrectxy(canvaskit.ltrbrect(10, 60, 210, 260), 25, 15);
      function draw(canvas) {
        canvas.clear(canvaskit.white);
        canvas.drawrrect(rr, paint);
      }
      surface.drawonce(draw);
  });
</script>

二、代码解释

<canvas id=foo width=300 height=300></canvas>

创建 canvaskit 将绘制到的画布。这个元素是我们控制绘图缓冲区的宽度和高度的地方,而它的 css 样式将控制在绘制到这些像素后应用的任何缩放。尽管使用了画布元素,canvaskit 并没有调用 html 画布自己的绘制方法。它使用此画布元素获取 webgl2 上下文并使用编译为 webassembly 的 c++ 代码执行大部分绘图工作,然后在每帧结束时向 gpu 发送命令。

<script type="text/javascript"
  src="https://unpkg.com/canvaskit-wasm@0.19.0/bin/canvaskit.js"></script>
const ckloaded = canvaskitinit({locatefile: (file) => 'https://unpkg.com/canvaskit-wasm@0.19.0/bin/'+file});

加载canvaskit和wasm相关的二进制文件

canvaskitinit接受一个函数参数,允许您更改它将尝试查找canvaskit.wasm的路径,该函数的返回值是一个promise,解析为加载的模块,通常将其命名为 canvaskit。

const surface = canvaskit.makecanvassurface('foo');

创建一个与上面的 html canvas 元素关联的 surface。但可以通过调用 makeswcanvassurface 来覆盖。 makecanvassurface 也是可以指定替代颜色空间或 gl 属性的地方。这个surface会硬件加速

const paint = new canvaskit.paint();
paint.setcolor(canvaskit.color4f(0.9, 0, 0, 1.0));
paint.setstyle(canvaskit.paintstyle.stroke);
paint.setantialias(true);
const rr = canvaskit.rrectxy(canvaskit.ltrbrect(10, 60, 210, 260), 25, 15);

创建绘画,描述如何在 canvaskit 中填充或描边矩形、路径、文本和其他几何图形。 rr 是一个圆角矩形,其角在 x 轴上的半径为 25像素,在 y 轴上的半径为 15 个像素。

function draw(canvas) {
  canvas.clear(canvaskit.white);
  canvas.drawrrect(rr, paint);
}

定义一个函数来绘制。函数参数需要提供一个 canvas 对象,我们可以在该对象上进行绘制调用。先清除画布再绘制圆角矩形。

我们还删除了 paint 对象。必须删除使用 new 创建的 canvaskit 对象或以 make 为前缀的方法才能释放 wasm 内存。 javascript 的 gc 不会自动处理它。 rr 只是一个数组,不是用 new 创建的,也没有指向任何 wasm 内存,所以我们不必对其调用 delete。

surface.drawonce(draw);
paint.delete()

将绘图函数交给 surface.drawonce 进行调用并刷新表面。刷新后,skia 将批处理并发送 webgl 命令,使可见的变化出现在屏幕上。此示例绘制一次并处理表面,这就是一个一个canvaskit的最小应用程序。

codesandbox.io/s/suspiciou…

三、基本绘制循环

如果我们需要每一帧都重绘到画布上怎么办?此示例像 90 年代的屏幕保护程序一样弹跳圆角矩形。

ckloaded.then((canvaskit) => {
  const surface = canvaskit.makecanvassurface('foo');

  const paint = new canvaskit.paint();
  paint.setcolor(canvaskit.color4f(0.9, 0, 0, 1.0));
  paint.setstyle(canvaskit.paintstyle.stroke);
  paint.setantialias(true);
  // const rr = canvaskit.rrectxy(canvaskit.ltrbrect(10, 60, 210, 260), 25, 15);
  const w = 100; // size of rect
  const h = 60;
  let x = 10; // initial position of top left corner.
  let y = 60;
  let dirx = 1; // box is always moving at a constant speed in one of the four diagonal directions
  let diry = 1;

  function drawframe(canvas) {
    // boundary check
    if (x < 0 || x+w > 300) {
      dirx *= -1; // reverse x direction when hitting side walls
    }
    if (y < 0 || y+h > 300) {
      diry *= -1; // reverse y direction when hitting top and bottom walls
    }
    // move
    x += dirx;
    y += diry;

    canvas.clear(canvaskit.white);
    const rr = canvaskit.rrectxy(canvaskit.ltrbrect(x, y, x+w, y+h), 25, 15);
    canvas.drawrrect(rr, paint);
    surface.requestanimationframe(drawframe);
  }
  surface.requestanimationframe(drawframe);
});

codesandbox.io/s/zen-bush-…

这里的主要区别是我们定义了一个在绘制每一帧之前要调用的函数,并将其传递给 surface.requestanimationframe(drawframe);该回调被交给画布并处理冲洗。

创建一个函数作为我们的主要绘图循环。每次要渲染一帧(浏览器通常以 60fps 为目标)时,都会调用我们的函数,我们用白色清除画布,重新绘制圆形矩形,然后调用 surface.requestanimationframe(drawframe) 注册要再次调用的函数在下一帧之前。

surface.requestanimationframe(drawframe) 结合了 window.requestanimationframe 和 surface.flush() 并且应该以相同的方式使用。如果您的应用程序只会因鼠标事件而做出可见更改,请不要在 drawframe 函数末尾调用 surface.requestanimationframe。仅在处理鼠标输入后调用它。

四、变形文本

canvaskit 通过 html canvas api 提供的最大功能之一是段落整形。要在您的应用程序中使用文本,请提供字体文件并在 canvaskit 和字体文件准备就绪后使用 promise.all 运行您的代码。

const loadfont = fetch('https://storage.googleapis.com/skia-cdn/misc/roboto-regular.ttf')
  .then((response) => response.arraybuffer());

promise.all([ckloaded, loadfont]).then(([canvaskit, robotodata]) => {
  const surface = canvaskit.makecanvassurface('foo3');
  const canvas = surface.getcanvas();
  canvas.clear(canvaskit.color4f(0.9, 0.9, 0.9, 1.0));

  const fontmgr = canvaskit.fontmgr.fromdata([robotodata]);
  const parastyle = new canvaskit.paragraphstyle({
    textstyle: {
      color: canvaskit.black,
      fontfamilies: ['roboto'],
      fontsize: 28,
    },
    textalign: canvaskit.textalign.left,
  });
  const text = 'any sufficiently entrenched technology is indistinguishable from javascript';
  const builder = canvaskit.paragraphbuilder.make(parastyle, fontmgr);
  builder.addtext(text);
  const paragraph = builder.build();
  paragraph.layout(290); // width in pixels to use when wrapping text
  canvas.drawparagraph(paragraph, 10, 10);
  surface.flush();
});

codesandbox.io/s/serene-ch…

const fontmgr = canvaskit.fontmgr.fromdata([robotodata]);

创建一个对象,该对象按名称为 canvaskit 中的各种文本工具提供字体。如果需要,您可以在此语句中加载多种字体。

const parastyle = new canvaskit.paragraphstyle({
  textstyle: {
    color: canvaskit.black,
    fontfamilies: ['roboto'],
    fontsize: 28,
  },
  textalign: canvaskit.textalign.left,
});

指定文本的样式。字体名称 roboto 将用于从字体管理器中获取它。您可以指定 (color) 或 (foregroundcolor and backgroundcolor) 以突出显示。有关 api 的完整文档,请查看 npm 包的类型/子文件夹或 skia 存储库中的 typescript 定义。

const builder = canvaskit.paragraphbuilder.make(parastyle, fontmgr);
builder.addtext(text);
const paragraph = builder.build();

接下来,我们创建一个带有样式的 paragraphbuilder,添加一些文本,并使用 build() 完成它。并且,我们可以在一个段落中使用多个 textstyles

const builder = canvaskit.paragraphbuilder.make(parastyle, fontmgr);
builder.addtext(text1);
const boldtextstyle = canvaskit.textstyle({
    color: canvaskit.black,
    fontfamilies: ['roboto'],
    fontsize: 28,
    fontstyle: {'weight': canvaskit.fontweight.bold},
})
builder.pushstyle(boldtextstyle);
builder.addtext(text2);
builder.pop();
builder.addtext(text3);
const paragraph = builder.build();

最后,我们对段落进行布局,将文本包装到特定宽度,然后将其绘制到画布上

paragraph.layout(290); // width in pixels to use when wrapping text
canvas.drawparagraph(paragraph, 10, 10); // (x, y) position of left top corner of paragraph.

以上就是canvaskit快速入门教程的详细内容,更多关于canvaskit入门教程的资料请关注七九推其它相关文章!

(0)
打赏 微信扫一扫 微信扫一扫

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2023  七九推 保留所有权利. 粤ICP备17035492号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com