首页 > 其他分享 >Webgl 基础以及canvasKit学习

Webgl 基础以及canvasKit学习

时间:2023-10-17 09:04:02浏览次数:39  
标签:ck canvas const canvasKit Webgl 学习 paint path 绘制

一 基础概念 1. 关于canvas 、 webgl 、 skia 、canvasKit ctx.getContext('2d ' / 'webgl ' / 'webgl2'); 类型 2d 、webgl、webgl2 有什么不同? canvas2d 主要的性能问题就在于,绘制中间对象没法缓存,以及部分能力需要 CPU 计算这两点上。 而 canvaskit 在提供了类似 canvas 2d 的接口的同时,又让我们不用去操心 webGL 上的技术问题,可以说非常适合复杂的 2d 图形绘制场景了。canvasKit 还提供其他功能,比如布尔运算,文字排版(canvas 2d 中 fillText 只能绘制单行文本,不能直接换行,需要配合 计算文字长度的属性 measureText 来判断换行) 2. 关于skia 和 canvasKit 以及 wasm Skia 是一个开源 2D 图形库,它提供适用于各种硬件和软件平台的通用 API。 它作为 Google Chrome 和 ChromeOS、Android、Flutter 和许多其他产品的图形引擎。Skia 支持多语言调用, C++/C#/Java/Python/Rust/WASM 等。 程序化设计有浏览器端以及服务端的绘制需求,所以我们选择 canvaskit-wasm 这个 Skia 打包出来的供 JS 调用的 WebAssembly NPM 包,在 web 端以及 nodejs 端都能使用,这样就满足了多端的需求。 尽管使用了画布元素,CanvasKit 并没有调用 HTML 画布自己的绘制方法。它使用此画布元素获取 WebGL2 上下文并使用编译为 WebAssembly 的 C++ 代码执行大部分绘图工作,然后在每帧结束时向 GPU 发送命令 3. 其他概念 1. Surface 是什么? Surface本身的作用类似一个句柄,得到了这个句柄就可以得到其中的Canvas、原始缓冲区以及其他方面的内容,所以简单的说Surface是用来管理数据的(句柄)。 2. Canvas 中在style中设置 viewWidth,又在 width 中设置 realWidth 的意义何在? canvasKit api 1. CanvasKit.XYWHRect(x,y,width,height) 2. CanvasKit.Color(rgba) 3. CanvasKit.RRectXY(cc,rx,ry); // cc为矩形,rx,ry分别为圆角在x,y上的半径 async function init(){ // CanvasKitInit 加载 CanvasKit库的WebAssembly二进制文件,一旦CanvasKitInit函数成功地初始化了CanvasKit库,就可以使用它来创建2D和3D图形,并将它们呈现在HTML5画布元素上 // ck 是canvasKit 加载完成后实例化一个绘图对象 const ck = await CanvasKitInit({locateFile: (file) => 'https://unpkg.com/[email protected]/bin/'+file}); // 创建一个与上面的 HTML canvas 元素关联的 Surface。但可以通过调用 MakeSWCanvasSurface 来覆盖。 MakeCanvasSurface 也是可以指定替代颜色空间或 gl 属性的地方。这个Surface会硬件加速 const surface = ck.MakeCanvasSurface('foo'); // 获取画布 const canvas = surface.getCanvas(); function draw(canvas) { canvas.clear(CanvasKit.WHITE); canvas.drawRRect(rr, paint); } const paint = new CanvasKit.Paint(); paint.setColor(CanvasKit.Color4f(0.9, 0, 0, 1.0)); paint.setStyle(ck.PaintStyle.Stroke); // ck.PaintStyle.Fill 表示填充 paint.setAntiAlias(true); surface.drawOnce(draw,paint); paint.delete() } 二 canvasKit 基础 api A. CanvasKitInit 用于加载 canvaskit-wasm 文件 用于浏览器端使用,返回一个promise对象,完成后会返回一个ck对象 - 用户创建画布,画笔,绘制图形api等 B. Ck 对象中的方法 1. 创建画布 const surface = ck.MakeOnScreenGLSurface;// (DT 那边的用法) const surface = ck.MakeCanvasSurface('canvas') ; // 获取canvas 属性用于绘制图形 const canvas = surface.getCanvas(); 2. 创建画笔 Paint - paint.setColor():设置画笔颜色(类似于 strokeStyle 和 fillStyle) - paint.setAlphaf():设置透明度 - paint.setAntiAlias():抗锯齿 - paint.setBlendMode():设置混合模式 - paint.setStyle():设置画笔样式 (ck.PaintStyle.Stroke 描边 ,ck.PaintStyle.Fill 填充 ) - paint.setStrokeWidth():设置描边宽度 - paint.setColorFilter():设置颜色筛选器 - paint.setImageFilter():设置图像筛选器 - paint.setMaskFilter():设置掩码筛选器 - paint.setShader():设置着色器 const paint = new ck.Paint(); // ck.Color4f 以(1,1,1,1.0) 方式创建颜色 // ck.Color 以rgba方式创建颜色 // paint.setColor 创建 stroke 或者fill 模式的颜色 paint.setColor(ck.Color4f(0.9, 0, 0, 1.0)); // 代表是stroke 或者 fill :使用描边模式还是填充模式 // ck.PaintStyle.Stroke 描边模式; ck.PaintStyle.Fill 填充模式 paint.setStyle(ck.PaintStyle.Stroke); // 设置画笔锯齿效果,不设置的话 描边会出现锯齿 paint.setAntiAlias(true); 3. 创建路径Path - path.moveTo(x, y):从(x,y)开始绘制一个路径 - path.lineTo():将直线添加到路径 - path.arcTo():将弧线添加到路径 - path.cubicTo():添加贝塞尔曲线 - path.quadTo():添加二次贝齐尔曲线 - path.close():闭合路径 - path.addRect():添加一个矩形到路径 - path.addCircle():添加圆 - path.addOval():添加椭圆 - path.addRoundedRect():添加圆角矩形 - path.addArc():添加圆弧 - path.addPath():添加另一个路径 const path = new ck.Path(); // 通过配置 paint.setStyle(CanvasKit.PaintStyle.Stroke 描边 ,CanvasKit.PaintStyle.Fill 填充) path.moveTo(10,10); path.lineTo(100,100); path.lineTo(50,50); path.close(); 4. Shader 着色器,用于绘制渐变、噪声、平铺等效果。 - shader.MakeColor():设置着色器颜色 - shader.MakeLinearGradient():线性渐变 - shader.MakeRadialGradient():径向渐变 - shader.MakeSweepGradient():扫描渐变 - shader.MakeTwoPointConicalGradient():两点圆锥渐变 - shader.MakeFractalNoise():柏林噪声 - shader.MakeTurbulence():平铺柏林噪声 - shader.MakeBlend():组合多个着色器效果 // 绘制渐变 const { Shader, parseColorString, TileMode } = CanvasKit const shader = Shader.MakeLinearGradient( [0, 0], // 渐变开始点 [50, 50], // 渐变结束点 [ parseColorString('#ff0000'), parseColorString('#ffff00'), parseColorString('#0000ff') ], // 渐变颜色 [0, 0.5, 1], // 颜色范围比例 TileMode.Clamp, // 范围外颜色样式模式 ) paint.setShader(shader) 5. 绘制图形 - canvas.drawRect():绘制一个矩形 - canvas.drawCircle():绘制一个圆 - canvas.drawOval() : 绘制一个椭圆 - canvas.drawLine():绘制一条直线 - canvas.drawPath():绘制一条路径 - canvas.drawArc():绘制一条圆弧 - canvas.drawText():绘制文字 - canvas.drawImage(image, x,y ): 绘制图片 绘制原尺寸的图片 - canvas.drawImageRect(image,someRect,someRect,paint); 绘制指定尺寸的图片 // 绘制矩形 const rect = ck.XYWHRect(x,y,width,height); canvas.drawRect(rect,paint); // 绘制圆角矩形 const rr = ck.RRectXY(rect,radiusX,radiusY); canvas.drawRRect(rr,paint); // 绘制椭圆 const ovalRect = ck.XYWHRect(x,y,width,height); // 椭圆的外层矩形 canvas.drawOval(ovalRect,paint); // 绘制图片 const image = await ajax(src); // 注意 返回的数据需要设置 arrayBuffer 格式 -> xhr.responseType = 'arraybuffer'; // 将arraybuffer转化为 canvaskit格式图片数据 const imageData = ck.MakeImageFromEncoded(image) ?? undefined; canvas.drawImageRect(imageData,ck.XYWHRect(0,0,imageData.width(),imageData.height()), ck.XYWHRect(x,y,width,height), null); // 绘制文本 // 需要加载文本数据 const robotoData = await fetch('https://storage.googleapis.com/skia-cdn/misc/Roboto-Regular.ttf').then((response) => response.arrayBuffer(), ); const fontMgr = ck.FontMgr.FromData([robotoData]); const paraStyle = new ck.ParagraphStyle({ textStyle: { color: ck.BLACK, fontFamilies: ['Roboto'], fontSize: 28, }, textAlign: ck.TextAlign.Left, }); const text = 'c \nanvasfadsfsadfasdfasdfkit\nfasdf asdfas /n dfsdafd fz中'; const builder = ck.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); 基础概念 什么是skia? Skia 是 由c++开发的 一款性能优异的2d 图像渲染引擎。目前主要用户chrome 以及安卓的核心产品上,以及作为flutter渲染引擎,skia 能直接与GPU通信,开发者只需要理解Skia的图形概念即可开发图形界面,有了skia他们也不需要理解复杂的webgl指令。以其绝佳的性能以及跨平台的兼容性,写一套代码就能保证在安卓和ios上运行效果保持一致。 什么是 webassembly ? Wasm 是一种 使用非 javasript代码,并使其在浏览器中运行的方法。这些代码可以c、c++、rust 等,他们会被编译进你的浏览器,在cpu上以类似原生的速度运行。这些代码的形式是二进制文件,你可以直接在javasript中把它们当作模版来使用。 什么是canvaskit? Canvaskit 是一个以wasm为编译目标的图形绘制接口,它是将skia的图形绘制api导出到web平台来使用。canvaskit同样适用canvasHTML元素作为画布,但是没有使用画布的原生绘图方法,而是通过画布获取webgl2 上下文并利用 skia 绘图能力 进行绘图,并直接和GPU通信,使得性能大大提升。 Canvaskit 和 canvas的区别? Canvas 是 HTML提供元素,其绘制的中间对象没办法缓存以及绘图部分能力需要借助cpu进行计算,其性能在某些场景下并不尽人意。 Canvaskit 利用skia 通过wasm编译而成,其底层c++代码直接在cpu上运行相当于原生代码的速度,并且skia有提供数据缓存区以及直接同GPU对话,并且提供了布尔运算,文字换行等功能。非常适合比较复杂的2d图形绘制。 参考文档 1. WebGL API文档 2. Canvaskit 官方文档 3. Webassembly 文档 4. 使用 Skia 绘制 2D 图形 5. SkiaSharp Graphics in Xamarin.Forms 6. canvasKit类型文件&API解释(一)

