画布包
Skia
现在提供了,在Web
上轻松部署图形API
的WebAssembly
构建,即CanvasKit
.
CanvasKit
提供了测试新的Canvas
和SVG
平台API
的地基,从而在Web
平台上,实现快节奏
开发.还可用作要求如Skia
的Lottie
动画支持等边角特征
的自定义Web
应用的部署机制
.
特征
1,按允许直接绘画到HTML
画布的SkSurface
封装的WebGL
环境
2,提供Skia
的canvas/paint/path/text
接口的核心集,见绑定
3,绘画
到硬件加速的后端
4,使用Skia
的模糊
安全测试
下载
在NPM
上取CanvasKit
这里.可在npm
包的types/
子目录中或Skia
仓库中找到文档
和ts
定义.
另见快速入门指南.
路径包.
Skia
已用WebAssembly
和asm.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,与使用op
或PathKit.MakeFromOp(p1,p2,op)
的其他路径
组合.
如,path1.op(path2,PathKit.PathOp.INTERSECT)
会设置path1
为path1
和path2
重叠(相交)所表示的区域
.
PathKit.MakeFromOp(path1,path2,PathKit.PathOp.INTERSECT)
将同样,但按新的SkPath
对象返回.
3,使用一些(修剪,破折号,描边
等)特效
调整.
重要提示:离开域
时,必须使用path.delete()
清理创建的(SkPath,SkOpBuilder
等)对象,以避免泄漏WASM
堆中的内存.
这包括构造器,copy()
或以"make"
为前缀
的函数.
路径包
FromSVGString(str)
str
:表示SVGPath
这里的串
返回一个动作和参数
与SVG
串相同的SkPath
,如果失败
,则返回null
.
例:
let path = PathKit.FromSVGString('M150 0 L75 200 L225 200 Z');`path`表示一个`三角形`,出域时,记得执行`path.delete()`.
FromCmds(cmds)
cmds
为2D
命令数组的Array<Array<Number>>
,其中命令是一个动词加其参数
.
返回包含列表
中动作和参数
的SkPath
,如果失败,则返回null
.
比多次调用.moveTo()
,.lineTo()
等更快.
例:
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
对象.
例:
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
.
例:
let otherPath = ...;let clone = PathKit.NewPath(otherPath);clone.simplify();//也可let clone = new PathKit.SkPath(otherPath);//或let clone = otherPath.copy();
MakeFromOp(pathOne, pathTwo, op)
1,pathOne
,SkPath
路径.
2,pathTwo
,SkPath
路径.
3,op
,PathOp
要应用的运算
返回一个给定的PathOp
应用至第一个和第二个路径
的结果(顺序很重要
)的新的SkPath
.
例:
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
中,来避免分配
另一个对象.
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坐标
.
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)
addPath(otherPath)
otherPath
,要附加
到此路径的SkPath
路径
把给定路径
添加到此路径
,然后返回此路径
来链接
.
addPath(otherPath, transform)
otherPath
,要追加
到此路径的SkPath
路径.
transform
,在追加它之前应用至otherPath
的SVGMatrix
转换在此.
在应用
转换后,把给定路径
添加到此路径
,然后返回此路径
以链接.细节,见Path2D.addPath()
这里.
addPath(otherPath, a, b, c, d, e, f)
otherPath
,要追加到此路径的SkPath
路径.
a,b,c,d,e,f
:数字,定义附加
转换前,应用至otherPath
转换的SVGMatrix
的六个组件
.
在应用
转换后,把给定路径
添加到此路径
,然后返回此路径
以链接.细节,见Path2D.addPath()
这里.
例:
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个路径
addPath(otherPath, scaleX, skewX, transX, skewY, scaleY, transY, pers0, pers1, pers2)
otherPath
,追加到此路径的SkPath
路径.
scaleX,skewX,transX,skewY,scaleY,transY,pers0,pers1,pers2
数字,仿射矩阵
的九个分量,用来定义,在附加前应用至otherPath
的变换
.
应用转换
后,把给定路径
添加到此路径,然后返回此路径
以链接.
例:
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()
这里.
例:
let path = PathKit.NewPath();path.moveTo(20, 120);.arc(20, 120, 18, 0, 1.75 * Math.PI);.lineTo(20, 120);// 路径像一个去除了1/8切片的馅饼.
arcTo(x1, y1, x2, y2, radius)
x1,y1,x2,y2
数字,定义控制点
坐标.
radius
数字,圆弧
半径.
把描述
的弧添加到此弧
中,(如果需要,附加一行),然后返回此弧
以链接.细节Path2D.arcTo().
close()
或closePath()
返回笔
到当前子路径
开头,然后返回此值
以链接.细节,见Path2D.closePath()
这里.
computeTightBounds()
返回一个表示此路径最小和最大面积
的SkRect
.细节,见SkPath
参考.
conicTo(x1, y1, x2, y2, w)
x1,y1,x2,y2
:数字,定义控制点和终点
坐标.
w
:数字,圆锥的权重.
把描述的圆锥线
添加到此值
(如果需要,请附加一行),然后返回此行
以链接.细节,见SkPath参考.
复制()/copy()
返回此路径的副本.
cubicTo(cp1x, cp1y, cp2x, cp2y, x, y)
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
cp1x,cp1y,cp2x,cp2y
数字,定义控制点
坐标.
x,y
数字,定义终点
坐标
把描述的立方线
添加到此值(如果需要,请附加一行),然后返回此值
以链接.细节,见Path2D.bezierCurveTo
这里.
dash(on, off, phase)
on,off
:数字,应打开(绘画
)和关闭(空白
)的破折号
的像素数.
phase
:数字,开/关
应偏移的像素数(模on+off)
对此应用虚线
路径特效,然后返回此值
以链接.有关视觉示例
,见上面的"Dash"
特效.
例:
let box = PathKit.NewPath().rect(0, 0, 100, 100);box.dash(20, 10, 3);//box现在是一个将绘画20像素然后停止10像素的`虚线矩形`.因为相位为3,因此`第一行`不会从(0,0)开始,而是从路径(3,0)周围的3个像素开始.
ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, ccw=false)
x,y
:数字,椭圆中心
坐标.
radiusX,radiusY
:数字,X和Y
方向半径
.
rotation:
数字,该椭圆的弧度旋转
.
startAngle,endAngle
:数字,要绘画
的起始角和结束角
,以正x轴
的弧度
为单位.
ccw
:布尔值
,指定是否应在起角
和尾角
之间逆时针
而不是默认的顺时针
绘画椭圆的可选参数
.
把描述椭圆
添加到此
,然后返回此椭圆
以链接.细节,见Path2D.ellipse
这里.
equals(otherPath)
otherPath
:要比较的SkPath
路径.
根据此路径
是否等于otherPath
返回布尔值
.
getBounds()
返回表示此路径的最小和最大面积
的SkRect
.细节,见SkPath
参考.
getFillType()
根据此路径
返回FillType
.默认为PathKit.FillType.WINDING
,但可能会随op()
或simplify()
更改.
客户一般需要getFillTypeString()
,因为可直接传递该值
给SVG
或Canvas
.
getFillTypeString()
返回一个表示此路径fillType
的String
.这些值为"nonzero"
或"evenodd"
.
例:
let path = ...;let ctx = document.getElementById('canvas1').getContext('2d');ctx.strokeStyle = 'green';ctx.fill(path.toPath2D(), path.getFillTypeString());
moveTo(x, y)
x,y
:数字,笔应移动到的目标位置
坐标.
移动
笔(不绘画
)到给定坐标
,然后返回此坐标
以链接.细节,见Path2D.moveTo
这里.
lineTo(x, y)
x,y
:数字,笔应移动到的目标位置
坐标.
绘画
一条给定坐标
直线,然后返回此直线
以链接.细节,见Path2D.lineTo
这里.
op(otherPath,操作)
otherPath
:要与this
路径组合的另一条SkPath
路径.
operation
:应用至两个路径的PathOp
操作.
用给定操作与otherPath
合并到此路径
中,并返回此路径
以链接.
例:
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()`.
quadTo(cpx, cpy, x, y) or quadraticCurveTo(cpx, cpy, x, y)
cpx,cpy
:数字,控制点
坐标.
x,y
:数字,终点
坐标.
用给定坐标绘画
二次贝塞尔
曲线,然后返回此曲线
以链接.细节,见Path2D.quadraticCurveTo
这里.
rect(x, y, w, h)
x,y
:数字,矩形左上角
坐标.
w,h
:数字,矩形的宽高
在此基础上绘画
一个矩形,然后返回此矩形
以链接.细节,见Path2D.rect
这里.
setFillType(fillType)
fillType
:FillType
,新的fillType
.
设置路径的fillType
.细节,见SkPath
参考.
简化(simplify)()
设置此路径
为一组描述与原始路径
相同区域的不重叠的等值线
.有关视觉
示例,见上面的"简化"特效.
stroke(opts)
opts
:包含删除的StrokeOpts
选项.
用给定
的选项划出
此路径.可用来搞各种特效
.有关视觉示例,见上面的"描边","增长"和"收缩"
特效.
例:
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()!
toCanvas(ctx)
ctx
:要在其上绘画路径的Canvas2DContext
画布.
在传递的CanvasContext
上绘画此路径.
例:
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()
.
toPath2D()
返回与此路径
相同操作的Path2D
对象.
例:
let box = PathKit.NewPath().rect(0, 0, 100, 100);let ctx = document.getElementById('canvas1').getContext('2d');ctx.strokeStyle = 'green';ctx.stroke(box.toPath2D());
toSVGString()
返回表示基于此路径的SVGPath
的一个String
.
例:
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);
transform(matr)
matrS
:kMatrix
,即仿射变换
矩阵的九个数字
中的Array<Number>
.
给this
应用指定的转换
,然后返回此值
以链接.
transform(scaleX, skewX, transX, skewY, scaleY, transY, pers0, pers1, pers2)
scaleX,skewX,transX,skewY,scaleY,transY,pers0,pers1,pers2
:数字,仿射变换
矩阵的九个数字
.
给此值应用指定的转换
,然后返回此值
以链接.
例:
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);
trim(startT, stopT, isComplement=false)
startT,stopT
:数字,[0,1]
中,指示要绘画
的路径的开始和停止"百分比"
的值
isComplement
:布尔值,在startT
和stopT
之间的区域,是否应该绘画修剪部分
的补码.
设置此路径
为原始路径
的子集
,然后返回此路径
以链接.有关视觉示例,见上面的"修剪"
特效.
例:
let box = PathKit.NewPath().rect(0, 0, 100, 100);box.trim(0.25, 1.0);//`box`现在是像(已删除`顶部段`)`U`的3个段.
SkOpBuilder (object)
此对象
允许链接多个PathOps
在一起.用
let builder = new PathKit.SkOpBuilder();
创建一个;创建时,内部状态为"空路径
".记得在构建器
和resolve()
的结果上调用delete()
.
add(path,operation)
path
:要与给定规则组合的SkPath
路径.
operation
:应用至两个路径的PathOp
操作.
把路径和操作数
添加到生成器
.
make()
或resolve()
根据给定路径和操作数
创建并返回新的SkPath
.
返回路径
出域时,记得在返回
路径上调用.delete()
.
SkMatrix (struct)
SkMatrix
,在C++
结构和JS
数组之间转换.带一个九元素
一维数组,并转换它为3x3
的2D
仿射矩阵.
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
参考.
PathOp (enum)
公开以下枚举值
.它们是通过其.value
属性区分的常量对象
.
PathKit.PathOp.DIFFERENCE
PathKit.PathOp.INTERSECT
PathKit.PathOp.REVERSE_DIFFERENCE
PathKit.PathOp.UNION
PathKit.PathOp.XOR
在PathKit.MakeFromOp()
和SkPath.op()
中使用它们.
FillType (enum)
公开以下枚举值
.它们是通过其.value
属性区分的常量对象
.
PathKit.FillType.WINDING (also known as nonzero)
PathKit.FillType.EVENODD
PathKit.FillType.INVERSE_WINDING
PathKit.FillType.INVERSE_EVENODD
由SkPath.getFillType()
和SkPath.setFillType()
使用它们,但一般客户需要SkPath.getFillTypeString()
.
StrokeJoin (enum)
公开以下枚举值
.它们是通过其.value
属性区分的常量对象
.
PathKit.StrokeJoin.MITER
PathKit.StrokeJoin.ROUND
PathKit.StrokeJoin.BEVEL
细节,见SkPaint
参考.
StrokeCap (enum)
公开以下枚举值
.它们是通过其.value
属性区分的常量对象
.
PathKit.StrokeCap.BUTT
PathKit.StrokeCap.ROUND
PathKit.StrokeCap.SQUARE
细节,见SkPaint
参考.
常数
公开以下常量:
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()
打印控制台的动词
和参数
.仅在调度/测试
中可用.