这篇“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的最小应用程序。
如果我们需要每一帧都重绘到画布上怎么办?此示例像 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);
});
这里的主要区别是我们定义了一个在绘制每一帧之前要调用的函数,并将其传递给 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();
});
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快速入门实例代码分析”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注亿速云行业资讯频道。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://juejin.cn/post/7210256070300057659