标签:ck,canvas,const,canvasKit,Webgl,学习,paint,path,绘制
From: https://www.cnblogs.com/honkerzh/p/17768841.html

相关文章

  • java学习第一天-安装JDK,运行Hello.java
    卸载JDK删除java的安装目录删除JAVA_HOME删除path下关于java的目录cmd下输入java-version安装JDK华为云JDK下载链接,首先下载JDK下载对应版本安装JDK设置安装路径配置环境变量打开环境变量新建系统变量-->JAVA_HOME配置path变量,新建%JAVA_......
  • AI学习笔记(五)-支持向量机(SVM)
    将数据映射到高维空间,在其中找到一个最优的超平面,将不同类别的数据点分开。它可最大化边际,使得不同类别的数据点离超平面的距离最大化。......
  • boot驱动模型中的常用API--Apple的学习笔记
    一,前言之前解决ping问题的过程中,需要看uboot的代码,感觉看起来很轻松,我一直觉得代码写的小学生都能看懂的,这才是高手写的代码。面向对象设计的好,封装做的也好。虽然和qemu的Qobject设计雷同,但是我又手痒想画图了。二,学习1,uclass_find(id)根据uclassid来找uclass。在gd->uclass_roo......
  • 排列组合学习指南
    前置芝士卡特兰数性质组合数求法递推法1<=m,n<=1e3、constintN=2010,P=1e9+7;intC[N][N];//预处理voidinit(){for(inti=0;i<N;i++)C[i][0]=1;for(inti=1;i<N;i++)for(intj=1;j<=i;j++)C[i][j]=(C[i-1][j]+C[i-1][j-1])%P;}费马......
  • 10月16日学习记录
    今天上午去上了铁道技术认知,学习了铁道的相关知识,然后老师让我们亲自体验了开列车,列车调配等的相关操作,下午去上了java课,发现课上算法其实是很重要的一部分内容,我需要督促自己学习算法了,还有今天的报错和错误处理我也需要学习一下,最后是今天的课堂测试,我需要继续学习jav......
  • 图中环学习指南
    无向图求最大环长度/*时间戳+dfs->求最大环的长度(无向图)*/constintN=2e5+10;//b数组:找出每个连通块的最大环,//dfn数组:为每个节点打上时间戳,演变为一颗深度优先搜索树inttot,b[N],dfn[N];boolvis[N];vector<int>e[N];intn;voiddfs(intu,intcnt){/......
  • 今日学习:位运算&中国剩余定理
    -2^31的补码是-0.也就是10000000000000000000000000000000补码是原码取反加1x&(-x)是最低位为1的位为1,其余位为0. 中国剩余定理: m1,m2,.....,mn相互互质。x=a1(modm1)x=a2(modm2)...x=an(modmn)那么解为:记M=m1*m2*...*mn;  Mi=m1*m2....*mn/mi  ......
  • prompt提示工程/diffusion扩散模型/datawhale组队学习///day1 看直播
    今日学习来源【纯干货】提示工程(PromptEngineering)-AI编程新范式_哔哩哔哩_bilibili 抄一下评论区的课代表: -0:00......
  • ServletContext对象的学习
    一、新建了一个模块servlet-02,需要改变web.xml头部,并且改变tomcat配置,war尽量用哪个打哪个头部代码:<?xmlversion="1.0"encoding="UTF-8"?><web-appversion="4.0"xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http......
  • 2023/10/16 学习笔记
    网络层协议与解析网络层的功能: 定义了基于IP协议的逻辑地址  连接不同的媒介类型 选择数据通过网络的最佳路径IP数据包格式: 注解:版本(4) 指IP协议版本。并且通过双方使用的版本必须一致,目前我们使用的是ipv4,表示为0100十进制是4首部长度(4) IP数据包的包头长......