2312skia,12画布包与路径包

画布包

Skia现在提供了,在Web上轻松部署图形APIWebAssembly构建,即CanvasKit.
CanvasKit提供了测试新的CanvasSVG平台API的地基,从而在Web平台上,实现快节奏开发.还可用作要求如SkiaLottie动画支持等边角特征的自定义Web应用的部署机制.

特征

1,按允许直接绘画到HTML画布的SkSurface封装的WebGL环境

2,提供Skiacanvas/paint/path/text接口的核心集,见绑定

3,绘画到硬件加速的后端

4,使用Skia模糊安全测试

下载

NPM上取CanvasKit这里.可在npm包的types/子目录中或Skia仓库中找到文档ts定义.

另见快速入门指南.

路径包.

Skia已用WebAssemblyasm.js提供其SkPath对象许多相关方法给JS客户(如Web浏览器).

特征

仍在快速开发PathKit,因此确切API可能会变化.

主要特点是:

1,API兼容性(如直接替换)与2D路径

2,可输出到SVG/Canvas/Path2D

3,公开各种路径特效.

示例代码

npm包中的example.html,可查找如何使用PathKit这里.

应用接口

该库的主要特征是SkPath对象.可从如下创建:

1,从PathKit.FromSVGString(str)路径的SVG

2,从动词和参数PathKit.FromCmds(cmds)二维数组.

3,FromPathKit.NewPath()(将为空)

4,现有带path.copy()PathKit.NewPath(path)SkPath的副本

可导出为:

1,SVG串:path.toSVGString()

2,Path2D对象:path.toPath2D()

3,直接到2D画布环境:path.toCanvas(ctx)

4,动词和参数的二维数组:path.toCmds()

创建SkPath对象后,可如下与之交互:

1,通过Path2D操作(moveTo,lineTo,rect,arc,等)

2,与使用opPathKit.MakeFromOp(p1,p2,op)其他路径组合.

如,path1.op(path2,PathKit.PathOp.INTERSECT)会设置path1path1path2重叠(相交)所表示的区域.
PathKit.MakeFromOp(path1,path2,PathKit.PathOp.INTERSECT)将同样,但按新的SkPath对象返回.

3,使用一些(修剪,破折号,描边等)特效调整.

重要提示:离开域时,必须使用path.delete()清理创建的(SkPath,SkOpBuilder等)对象,以避免泄漏WASM堆中的内存.

这包括构造器,copy()或以"make"前缀的函数.

路径包

cpp 复制代码
FromSVGString(str)

str:表示SVGPath这里的串

返回一个动作和参数SVG串相同的SkPath,如果失败,则返回null.

例:

cpp 复制代码
let path = PathKit.FromSVGString('M150 0 L75 200 L225 200 Z');
  `path`表示一个`三角形`,出域时,记得执行`path.delete()`.
cpp 复制代码
FromCmds(cmds)

cmds2D命令数组的Array<Array<Number>>,其中命令是一个动词加其参数.

返回包含列表动作和参数SkPath,如果失败,则返回null.

比多次调用.moveTo(),.lineTo()等更快.

例:

cpp 复制代码
    let cmds = [
        [PathKit.MOVE_VERB, 0, 10],
        [PathKit.LINE_VERB, 30, 40],
        [PathKit.QUAD_VERB, 20, 50, 45, 60],
    ];
    let path = PathKit.FromCmds(cmds);
    //`path`与用户完成路径相同
    //let path = PathKit.NewPath().moveTo(0, 10).lineTo(30, 40).quadTo(20, 50, 45, 60);
    //出域时,记得执行`path.delete()`

NewPath()

返回一个空的SkPath对象.

例:

cpp 复制代码
    let path = PathKit.NewPath();
    path.moveTo(0, 10)
        .lineTo(30, 40)
        .quadTo(20, 50, 45, 60);
    //也可let path = new PathKit.SkPath();

(pathToCopy)新路径

pathToCopy:要复制的SkPath路径.

返回在SkPath中传递的副本的SkPath.

例:

cpp 复制代码
    let otherPath = ...;
    let clone = PathKit.NewPath(otherPath);
    clone.simplify();
    //也可let clone = new PathKit.SkPath(otherPath);
    //或let clone = otherPath.copy();
cpp 复制代码
MakeFromOp(pathOne, pathTwo, op)

1,pathOne,SkPath路径.

2,pathTwo,SkPath路径.

3,op,PathOp要应用的运算

返回一个给定的PathOp应用至第一个和第二个路径的结果(顺序很重要)的新的SkPath.

例:

