当前位置: 首页 > news >正文

2312skia,13画布包入门

画矶包快速入门

CanvasKit是用比canvasAPI更高级功能集Skia来绘画元素到canvas中的wasm模块.

最小应用

此例是个最小Canvaskit应用,它为一帧绘画一个圆角矩形.从unpkg.com中提取wasm二进制文件,但你也可自己构建和管理它.

<canvas id=foo width=300 height=300></canvas>
<script type="text/Js"src="https://unpkg.com/canvaskit-wasm@0.19.0/bin/canvaskit.js"></script>
<script type="text/Js">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风格控制绘画到这些像素后应用的缩放.

尽管使用了canvas元素,但CanvasKit并没有调用HTMLcanvas自己的绘画方法.它使用此canvas元素,来取WebGL2环境,并用编译为WebAssemblyC++代码来绘图,然后在每帧结束时向GPU发送命令.

<script type="text/Js"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});
ckLoaded.then((CanvasKit) => {

分别加载canvaskit助手jswasm二进制文件.CanvasKitInit接受一个一般叫CanvasKita函数函数,a允许你更改它试查找canvaskit.wasm的路径,并返回一个用加载模块解析promise.

const surface = CanvasKit.MakeCanvasSurface('foo');

创建与上述HTMLcanvas元素关联的Surface.默认硬件加速,但可调用MakeSWCanvasSurface来覆盖.MakeCanvasSurface也可指定替代颜色空间或gl属性.

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对象.一个用来清理整个画布,另一个用上面的画笔绘画圆形矩形.

还删除了画笔对象.必须删除使用new或以make为前缀的方法创建的CanvasKit对象,才能释放wasm内存.JsGC不会自动处理它.
rr只是一个不是用new创建的数组,也不指向WASM内存,因此不必对它调用delete.

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

绘图函数提交调用并刷新表面surface.drawOnce.刷新后,Skia处理并批发送WebGL命令,这样,在屏幕上出现可见更改.

基本绘画循环

如果要在画布上每一帧,都重画该怎么办?此例像90年代的屏幕保护程序一样,反弹一个圆角矩形.

ckLoaded.then((CanvasKit) => {const surface = CanvasKit.MakeCanvasSurface('foo2');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; //矩形的大小const h = 60;let x = 10; //左上角的初始位置.let y = 60;let dirX = 1; //盒子总是在`四个对角线方向`之一上,按`恒定`速度移动let dirY = 1;function drawFrame(canvas) {//检查边界if (x < 0 || x+w > 300) {dirX *= -1; //撞击侧壁时反转X方向}if (y < 0 || y+h > 300) {dirY *= -1; //撞击顶壁和底壁时反转Y方向}//移动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);,传递该回调给画布,并刷新.

function drawFrame(canvas) {canvas.clear(CanvasKit.WHITE);//在此更新和绘画框架的代码surface.requestAnimationFrame(drawFrame);
}
surface.requestAnimationFrame(drawFrame);

创建函数作为主绘图循环.每次渲染一帧(浏览器一般以60fps为目标)时,都会调用该函数,用白色清理画布,重画圆角矩形,然后调用surface.requestAnimationFrame(drawFrame)注册要在下一帧再次调用的函数.

surface.requestAnimationFrame(drawFrame)window.requestAnimationFramesurface.flush()``组合在一起,并同样方法使用.

如果应用仅因鼠标事件而有可见更改,请不要在drawFrame函数末尾调用surface.requestAnimationFrame.而仅在处理鼠标输入调用它.

变形文本

CanvasKitHTMLCanvasAPI上提供的最大功能之一是变形段落.要用它,提供字体文件,并在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 Js';const builder = CanvasKit.ParagraphBuilder.Make(paraStyle, fontMgr);builder.addText(text);const paragraph = builder.build();paragraph.layout(290); //换行文本时使用的宽度(以像素为单位)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,
});

指定文本风格及字体名,机器从字体管理器中取它.可指定(color)或(foregroundColorbackgroundColor)以获得高亮.
有关API的完整文档,请查看npm包的types/子目录或Skia仓库中的ts定义.

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); //换行文本时使用的宽度(以像素为单位)
canvas.drawParagraph(paragraph, 10, 10); //段落左上角的(x,y)位置.

动画

Skia现在为从AfterEffects继承的Bodymovin插件的JSON动画提供了一个高性能,安全的本地播放器.可在包括安卓iOSSkia平台上使用.

该播放器旨在在创建当今广泛用来动画Lottie播放器的基础上,为客户提高性能,功能集和平台凝聚力.是Bodymovin格式的忠实粉丝,并在可能时为Bodymovin/Lottie贡献.

示例JSON动画

Skia的动画代码入口可在GooglesourceGitHub上找到.该代码是Skia库的一部分,但也可作为单独的包提供这里及这里.

嵌入示例

1,可在此处找到用Skottie原生播放器的示例C代码.
2,可在此处找到取灵感的安卓应用代码.
3,在此嵌入SkottieViewer应用中的示例代码.
4,可按后面说明构建ViewerSkottieAndroid应用.

相关文章:

2312skia,13画布包入门

画矶包快速入门 CanvasKit是用比canvasAPI更高级功能集的Skia来绘画元素到canvas中的wasm模块. 最小应用 此例是个最小Canvaskit应用,它为一帧绘画一个圆角矩形.从unpkg.com中提取wasm二进制文件,但你也可自己构建和管理它. <canvas idfoo width300 height300></c…...

【网络安全技术】消息认证技术

一、哈希函数 1.安全性质 1&#xff09;抗第一原像攻击&#xff08;Preimage Resistance&#xff09; 给定哈希后的值&#xff0c;很难找到哈希前的原消息。这很好理解&#xff0c;需要哈希函数具有单向性。 一个简单的例子就是密码存储系统&#xff0c;用户登录服务器需要…...

智慧安防三大信息技术:云计算、大数据及人工智能在视频监控EasyCVR中的应用

说到三大信息技术大家都很清楚&#xff0c;指的是云计算、大数据和人工智能&#xff0c;在人工智能&#xff08;AI&#xff09;快速发展的当下&#xff0c;例如常见的大数据分析、人工智能芯片生产的智能机器人等等&#xff0c;在工作、生活、教育、金融、科技、工业、农业、娱…...

接口测试基础知识

一、接口测试简介 什么是接口测试&#xff1f; 接口测试是测试系统组件间接口的一种测试&#xff0c;主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。 测试的重点&#xff1a; 检查数据的交换&#xff0c;传递和控制管理过程&#xff1b;检查系统间的相互…...

C++多线程之通过成员函数作为线程入口

说明&#xff1a; 通过类里面的函数作为线程入口&#xff0c;我个人难理解的地方在于给线程传递参数的时候&#xff0c;怎么找到Main函数。后面会做分析。 首先创建类&#xff1a;创建MyThread类&#xff0c;其中公有函数Main作为入口。这个类的传教比较简单&#xff0c;成员…...

word、excel文件转PDF(documents4j方式,简单)

1 documents4j方式 引入pom <dependency><groupId>com.documents4j</groupId><artifactId>documents4j-local</artifactId><version>1.1.12</version></dependency><dependency><groupId>com.documents4j</g…...

【Linux】:信号(三)捕捉

信号捕捉 一.sigaction1.基本使用2.sa_mask字段 二.可重入函数三.volatile四.SIGCHLD信号 承接上文 果信号的处理动作是用户自定义函数,在信号递达时就调用这个函数,这称为捕捉信号。由于信号处理函数的代码是在用户空间的,处理过程比较复杂,举例如下: 用户程序注册了SIGQUIT信…...

数据结构 / 队列 / 循环队列 / 概念

1. 定义 为充分利用向量空间&#xff0c;克服假溢出现象的方法是&#xff1a;将向量空间想象为一个首尾相接的圆环&#xff0c;并称这种向量为循环向量。存储在其中的队列称为循环队列&#xff08;Circular Queue&#xff09;。循环队列是把顺序队列首尾相连&#xff0c;把存储…...

elasticsearch 内网下如何以离线的方式上传任意的huggingFace上的NLP模型(国内闭坑指南)

es自2020年的8.x版本以来&#xff0c;就提供了机器学习的能力。我们可以使用es官方提供的工具eland&#xff0c;将hugging face上的NLP模型&#xff0c;上传到es集群中。利用es的机器学习模块&#xff0c;来运维部署管理模型。配合es的管道处理&#xff0c;来更加便捷的处理数据…...

vue中中的动画组件使用及如何在vue中使用animate.css

“< Transition >” 是一个内置组件&#xff0c;这意味着它在任意别的组件中都可以被使用&#xff0c;无需注册。它可以将进入和离开动画应用到通过默认插槽传递给它的元素或组件上。进入或离开可以由以下的条件之一触发&#xff1a; 由 v-if 所触发的切换由 v-show 所触…...

MATLAB 模型参考自适应控制 - Model Reference Adaptive Control

系列文章目录 文章目录 系列文章目录前言一、参考模型二、扰动与不确定性模型三、直接 MRAC名义模型参数更新间接 MRAC估计器模型和控制器增益参数更新学习修正参考文献 前言 模型参考自适应控制模块计算控制动作&#xff0c;使不确定的受控系统跟踪给定参考被控对象模型的行为…...

【如何用批处理文件实现自动编译Keil工程和C# Visual Studio工程】

如何用批处理文件实现自动编译Keil工程和C# Visual Studio工程 写个Bat 批处理文件&#xff0c;现自动编译Keil工程和C# Visual Studio工程。这样可以结合Python 实现复杂的操作。 编译Keil工程&#xff1a; echo off set UVC:\Keil_v5\UV4\UV4.exe set UV_PRO_PATHD:\worksp…...

大模型的实践应用11-“书生”通用大模型的搭建与模型代码详细介绍,以及快速使用方法

大家好,我是微学AI,今天给大家介绍一下大模型的实践应用11-“书生”通用大模型的搭建与模型代码详细介绍,以及快速使用方法。“书生” 通用大模型是上海人工智能实验室研制的大模型,并且已经开源了“书生浦语”大模型70亿参数的轻量级版本InternLM-7B。InternLM-7B模型主要…...

【开发PaaS】基于Postgresql的开发平台Supabase

Supadase是开源的。我们选择可扩展的开源工具&#xff0c;使其易于使用。 Supadase不是Firebase的1对1映射。虽然我们正在构建Firebase提供的许多功能&#xff0c;但我们不会以同样的方式进行&#xff1a; 我们的技术选择大不相同&#xff1b;我们使用的一切都是开源的&#…...

前端开启gzip优化页面加载速度

生成gizp的打包资源&#xff0c;可以优化页面加载速度 打包的时候开启gzip可以很大程度减少包的大小&#xff0c;页面大小可以变为原来的30%甚至更小,非常适合线上部署, 但还记得需要服务端支持 1、前端配置compression-webpack-plugin 先安装&#xff1a;npm install compres…...

用Java写一个俄罗斯方块

目录 游戏规则 小方块类&#xff1a;Cell 七种图形类&#xff1a;I、J、L、O、S、T、Z J L O S T Z 俄罗斯方块游戏主类&#xff1a;Tetris 效果展示 游戏规则 由小方块组成的不同形状的板块陆续从屏幕上方落下来&#xff0c;玩家通过调整板块的位置和方向&#xff0c;使它…...

应用于智慧金融的AI边缘计算盒子+AI算法软硬一体化方案

传统金融营业厅存在运营管理模式落后、资源投放不平衡、从业人员培训效果不达预期、客户体验割裂等普遍现象&#xff1b; 部署英码数字金融解决方案&#xff0c;将助力企业从传统金融模式快速向数字金融模式转变&#xff0c;可针对每一个客户定制个性化“一对一”服务&#xff…...

目标检测——Faster R-CNN算法解读

论文&#xff1a;Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks 作者&#xff1a;Shaoqing Ren, Kaiming He, Ross Girshick, and Jian Sun 链接&#xff1a;https://arxiv.org/abs/1506.01497 代码&#xff1a;https://github.com/rbgirsh…...

Wireshark (一)安装入门 —— 软件介绍

文章目录 Wireshark是什么&#xff1f;为什么要使用Wireshark&#xff1f;相关网络分析工具软件对比 Wireshark是什么&#xff1f; Wireshark是一种开源网络协议分析器&#xff0c;它可以捕获和分析网络中传输的数据包。 用户可以使用Wireshark来诊断网络问题、了解网络协议的…...

Web框架与Django路由层

Web框架 一 web框架 Web框架&#xff08;Web framework&#xff09;是一种开发框架&#xff0c;用来支持动态网站、网络应用和网络服务的开发。这大多数的web框架提供了一套开发和部署网站的方式&#xff0c;也为web行为提供了一套通用的方法。web框架已经实现了很多功能&…...

实战避坑:在Windows上用C++/WinRT搞定双模蓝牙(EDR+Ble)通信的完整流程

实战避坑&#xff1a;在Windows上用C/WinRT搞定双模蓝牙&#xff08;EDRBle&#xff09;通信的完整流程 蓝牙技术在现代设备中无处不在&#xff0c;但对于开发者而言&#xff0c;实现Windows桌面应用与双模蓝牙设备&#xff08;同时支持经典蓝牙EDR和低功耗蓝牙BLE&#xff09;…...

LingBot-Depth效果实测:与传感器原生深度对比的绝对误差(mm)分布图

LingBot-Depth效果实测&#xff1a;与传感器原生深度对比的绝对误差&#xff08;mm&#xff09;分布图 1. 引言&#xff1a;当深度图遇上“脑补”大师 想象一下&#xff0c;你手里有一张用深度相机拍出来的照片&#xff0c;它告诉你每个像素离相机有多远。但问题是&#xff0…...

SEO 页面优化平台如何分析竞争对手的优化情况

SEO 页面优化平台如何分析竞争对手的优化情况 在当前竞争激烈的互联网环境中&#xff0c;SEO&#xff08;搜索引擎优化&#xff09;已经成为每个网站的生存和发展的关键。而在这其中&#xff0c;SEO 页面优化平台的角色尤为重要。通过对竞争对手的优化情况进行深入分析&#x…...

Oracle日期处理进阶:除了EXTRACT,这些场景你还可以试试INTERVAL和TO_CHAR

Oracle日期处理进阶&#xff1a;解锁INTERVAL与TO_CHAR的高阶应用场景 在Oracle数据库的日常开发中&#xff0c;日期时间处理是每个开发者都无法回避的课题。当我们已经熟练掌握了EXTRACT这类基础函数后&#xff0c;往往会发现单纯提取日期部分已经无法满足复杂业务场景的需求—…...

AT命令驱动的跨平台嵌入式Web服务器框架

1. 项目概述ESP8266_AT_WebServer 是一个面向嵌入式硬件工程师的轻量级、跨平台 Web 服务框架&#xff0c;其核心设计哲学是“硬件无关性”与“协议抽象化”。它并非直接运行于 ESP8266/ESP32 芯片之上&#xff0c;而是将这些 Wi-Fi 模块降级为一个标准的 AT 命令外设&#xff…...

基于Python的可穿戴设备的人机交互设计与实现

前言随着科技的进步发展&#xff0c;人们对生活水平提高有了一定的要求&#xff0c;穿戴设备得到了一定的普及与发展&#xff0c;人与设备之间交互的快捷性和智能化成为了提高用户体验感的关键所在。 对穿戴设备与人之间的交互的需求进行调查&#xff0c;分析用户在使用过程中存…...

LAMMPS read_data命令保姆级教程:从MS建模到data文件生成的完整避坑指南

LAMMPS read_data命令全流程实战&#xff1a;从分子建模到多体系合并的进阶指南 当你在Materials Studio中精心构建的分子模型终于完成&#xff0c;准备转入LAMMPS进行分子动力学模拟时&#xff0c;是否曾被data文件的各种格式要求绊住脚步&#xff1f;作为连接建模软件与计算引…...

企业开始用 AI 后,最容易被忽略的其实是这件事!

这两年&#xff0c;越来越多企业开始尝试把 AI 用到日常办公中。从写邮件、整理纪要&#xff0c;到查询知识库、生成文档&#xff0c;AI 正在从个人工具变成企业工作的一部分。但很多企业在推进 AI 时&#xff0c;首先关注的往往是功能和效率&#xff0c;比如“能不能写”“能不…...

颠覆传统:智能网页捕获工具重新定义长截图体验

颠覆传统&#xff1a;智能网页捕获工具重新定义长截图体验 【免费下载链接】full-page-screen-capture-chrome-extension One-click full page screen captures in Google Chrome 项目地址: https://gitcode.com/gh_mirrors/fu/full-page-screen-capture-chrome-extension …...

哈工大深圳LaTeX论文模板:5分钟搞定专业学位论文排版的终极方案

哈工大深圳LaTeX论文模板&#xff1a;5分钟搞定专业学位论文排版的终极方案 【免费下载链接】hitszthesis A dissertation template for Harbin Institute of Technology, ShenZhen (HITSZ), including bachelor, master and doctor dissertations. 项目地址: https://gitcod…...