Canvaskit快速入门教程

目录
  • 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)

相关推荐

  • ECharts Canvas渲染在SVG合理运用

    目录 Canvas渲染 SVG 底图 Canvas渲染 使用 Canvas 渲染器(默认)等价于:使用 SVG 渲染器 var chart = echarts.init(containerDom, null, {renderer: 'canvas'}); var chart = echarts.init(containerDom); var chart = echarts.init(containerDom, null, {renderer: 'svg'}); 在大多数浏览器侧图库中,将选择SV

  • Canvas drawImage方法实现图片压缩详解

    目录 图片压缩原理 CanvasRenderingContext2D.drawImage() HTMLCanvasElement.toDataURL() HTMLCanvasElement.toBlob() 示例 图片压缩原理 CanvasRenderingContext2D.drawImage() 方法可以从页面 DOM 元素作为图像源来根据坐标和大小重新绘制该图像. HTMLCanvasElement.toDataURL() 和 HTMLCanvasElement.toBlob() 方法支持

  • JS技巧Canvas 性能优化脏矩形渲染实例详解

    目录 正文 画布该如何更新? 脏矩形渲染原理 脏矩形渲染实现 性能测试 结尾 正文 使用 Canvas 做图形编辑器时,我们需要自己维护自己的图形树,来保存图形的信息,并定义元素之间的关系. 我们改变画布中的某个图形,去更新画布,最简单的是清空画布,然后根据图形树将所有图形再绘制一遍,这在图形较少的情况下是没什么问题的.但如果图形数量很多,那绘制起来可能就出现卡顿了. 那么,有没有什么办法来优化一下?有,脏矩形渲染. 画布该如何更新? 这里我们假设这么一个场景,画布上绘制了随机位置大量的绿球,然

  • Canvas中绘制Geojson数据示例详解

    目录 需求分析 数据处理 将经度和纬度单独拆分出来 计算缩放比例 计算偏移度 将 Coordinates 进行缩放 使用 Canvas 进行绘制 需求分析 在做地图开发的时候遇到一个需求,是在 canvas 中绘制 Geojson 数据 数据格式为 EPSG:4326 的 Polygon: 三维数组 每一项都是由经纬度组成的 第一个点和最后一个点相同,表示 Polygon 是闭合的 [ [ [109.54420471485196, 35.76192112844663], [109.5442361

  • Canvaskit快速入门教程

    目录 CanvasKit快速开始 一.最小应用 二.代码解释 三.基本绘制循环 四.变形文本 CanvasKit快速开始 CanvasKit 是一个 wasm 模块,它使用 Skia 去绘制画布元素,是一个比canvas API更高级的功能集. 一.最小应用 这个例子是一个最小的 Canvaskit 应用程序,它为一帧绘制一个圆角矩形.它从 unpkg.com 中提取 wasm 二进制文件,但您也可以自己构建和托管它. <canvas id=foo width=300 height=300>&

  • jQuery Easyui快速入门教程

    1.什么是JQuery EasyUI jQuery EasyUI是一组基于JQuery的UI插件集合,而JQueryEasyUI的目标就是帮助开发者更轻松的打造出功能丰富并且美观的UI界面.开发者不需要编写复杂的JavaScript,也不需要对css样式有深入的了解,开发者需要了解的只是一些简单的html标签. 2.学习jQuery EasyUI的条件 因为JQueryEasyUI是基于jQuery的UI库,所以,必须需要JQuery课程的基础. 3.JQuery EasyUI的特点 基于JQu

  • OpenStack云计算快速入门教程(1)之OpenStack及其构成简介

    该教程基于Ubuntu12.04版,它将帮助读者建立起一份OpenStack最小化安装.我是五岳之巅,翻译中多采用意译法,所以个别词与原版有出入,请大家谅解.我不是英语专业,我觉着搞技术最重要的就是理解,而不是四级和考研中那烦人的英译汉,所以我的目标是忠于原意.通俗表达,Over.英文原文在这里(http://docs.openstack.org/es@***/openstack-compute/starter/content/ ,请将ex@***中的@去掉,CU屏蔽的F词),下面步入正题: 第

  • ReactJs快速入门教程(精华版)

    现在最热门的前端框架有AngularJS.React.Bootstrap等.自从接触了ReactJS,ReactJs的虚拟DOM(Virtual DOM)和组件化的开发深深的吸引了我,下面来跟我一起领略ReactJs的风采吧~~ 文章有点长,耐心读完,你会有很大收获哦~   一.ReactJS简介 React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设 Instagram 的网站.做出来以后,发现这套东西

  • Yii2框架制作RESTful风格的API快速入门教程

    先给大家说下什么是REST restful REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态转移. 它首次出现在2000年Roy Fielding的博士论文中,Roy Fielding是HTTP规范的主要编写者之一. 他在论文中提到:"我这篇文章的写作目的,就是想在符合架构原理的前提下,理解和评估以网络为基础的应用软件的架构设计,得到一个功能强.性能好.适宜通信的架构.REST指的是一组架构约束条件和原则." 如

  • Vue.js快速入门教程

    像AngularJS这种前端框架可以让我们非常方便地开发出强大的单页应用,然而有时候Angular这种大型框架对于我们的项目来说过于庞大,很多功能不一定会用到.这时候我们就需要评估一下使用它的必要性了.如果我们仅仅需要在一个简单的网页里添加屈指可数的几个功能,那么用Angular就太麻烦了,必要的安装.配置.编写路由和设计控制器等等工作显得过于繁琐. 这时候我们需要一个更加轻量级的解决方案.Vue.js就是一个不错的选择.Vue.js是一个专注于视图模型(ViewModal)的框架.视图模型是U

  • Vue.js 60分钟快速入门教程

    vuejs是当下很火的一个JavaScript MVVM库,它是以数据驱动和组件化的思想构建的.相比于Angular.js,Vue.js提供了更加简洁.更易于理解的API,使得我们能够快速地上手并使用Vue.js. 如果你之前已经习惯了用jQuery操作DOM,学习Vue.js时请先抛开手动操作DOM的思维,因为Vue.js是数据驱动的,你无需手动操作DOM.它通过一些特殊的HTML语法,将DOM和数据绑定起来.一旦你创建了绑定,DOM将和数据保持同步,每当变更了数据,DOM也会相应地更新. 当

  • Java的JNI快速入门教程(推荐)

    1. JNI简介 JNI是Java Native Interface的英文缩写,意为Java本地接口. 问题来源:由于Java编写底层的应用较难实现,在一些实时性要求非常高的部分Java较难胜任(实时性要求高的地方目前还未涉及,实时性这类话题有待考究). 解决办法:Java使用JNI可以调用现有的本地库(C/C++开发任何和系统相关的程序和类库),极大地灵活Java的开发. 2. JNI快速学习教程 2.1 问题: 使用JNI写一段代码,实现string_Java_Test_helloworld

  • Jupyter notebook快速入门教程(推荐)

    本文主要介绍了Jupyter notebook快速入门教程,分享给大家,具体如下: 本篇将给大家介绍一款超级好用的工具:Jupyter notebook. 为什么要介绍这款工具呢? 如果你想使用Python学习数据分析或数据挖掘,那么它应该是你第一个应该知道并会使用的工具,它很容易上手,用起来非常方便,是个对新手非常友好的工具.而事实也证明它的确很好用,在数据挖掘平台 Kaggle 上,使用 Python 的数据爱好者绝大多数使用 jupyter notebook 来实现分析和建模的过程,因此,

  • Navicat使用快速入门教程

    学习数据库的时候,经常接触到 navicat 这个管理数据库的工具.下面介绍这个数据库管理工具的使用. 一. 连接使用 1.1 连接数据库 打开 navicat ,点击 连接 ,选择 数据库 弹出以下界面 (以MySQL为例),熟悉各部分的作用 测试是否可以连接,有以下提示,点击确定开始使用数据库 双击 或 右键 打开连接,图标变亮表示已经打开连接 1.2 操作数据库 右键 连接 ,点击 新建数据库 输入 数据库名 和 编码规则 双击 或 右键 打开数据库(灰色图标变亮表示打开) 二. 导入备份

随机推荐