cpp 复制代码
    let pathOne = PathKit.NewPath().moveTo(0, 20).lineTo(10, 10).lineTo(20, 20).close();
    let pathTwo = PathKit.NewPath().moveTo(10, 20).lineTo(20, 10).lineTo(30, 20).close();
    let mountains = PathKit.MakeFromOp(pathOne, pathTwo, PathKit.PathOp.UNION);

用户也可执行pathOne.op(pathTwo,PathKit.PathOp.UNION);生成路径存储pathOne中,来避免分配另一个对象.

cpp 复制代码
cubicYFromX(cpx1, cpy1, cpx2, cpy2, X)

cpx1,cpy1,cpx2,cpy2:控制点的坐标数字.
X:要找相应Y坐标X坐标数字.

快速求值三次缓入/缓出曲线.按单位正方形内的参数化立方曲线定义.做出以下假设:

1,pt[0]隐式{0,0}

2,pt[3]隐式{1,1}

3,pts[1,2]单位正方形内

返回给定X坐标Y坐标.

cpp 复制代码
cubicPtFromT(cpx1, cpy1, cpx2, cpy2, T)

cpx1,cpy1,cpx2,cpy2控制点的坐标数字.
T数字,要查找相应(X,Y)坐标的T参数.

快速求值三次缓入/缓出曲线.按单位正方形内的参数化立方曲线定义.做出以下假设:

1,pt[0]隐式{0,0}

2,pt[3]隐式{1,1}

3,pts[1,2]单位正方形内

长度为2的数组返回给定T值(X,Y)坐标.

SkPath (object)

cpp 复制代码
addPath(otherPath)

otherPath,要附加到此路径的SkPath路径

给定路径添加到此路径,然后返回此路径链接.

addPath(otherPath, transform)

otherPath,要追加到此路径的SkPath路径.
transform,在追加它之前应用至otherPathSVGMatrix转换在此.

应用转换后,把给定路径添加到此路径,然后返回此路径以链接.细节,见Path2D.addPath()这里.

cpp 复制代码
addPath(otherPath, a, b, c, d, e, f)

otherPath,要追加到此路径的SkPath路径.
a,b,c,d,e,f:数字,定义附加转换前,应用至otherPath转换的SVGMatrix六个组件.

应用转换后,把给定路径添加到此路径,然后返回此路径以链接.细节,见Path2D.addPath()这里.

例:

cpp 复制代码
    let box = PathKit.NewPath().rect(0, 0, 100, 100);
    let moreBoxes = PathKit.NewPath();
    // 加未转换框(i.e. at 0, 0)
    moreBoxes.addPath(box)
    // 参数填充了一个类似如下2d矩阵:
    //     a c e
    //     b d f
    //     0 0 1
    //向右添加了300个点的框
             .addPath(box, 1, 0, 0, 1, 300, 0)
    //添加一个双向缩小50%的框.
             .addPath(box, 0.5, 0, 0, 0.5, 0, 0);
    //现在moreBoxes附加了3个路径
cpp 复制代码
addPath(otherPath, scaleX, skewX, transX, skewY, scaleY, transY, pers0, pers1, pers2)

otherPath,追加到此路径的SkPath路径.
scaleX,skewX,transX,skewY,scaleY,transY,pers0,pers1,pers2数字,仿射矩阵的九个分量,用来定义,在附加前应用至otherPath变换.

应用转换后,把给定路径添加到此路径,然后返回此路径以链接.

例:

cpp 复制代码
    let box = PathKit.NewPath().rect(0, 0, 100, 100);
    let moreBoxes = PathKit.NewPath();
    moreBoxes.addPath(box)
    // 加未转换框(i.e. at 0, 0)
    // 参数填充了一个类似如下2d矩阵:
    //     a c e
    //     b d f
    //     0 0 1
    //向右添加了300个点的框
             .addPath(box, 1, 0, 0,
                           0, 1, 300,
                           0, 0 ,1)
    //添加一个双向缩小50%的框.
             .addPath(box, 0.5, 0,   0,
                           0,   0.5, 0,
                           0,   0,   1)
    //现在moreBoxes附加了3个路径

arc(x,y,radius,startAngle,endAngle,ccw=false)
x,y:数字,圆弧中心坐标.
radius:数字,圆弧半径.
startAngle,endAngle:数字,角度起点和终点,以弧度为单位,从正x轴顺时针测量.
ccw:布尔值,可选参数,指定是否应默认在起角尾角之间用逆时针而不是默认的顺时针绘画弧.

描述的弧添加到此弧中,然后返回此弧以链接.细节,见Path2D.arc()这里.

