Extract the core code related to Path2D, PathStrore, and isPointInPath from Skia and rewrite it with typescript
npm install skia-path2dPathBuilderPath2D,PathStroker,ProxyPath2D几个:
conitTo、ellipseArc、getBounds、computeTightBounds,contains,fromSvgPath,toSvgPath,toPath2D,toCanvas等方法。contains方法完全移植skia的,所以对图形的命中计算与浏览是一致的。
ellipseArc,conicTo,等。
ProxyPath2D是Path2D的轻量级代理,它只是存储命令和坐标,并没有生成实际的渲染路径。如:ellipse方法,Path2D会通过一系统计算用曲线近似,而ProxyPath2D则直接存储命令和坐标。如下:PathCommand<'E', [number, number, number, number, number, number, number, boolean]>
typescript
path.getBounds() // 包围盒包含曲线的控制点
path.computeTightBounds()// 不包含曲线控制点
`
命中测试
`typescript
// 判断点是否在填充区域内
path.contains(x,y,"evenodd" | "nonzero")
// 判断点是否在路径上
let newPath=stroker.stroke(path,{
strokeWidth:20,
lineJoin:'round',// 'miter'|'round'|'bevel'
lineCap:'butt',
miterLimit:10
})
newPath.contains(x,y)
`
在Canvas中使用
`typescript
import {Path2D,PathStroker,PathBuilder} from 'skia-path2d'
//
let canvas=document.createElement('canvas')
let ctx=canvas.getContext('2d')
let path2d=new Path2D()
let path2d=new Path2D('M100 100')
path2d.ellipse(100,100,50,60,0,0,Math.PI*2,false)
path2d.toCanvas(ctx)
`
在Svg中使用
`typescript
let svgCmd='M100 100A50 60 0 1 1 100 100 Z'
let path=new Path2D(svgCmd)
path.arc(100,100,100,0,Math.PI*2,false)
//or
path.ellipseArc(100,100,50,60,0,0,Math.PI*2,false)
let svgCmd=path.toSvgPath() // 返回svg path
// svg
${svgCmd} />
`
在Webgl中使用
`typescript
import {tesselate} form 'tess2'
let path=new Path2D()
path.arc(100,100,100,0,Math.PI*2,false)
let stroker=new PathStroker()
let path_builder=path.getPath()
let newPathBuild=stroker.stroke(path_builder,{
strokeWidth:20,
lineJoin:'round',// 'miter'|'round'|'bevel'
lineCap:'butt',
miterLimit:10
})
// webgl
let gl=canvas.getContext('webgl')
const res = tesselate({
windingRule: 1,
contours: newPathBuild.toPolygons(),
vertexSize: 2,
})!
// Use triangles
let vertices=[]
for (var i = 0; i < res.elements.length; i += 3) {
var a = res.elements[i], b = res.elements[i + 1], c = res.elements[i + 2];
vertices.push(res.vertices[a 2], res.vertices[a 2 + 1],)
vertices.push(res.vertices[b 2], res.vertices[b 2 + 1])
vertices.push(res.vertices[c 2], res.vertices[c 2 + 1])
}
let vertexBuffer=gl.createBuffer()
gl.bindBuffer(gl.ARRAY_BUFFER,vertexBuffer)
gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(push),gl.STATIC_DRAW)
gl.enableVertexAttribArray(0)
gl.vertexAttribPointer(0,2,this.gl.FLOAT,false,0,0)
gl.drawArrays(gl.TRIANGLES,0,push.length/2)
gl.disableVertexAttribArray(0)
``