例:

cpp 复制代码
    let path = PathKit.NewPath();
    path.moveTo(20, 120);
        .arc(20, 120, 18, 0, 1.75 * Math.PI);
        .lineTo(20, 120);
    // 路径像一个去除了1/8切片的馅饼.
cpp 复制代码
arcTo(x1, y1, x2, y2, radius)

x1,y1,x2,y2数字,定义控制点坐标.
radius数字,圆弧半径.

描述的弧添加到此弧中,(如果需要,附加一行),然后返回此弧以链接.细节Path2D.arcTo().

close()closePath()

返回到当前子路径开头,然后返回此值以链接.细节,见Path2D.closePath()这里.

computeTightBounds()

返回一个表示此路径最小和最大面积SkRect.细节,见SkPath参考.

cpp 复制代码
conicTo(x1, y1, x2, y2, w)

x1,y1,x2,y2:数字,定义控制点和终点坐标.
w:数字,圆锥的权重.

把描述的圆锥线添加到此值(如果需要,请附加一行),然后返回此行以链接.细节,见SkPath参考.

复制()/copy()

返回此路径的副本.

cpp 复制代码
cubicTo(cp1x, cp1y, cp2x, cp2y, x, y)
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)

cp1x,cp1y,cp2x,cp2y数字,定义控制点坐标.
x,y数字,定义终点坐标

把描述的立方线添加到此值(如果需要,请附加一行),然后返回此值以链接.细节,见Path2D.bezierCurveTo这里.

cpp 复制代码
dash(on, off, phase)

on,off:数字,应打开(绘画)和关闭(空白)的破折号的像素数.
phase:数字,开/关应偏移的像素数(模on+off)

对此应用虚线路径特效,然后返回此值以链接.有关视觉示例,见上面的"Dash"特效.

例:

cpp 复制代码
    let box = PathKit.NewPath().rect(0, 0, 100, 100);
    box.dash(20, 10, 3);
    //box现在是一个将绘画20像素然后停止10像素的`虚线矩形`.因为相位为3,因此`第一行`不会从(0,0)开始,而是从路径(3,0)周围的3个像素开始.
cpp 复制代码
ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, ccw=false)

x,y:数字,椭圆中心坐标.
radiusX,radiusY:数字,X和Y方向半径.
rotation:数字,该椭圆的弧度旋转.
startAngle,endAngle:数字,要绘画起始角和结束角,以正x轴弧度为单位.
ccw:布尔值,指定是否应在起角尾角之间逆时针而不是默认的顺时针绘画椭圆的可选参数.

把描述椭圆添加到,然后返回此椭圆以链接.细节,见Path2D.ellipse这里.

cpp 复制代码
equals(otherPath)

otherPath:要比较的SkPath路径.

根据此路径是否等于otherPath返回布尔值.

cpp 复制代码
getBounds()

返回表示此路径的最小和最大面积SkRect.细节,见SkPath参考.

cpp 复制代码
getFillType()

根据此路径返回FillType.默认为PathKit.FillType.WINDING,但可能会随op()simplify()更改.

客户一般需要getFillTypeString(),因为可直接传递该值SVGCanvas.

cpp 复制代码
getFillTypeString()

返回一个表示此路径fillTypeString.这些值为"nonzero""evenodd".

例:

cpp 复制代码
    let path = ...;
    let ctx = document.getElementById('canvas1').getContext('2d');
    ctx.strokeStyle = 'green';
    ctx.fill(path.toPath2D(), path.getFillTypeString());
cpp 复制代码
moveTo(x, y)

x,y:数字,笔应移动到的目标位置坐标.
移动笔(不绘画)到给定坐标,然后返回此坐标以链接.细节,见Path2D.moveTo这里.

cpp 复制代码
lineTo(x, y)

x,y:数字,笔应移动到的目标位置坐标.
绘画一条给定坐标直线,然后返回此直线以链接.细节,见Path2D.lineTo这里.

op(otherPath,操作)

otherPath:要与this路径组合的另一条SkPath路径.
operation:应用至两个路径的PathOp操作.

用给定操作与otherPath合并到此路径中,并返回此路径以链接.

例:

cpp 复制代码
    let pathOne = PathKit.NewPath().moveTo(0, 20).lineTo(10, 10).lineTo(20, 20).close();
    let pathTwo = PathKit.NewPath().moveTo(10, 20).lineTo(20, 10).lineTo(30, 20).close();
     //组合两个三角形为两座山的样子
    let mountains = pathOne.copy().op(pathOne, pathTwo, PathKit.PathOp.UNION);
 //设置`pathOne`为`pathOne`和`pathTwo`重叠的小三角形
    pathOne.op(pathOne, pathTwo, PathKit.PathOp.INTERSECT);
 //既然调用了`copy()`,记得在山上调用`delete()`.
cpp 复制代码
quadTo(cpx, cpy, x, y) or quadraticCurveTo(cpx, cpy, x, y)

cpx,cpy:数字,控制点坐标.
x,y:数字,终点坐标.

用给定坐标绘画二次贝塞尔曲线,然后返回此曲线以链接.细节,见Path2D.quadraticCurveTo这里.

cpp 复制代码
rect(x, y, w, h)

x,y:数字,矩形左上角坐标.
w,h:数字,矩形的宽高

在此基础上绘画一个矩形,然后返回此矩形以链接.细节,见Path2D.rect这里.

cpp 复制代码
setFillType(fillType)

fillType:FillType,新的fillType.

设置路径的fillType.细节,见SkPath参考.

简化(simplify)()

设置此路径为一组描述与原始路径相同区域的不重叠的等值线.有关视觉示例,见上面的"简化"特效.

cpp 复制代码
stroke(opts)

opts:包含删除的StrokeOpts选项.

给定的选项划出此路径.可用来搞各种特效.有关视觉示例,见上面的"描边","增长"和"收缩"特效.

例:

cpp 复制代码
    let box = PathKit.NewPath().rect(0, 0, 100, 100);
  //用宽度10和圆角描边路径
    let rounded = box.copy().stroke({width: 10, join: PathKit.StrokeJoin.ROUND});
    //增长特效,即在盒子周围扩展20像素
    let grow = box.copy().stroke({width: 20}).op(box, PathKit.PathOp.DIFFERENCE);
    //收缩特效,从原图像收缩,
    let simplified = box.copy().simplify(); // sometimes required for complicated paths
    //有时`复杂`路径需要它,
    let shrink = box.copy().stroke({width: 15, cap: PathKit.StrokeCap.BUTT})
               .op(simplified, PathKit.PathOp.REVERSE_DIFFERENCE);
    //记得在每个副本上调用delete()!
cpp 复制代码
toCanvas(ctx)

ctx:要在其上绘画路径的Canvas2DContext画布.

在传递的CanvasContext上绘画此路径.

例:

cpp 复制代码
    let box = PathKit.NewPath().rect(0, 0, 100, 100);
    let ctx = document.getElementById('canvas1').getContext('2d');
    ctx.strokeStyle = 'green';
    ctx.beginPath();
    box.toCanvas(ctx);
    ctx.stroke();  // 也可ctx.fill()

toCmds()

返回动作和参数二维数组.细节,见PathKit.FromCmds().

cpp 复制代码
toPath2D()

返回与此路径相同操作的Path2D对象.

例:

cpp 复制代码
    let box = PathKit.NewPath().rect(0, 0, 100, 100);
    let ctx = document.getElementById('canvas1').getContext('2d');
    ctx.strokeStyle = 'green';
    ctx.stroke(box.toPath2D());
cpp 复制代码
toSVGString()

返回表示基于此路径的SVGPath的一个String.

例:

cpp 复制代码
    let box = PathKit.NewPath().rect(0, 0, 100, 100);
    let svg = document.getElementById('svg1');
    let newPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
    newPath.setAttribute('stroke', 'green');
    newPath.setAttribute('fill', 'white');
    newPath.setAttribute('d', box.toSVGString());
    svg.appendChild(newPath);
cpp 复制代码
transform(matr)

matrS:kMatrix,即仿射变换矩阵的九个数字中的Array<Number>.

this应用指定的转换,然后返回此值以链接.

cpp 复制代码
transform(scaleX, skewX, transX, skewY, scaleY, transY, pers0, pers1, pers2)

scaleX,skewX,transX,skewY,scaleY,transY,pers0,pers1,pers2:数字,仿射变换矩阵的九个数字.

给此值应用指定的转换,然后返回此值以链接.

例:

cpp 复制代码
    let path = PathKit.NewPath().rect(0, 0, 100, 100);
    //放大路径5倍,
    path.transform([5, 0, 0,
                    0, 5, 0,
                    0, 0, 1]);
    //向右移动路径`75`像素.
    path.transform(1, 0, 75,
                   0, 1, 0,
                   0, 0, 1);
cpp 复制代码
trim(startT, stopT, isComplement=false)

startT,stopT:数字,[0,1]中,指示要绘画的路径的开始和停止"百分比"的值
isComplement:布尔值,在startTstopT之间的区域,是否应该绘画修剪部分的补码.

设置此路径原始路径子集,然后返回此路径以链接.有关视觉示例,见上面的"修剪"特效.

例:

cpp 复制代码
    let box = PathKit.NewPath().rect(0, 0, 100, 100);
    box.trim(0.25, 1.0);
    //`box`现在是像(已删除`顶部段`)`U`的3个段.
cpp 复制代码
SkOpBuilder (object)

此对象允许链接多个PathOps在一起.用

cpp 复制代码
let builder = new PathKit.SkOpBuilder();

创建一个;创建时,内部状态为"空路径".记得在构建器resolve()的结果上调用delete().

add(path,operation)

path:要与给定规则组合的SkPath路径.
operation:应用至两个路径的PathOp操作.

路径和操作数添加到生成器.

make()resolve()

根据给定路径和操作数创建并返回新的SkPath.
返回路径出域时,记得在返回路径上调用.delete().

cpp 复制代码
SkMatrix (struct)

SkMatrix,在C++结构和JS数组之间转换.带一个九元素一维数组,并转换它为3x32D仿射矩阵.

SkRect(struct)

SkRect使用以下所有值均为Number的键,在C++结构和JS对象之间转换:
fLeft:左上角的x坐标
fTop:左上角的y坐标.
fRight:右下角的x坐标
fBottom:右下角的y坐标

StrokeOpts(struct)

StrokeOpts使用以下键,在C++结构和JS对象之间转换:
width,路径线宽数.默认值1.
miter_limit,数字,斜接限制.默认为4,见SkPaint参考.
join,StrokeJoin要使用的联接.默认值为PathKit.StrokeJoin.MITER.

细节,见SkPaint参考.

cap,StrokeCap要使用的帽.默认值为PathKit.StrokeCap.BUTT.见SkPaint参考.

cpp 复制代码
PathOp (enum)

公开以下枚举值.它们是通过其.value属性区分的常量对象.

cpp 复制代码
PathKit.PathOp.DIFFERENCE
PathKit.PathOp.INTERSECT
PathKit.PathOp.REVERSE_DIFFERENCE
PathKit.PathOp.UNION
PathKit.PathOp.XOR

PathKit.MakeFromOp()SkPath.op()中使用它们.

cpp 复制代码
FillType (enum)

公开以下枚举值.它们是通过其.value属性区分的常量对象.

cpp 复制代码
PathKit.FillType.WINDING (also known as nonzero)
PathKit.FillType.EVENODD
PathKit.FillType.INVERSE_WINDING
PathKit.FillType.INVERSE_EVENODD

SkPath.getFillType()SkPath.setFillType()使用它们,但一般客户需要SkPath.getFillTypeString().

cpp 复制代码
StrokeJoin (enum)

公开以下枚举值.它们是通过其.value属性区分的常量对象.

cpp 复制代码
PathKit.StrokeJoin.MITER
PathKit.StrokeJoin.ROUND
PathKit.StrokeJoin.BEVEL

细节,见SkPaint参考.

cpp 复制代码
StrokeCap (enum)

公开以下枚举值.它们是通过其.value属性区分的常量对象.

cpp 复制代码
PathKit.StrokeCap.BUTT
PathKit.StrokeCap.ROUND
PathKit.StrokeCap.SQUARE

细节,见SkPaint参考.

常数

公开以下常量:

cpp 复制代码
PathKit.MOVE_VERB = 0
PathKit.LINE_VERB = 1
PathKit.QUAD_VERB = 2
PathKit.CONIC_VERB = 3
PathKit.CUBIC_VERB=4
PathKit.CLOSE_VERB=5

PathKit.FromCmds()需要它.

仅测试的函数

PathKit.LTRBRect(left,top,right,bottom)
left:SkRect左上角的数字x坐标.
top:SkRect左上角的数字y坐标.
right:数字,SkRect右下角的x坐标.
bottom:数字,SkRect右下角的y坐标.

返回有给定参数SkRect对象.
SkPath.dump()

打印控制台的动词参数.仅在调度/测试中可用.

相关推荐
shuai132_10 个月前
Skia最新版CMake编译
c++·gui·skia
太书红叶10 个月前
Flutter框架性泛学习系列之一、Flutter框架概述与源码获取
学习·flutter·skia·flutter源码·flutter引擎
fqbqrr1 年前
2312skia,15vulkan及技巧
skia
爱桥代码的程序媛1 年前
Flutter的专属Skia引擎解析+用法原理
android·flutter·程序员·android开发·skia
fqbqrr1 年前
2310x86版本skia的第一个示例
c++·skia