1cb93a386Sopenharmony_ci--- 2cb93a386Sopenharmony_cititle: 'PathKit - Geometry in the Browser' 3cb93a386Sopenharmony_cilinkTitle: 'PathKit - Geometry in the Browser' 4cb93a386Sopenharmony_ci 5cb93a386Sopenharmony_ciweight: 30 6cb93a386Sopenharmony_ci--- 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ciSkia has made its [SkPath](https://api.skia.org/classSkPath.html) object and 9cb93a386Sopenharmony_cimany related methods available to JS clients (e.g. Web Browsers) using 10cb93a386Sopenharmony_ciWebAssembly and asm.js. 11cb93a386Sopenharmony_ci 12cb93a386Sopenharmony_ci## Features 13cb93a386Sopenharmony_ci 14cb93a386Sopenharmony_ciPathKit is still under rapid development, so the exact API is subject to change. 15cb93a386Sopenharmony_ci 16cb93a386Sopenharmony_ciThe primary features are: 17cb93a386Sopenharmony_ci 18cb93a386Sopenharmony_ci- API compatibility (e.g. drop-in replacement) with 19cb93a386Sopenharmony_ci [Path2D](https://developer.mozilla.org/en-US/docs/Web/API/Path2D) 20cb93a386Sopenharmony_ci- Can output to SVG / Canvas / Path2D 21cb93a386Sopenharmony_ci- Exposes a variety of path effects: 22cb93a386Sopenharmony_ci 23cb93a386Sopenharmony_ci<style> 24cb93a386Sopenharmony_ci canvas.patheffect { 25cb93a386Sopenharmony_ci border: 1px dashed #AAA; 26cb93a386Sopenharmony_ci width: 200px; 27cb93a386Sopenharmony_ci height: 200px; 28cb93a386Sopenharmony_ci } 29cb93a386Sopenharmony_ci</style> 30cb93a386Sopenharmony_ci 31cb93a386Sopenharmony_ci<div id=effects> 32cb93a386Sopenharmony_ci <canvas class=patheffect id=canvas1 title="Plain: A drawn star with overlapping solid lines"></canvas> 33cb93a386Sopenharmony_ci <canvas class=patheffect id=canvas2 title="Dash: A drawn star with overlapping dashed lines"></canvas> 34cb93a386Sopenharmony_ci <canvas class=patheffect id=canvas3 title="Trim: A portion of a drawn star with overlapping solid lines"></canvas> 35cb93a386Sopenharmony_ci <canvas class=patheffect id=canvas4 title="Simplify: A drawn star with non-overlapping solid lines."></canvas> 36cb93a386Sopenharmony_ci <canvas class=patheffect id=canvas5 title="Stroke: A drawn star with non-overlapping solid lines stroked at various thicknesses and with square edges"></canvas> 37cb93a386Sopenharmony_ci <canvas class=patheffect id=canvas6 title="Grow: A drawn star's expanding outline"></canvas> 38cb93a386Sopenharmony_ci <canvas class=patheffect id=canvas7 title="Shrink: A solid drawn star shrunk down"></canvas> 39cb93a386Sopenharmony_ci <canvas class=patheffect id=canvasTransform title="Transform: A drawn star moved and rotated by an Affine Matrix"></canvas> 40cb93a386Sopenharmony_ci</div> 41cb93a386Sopenharmony_ci 42cb93a386Sopenharmony_ci<script type="text/javascript"> 43cb93a386Sopenharmony_ci(function() { 44cb93a386Sopenharmony_ci // Tries to load the WASM version if supported, then falls back to asmjs 45cb93a386Sopenharmony_ci let s = document.createElement('script'); 46cb93a386Sopenharmony_ci if (window.WebAssembly && typeof window.WebAssembly.compile === 'function') { 47cb93a386Sopenharmony_ci console.log('WebAssembly is supported! Using the wasm version of PathKit'); 48cb93a386Sopenharmony_ci window.__pathkit_locate_file = 'https://unpkg.com/pathkit-wasm@0.6.0/bin/'; 49cb93a386Sopenharmony_ci } else { 50cb93a386Sopenharmony_ci console.log('WebAssembly is not supported (yet) on this browser. Using the asmjs version of PathKit'); 51cb93a386Sopenharmony_ci window.__pathkit_locate_file = 'https://unpkg.com/pathkit-asmjs@0.6.0/bin/'; 52cb93a386Sopenharmony_ci } 53cb93a386Sopenharmony_ci s.src = window.__pathkit_locate_file+'pathkit.js'; 54cb93a386Sopenharmony_ci s.onload = () => { 55cb93a386Sopenharmony_ci // TODO(kjlubick) remove .ready() when we update the version served here. 56cb93a386Sopenharmony_ci try { 57cb93a386Sopenharmony_ci PathKitInit({ 58cb93a386Sopenharmony_ci locateFile: (file) => window.__pathkit_locate_file+file, 59cb93a386Sopenharmony_ci }).ready().then((PathKit) => { 60cb93a386Sopenharmony_ci // Code goes here using PathKit 61cb93a386Sopenharmony_ci PathEffectsExample(PathKit); 62cb93a386Sopenharmony_ci MatrixTransformExample(PathKit); 63cb93a386Sopenharmony_ci }); 64cb93a386Sopenharmony_ci } 65cb93a386Sopenharmony_ci catch(error) { 66cb93a386Sopenharmony_ci console.warn(error, 'falling back to image'); 67cb93a386Sopenharmony_ci document.getElementById('effects').innerHTML = '<img width=800 src="./PathKit_effects.png"/>' 68cb93a386Sopenharmony_ci } 69cb93a386Sopenharmony_ci } 70cb93a386Sopenharmony_ci 71cb93a386Sopenharmony_ci document.head.appendChild(s); 72cb93a386Sopenharmony_ci 73cb93a386Sopenharmony_ci function setCanvasSize(ctx, width, height) { 74cb93a386Sopenharmony_ci ctx.canvas.width = width; 75cb93a386Sopenharmony_ci ctx.canvas.height = height; 76cb93a386Sopenharmony_ci } 77cb93a386Sopenharmony_ci 78cb93a386Sopenharmony_ci function drawStar(path) { 79cb93a386Sopenharmony_ci let R = 115.2, C = 128.0; 80cb93a386Sopenharmony_ci path.moveTo(C + R + 22, C); 81cb93a386Sopenharmony_ci for (let i = 1; i < 8; i++) { 82cb93a386Sopenharmony_ci let a = 2.6927937 * i; 83cb93a386Sopenharmony_ci path.lineTo(C + R * Math.cos(a) + 22, C + R * Math.sin(a)); 84cb93a386Sopenharmony_ci } 85cb93a386Sopenharmony_ci path.closePath(); 86cb93a386Sopenharmony_ci return path; 87cb93a386Sopenharmony_ci } 88cb93a386Sopenharmony_ci 89cb93a386Sopenharmony_ci function PathEffectsExample(PathKit) { 90cb93a386Sopenharmony_ci let effects = [ 91cb93a386Sopenharmony_ci // no-op 92cb93a386Sopenharmony_ci (path) => path, 93cb93a386Sopenharmony_ci // dash 94cb93a386Sopenharmony_ci (path, counter) => path.dash(10, 3, counter/5), 95cb93a386Sopenharmony_ci // trim (takes optional 3rd param for returning the trimmed part 96cb93a386Sopenharmony_ci // or the complement) 97cb93a386Sopenharmony_ci (path, counter) => path.trim((counter/100) % 1, 0.8, false), 98cb93a386Sopenharmony_ci // simplify 99cb93a386Sopenharmony_ci (path) => path.simplify(), 100cb93a386Sopenharmony_ci // stroke 101cb93a386Sopenharmony_ci (path, counter) => path.stroke({ 102cb93a386Sopenharmony_ci width: 10 * (Math.sin(counter/30) + 1), 103cb93a386Sopenharmony_ci join: PathKit.StrokeJoin.BEVEL, 104cb93a386Sopenharmony_ci cap: PathKit.StrokeCap.BUTT, 105cb93a386Sopenharmony_ci miter_limit: 1, 106cb93a386Sopenharmony_ci }), 107cb93a386Sopenharmony_ci // "offset effect", that is, making a border around the shape. 108cb93a386Sopenharmony_ci (path, counter) => { 109cb93a386Sopenharmony_ci let orig = path.copy(); 110cb93a386Sopenharmony_ci path.stroke({ 111cb93a386Sopenharmony_ci width: 10 + (counter / 4) % 50, 112cb93a386Sopenharmony_ci join: PathKit.StrokeJoin.ROUND, 113cb93a386Sopenharmony_ci cap: PathKit.StrokeCap.SQUARE, 114cb93a386Sopenharmony_ci }) 115cb93a386Sopenharmony_ci .op(orig, PathKit.PathOp.DIFFERENCE); 116cb93a386Sopenharmony_ci orig.delete(); 117cb93a386Sopenharmony_ci }, 118cb93a386Sopenharmony_ci (path, counter) => { 119cb93a386Sopenharmony_ci let simplified = path.simplify().copy(); 120cb93a386Sopenharmony_ci path.stroke({ 121cb93a386Sopenharmony_ci width: 2 + (counter / 2) % 100, 122cb93a386Sopenharmony_ci join: PathKit.StrokeJoin.BEVEL, 123cb93a386Sopenharmony_ci cap: PathKit.StrokeCap.BUTT, 124cb93a386Sopenharmony_ci }) 125cb93a386Sopenharmony_ci .op(simplified, PathKit.PathOp.REVERSE_DIFFERENCE); 126cb93a386Sopenharmony_ci simplified.delete(); 127cb93a386Sopenharmony_ci } 128cb93a386Sopenharmony_ci ]; 129cb93a386Sopenharmony_ci 130cb93a386Sopenharmony_ci let names = ["(plain)", "Dash", "Trim", "Simplify", "Stroke", "Grow", "Shrink"]; 131cb93a386Sopenharmony_ci 132cb93a386Sopenharmony_ci let counter = 0; 133cb93a386Sopenharmony_ci function frame() { 134cb93a386Sopenharmony_ci counter++; 135cb93a386Sopenharmony_ci for (let i = 0; i < effects.length; i++) { 136cb93a386Sopenharmony_ci let path = PathKit.NewPath(); 137cb93a386Sopenharmony_ci drawStar(path); 138cb93a386Sopenharmony_ci 139cb93a386Sopenharmony_ci // The transforms apply directly to the path. 140cb93a386Sopenharmony_ci effects[i](path, counter); 141cb93a386Sopenharmony_ci 142cb93a386Sopenharmony_ci let ctx = document.getElementById(`canvas${i+1}`); 143cb93a386Sopenharmony_ci if (!ctx) { 144cb93a386Sopenharmony_ci return; 145cb93a386Sopenharmony_ci } else { 146cb93a386Sopenharmony_ci ctx = ctx.getContext('2d'); 147cb93a386Sopenharmony_ci } 148cb93a386Sopenharmony_ci setCanvasSize(ctx, 300, 300); 149cb93a386Sopenharmony_ci ctx.strokeStyle = '#3c597a'; 150cb93a386Sopenharmony_ci ctx.fillStyle = '#3c597a'; 151cb93a386Sopenharmony_ci if (i >=4 ) { 152cb93a386Sopenharmony_ci ctx.fill(path.toPath2D(), path.getFillTypeString()); 153cb93a386Sopenharmony_ci } else { 154cb93a386Sopenharmony_ci ctx.stroke(path.toPath2D()); 155cb93a386Sopenharmony_ci } 156cb93a386Sopenharmony_ci 157cb93a386Sopenharmony_ci ctx.font = '42px monospace'; 158cb93a386Sopenharmony_ci 159cb93a386Sopenharmony_ci let x = 150-ctx.measureText(names[i]).width/2; 160cb93a386Sopenharmony_ci ctx.strokeText(names[i], x, 290); 161cb93a386Sopenharmony_ci 162cb93a386Sopenharmony_ci path.delete(); 163cb93a386Sopenharmony_ci } 164cb93a386Sopenharmony_ci window.requestAnimationFrame(frame); 165cb93a386Sopenharmony_ci } 166cb93a386Sopenharmony_ci window.requestAnimationFrame(frame); 167cb93a386Sopenharmony_ci } 168cb93a386Sopenharmony_ci 169cb93a386Sopenharmony_ci function MatrixTransformExample(PathKit) { 170cb93a386Sopenharmony_ci // Creates an animated star that twists and moves. 171cb93a386Sopenharmony_ci let ctx = document.getElementById('canvasTransform').getContext('2d'); 172cb93a386Sopenharmony_ci setCanvasSize(ctx, 300, 300); 173cb93a386Sopenharmony_ci ctx.strokeStyle = '#3c597a'; 174cb93a386Sopenharmony_ci 175cb93a386Sopenharmony_ci let path = drawStar(PathKit.NewPath()); 176cb93a386Sopenharmony_ci // TODO(kjlubick): Perhaps expose some matrix helper functions to allow 177cb93a386Sopenharmony_ci // clients to build their own matrices like this? 178cb93a386Sopenharmony_ci // These matrices represent a 2 degree rotation and a 1% scale factor. 179cb93a386Sopenharmony_ci let scaleUp = [1.0094, -0.0352, 3.1041, 180cb93a386Sopenharmony_ci 0.0352, 1.0094, -6.4885, 181cb93a386Sopenharmony_ci 0 , 0 , 1]; 182cb93a386Sopenharmony_ci 183cb93a386Sopenharmony_ci let scaleDown = [ 0.9895, 0.0346, -2.8473, 184cb93a386Sopenharmony_ci -0.0346, 0.9895, 6.5276, 185cb93a386Sopenharmony_ci 0 , 0 , 1]; 186cb93a386Sopenharmony_ci 187cb93a386Sopenharmony_ci let i = 0; 188cb93a386Sopenharmony_ci function frame(){ 189cb93a386Sopenharmony_ci i++; 190cb93a386Sopenharmony_ci if (Math.round(i/100) % 2) { 191cb93a386Sopenharmony_ci path.transform(scaleDown); 192cb93a386Sopenharmony_ci } else { 193cb93a386Sopenharmony_ci path.transform(scaleUp); 194cb93a386Sopenharmony_ci } 195cb93a386Sopenharmony_ci 196cb93a386Sopenharmony_ci ctx.clearRect(0, 0, 300, 300); 197cb93a386Sopenharmony_ci ctx.stroke(path.toPath2D()); 198cb93a386Sopenharmony_ci 199cb93a386Sopenharmony_ci ctx.font = '42px monospace'; 200cb93a386Sopenharmony_ci let x = 150-ctx.measureText('Transform').width/2; 201cb93a386Sopenharmony_ci ctx.strokeText('Transform', x, 290); 202cb93a386Sopenharmony_ci 203cb93a386Sopenharmony_ci window.requestAnimationFrame(frame); 204cb93a386Sopenharmony_ci } 205cb93a386Sopenharmony_ci window.requestAnimationFrame(frame); 206cb93a386Sopenharmony_ci } 207cb93a386Sopenharmony_ci})(); 208cb93a386Sopenharmony_ci</script> 209cb93a386Sopenharmony_ci 210cb93a386Sopenharmony_ci## Example Code 211cb93a386Sopenharmony_ci 212cb93a386Sopenharmony_ciThe best place to look for examples on how to use PathKit would be in the 213cb93a386Sopenharmony_ci[example.html](https://github.com/google/skia/blob/main/modules/pathkit/npm-wasm/example.html#L45), 214cb93a386Sopenharmony_ciwhich comes in the npm package. 215cb93a386Sopenharmony_ci 216cb93a386Sopenharmony_ci## Download the library 217cb93a386Sopenharmony_ci 218cb93a386Sopenharmony_ciSee the the npm page for either the 219cb93a386Sopenharmony_ci[WebAssembly](https://www.npmjs.com/package/pathkit-wasm) version or the 220cb93a386Sopenharmony_ci[asm.js](https://www.npmjs.com/package/pathkit-asmjs) version for details on 221cb93a386Sopenharmony_cidownloading and getting started. 222cb93a386Sopenharmony_ci 223cb93a386Sopenharmony_ciWebAssembly has faster load times and better overall performance but is 224cb93a386Sopenharmony_cicurrently supported by Chrome, Firefox, Edge, and Safari. The asm.js version 225cb93a386Sopenharmony_cishould run anywhere JavaScript does. 226cb93a386Sopenharmony_ci 227cb93a386Sopenharmony_ci## API 228cb93a386Sopenharmony_ci 229cb93a386Sopenharmony_ciThe primary feature of the library is the `SkPath` object. It can be created: 230cb93a386Sopenharmony_ci 231cb93a386Sopenharmony_ci- From the SVG string of a path `PathKit.FromSVGString(str)` 232cb93a386Sopenharmony_ci- From a 2D array of verbs and arguments `PathKit.FromCmds(cmds)` 233cb93a386Sopenharmony_ci- From `PathKit.NewPath()` (It will be blank) 234cb93a386Sopenharmony_ci- As a copy of an existing `SkPath` with `path.copy()` or 235cb93a386Sopenharmony_ci `PathKit.NewPath(path)` 236cb93a386Sopenharmony_ci 237cb93a386Sopenharmony_ciIt can be exported as: 238cb93a386Sopenharmony_ci 239cb93a386Sopenharmony_ci- An SVG string `path.toSVGString()` 240cb93a386Sopenharmony_ci- A [Path2D](https://developer.mozilla.org/en-US/docs/Web/API/Path2D) object 241cb93a386Sopenharmony_ci `path.toPath2D()` 242cb93a386Sopenharmony_ci- Directly to a canvas 2D context `path.toCanvas(ctx)` 243cb93a386Sopenharmony_ci- A 2D array of verbs and arguments `path.toCmds()` 244cb93a386Sopenharmony_ci 245cb93a386Sopenharmony_ciOnce an SkPath object has been made, it can be interacted with in the following 246cb93a386Sopenharmony_ciways: 247cb93a386Sopenharmony_ci 248cb93a386Sopenharmony_ci- expanded by any of the Path2D operations (`moveTo`, `lineTo`, `rect`, `arc`, 249cb93a386Sopenharmony_ci etc) 250cb93a386Sopenharmony_ci- combined with other paths using `op` or `PathKit.MakeFromOp(p1, p2, op)`. For 251cb93a386Sopenharmony_ci example, `path1.op(path2, PathKit.PathOp.INTERSECT)` will set path1 to be the 252cb93a386Sopenharmony_ci area represented by where path1 and path2 overlap (intersect). 253cb93a386Sopenharmony_ci `PathKit.MakeFromOp(path1, path2, PathKit.PathOp.INTERSECT)` will do the same 254cb93a386Sopenharmony_ci but returned as a new `SkPath` object. 255cb93a386Sopenharmony_ci- adjusted with some of the effects (`trim`, `dash`, `stroke`, etc) 256cb93a386Sopenharmony_ci 257cb93a386Sopenharmony_ci**Important**: Any objects (`SkPath`, `SkOpBuilder`, etc) that are created must 258cb93a386Sopenharmony_cibe cleaned up with `path.delete()` when they leave the scope to avoid leaking 259cb93a386Sopenharmony_cithe memory in the WASM heap. This includes any of the constructors, `copy()`, or 260cb93a386Sopenharmony_ciany function prefixed with "make". 261cb93a386Sopenharmony_ci 262cb93a386Sopenharmony_ci### PathKit 263cb93a386Sopenharmony_ci 264cb93a386Sopenharmony_ci#### `FromSVGString(str)` 265cb93a386Sopenharmony_ci 266cb93a386Sopenharmony_ci**str** - `String` representing an 267cb93a386Sopenharmony_ci[SVGPath](https://www.w3schools.com/graphics/svg_path.asp) 268cb93a386Sopenharmony_ci 269cb93a386Sopenharmony_ciReturns an `SkPath` with the same verbs and arguments as the SVG string, or 270cb93a386Sopenharmony_ci`null` on a failure. 271cb93a386Sopenharmony_ci 272cb93a386Sopenharmony_ciExample: 273cb93a386Sopenharmony_ci 274cb93a386Sopenharmony_ci let path = PathKit.FromSVGString('M150 0 L75 200 L225 200 Z'); 275cb93a386Sopenharmony_ci // path represents a triangle 276cb93a386Sopenharmony_ci // don't forget to do path.delete() when it goes out of scope. 277cb93a386Sopenharmony_ci 278cb93a386Sopenharmony_ci#### `FromCmds(cmds)` 279cb93a386Sopenharmony_ci 280cb93a386Sopenharmony_ci**cmds** - `Array<Array<Number>>`, a 2D array of commands, where a command is a 281cb93a386Sopenharmony_civerb followed by its arguments. 282cb93a386Sopenharmony_ci 283cb93a386Sopenharmony_ciReturns an `SkPath` with the verbs and arguments from the list or `null` on a 284cb93a386Sopenharmony_cifailure. 285cb93a386Sopenharmony_ci 286cb93a386Sopenharmony_ciThis can be faster than calling `.moveTo()`, `.lineTo()`, etc many times. 287cb93a386Sopenharmony_ci 288cb93a386Sopenharmony_ciExample: 289cb93a386Sopenharmony_ci 290cb93a386Sopenharmony_ci let cmds = [ 291cb93a386Sopenharmony_ci [PathKit.MOVE_VERB, 0, 10], 292cb93a386Sopenharmony_ci [PathKit.LINE_VERB, 30, 40], 293cb93a386Sopenharmony_ci [PathKit.QUAD_VERB, 20, 50, 45, 60], 294cb93a386Sopenharmony_ci ]; 295cb93a386Sopenharmony_ci let path = PathKit.FromCmds(cmds); 296cb93a386Sopenharmony_ci // path is the same as if a user had done 297cb93a386Sopenharmony_ci // let path = PathKit.NewPath().moveTo(0, 10).lineTo(30, 40).quadTo(20, 50, 45, 60); 298cb93a386Sopenharmony_ci // don't forget to do path.delete() when it goes out of scope. 299cb93a386Sopenharmony_ci 300cb93a386Sopenharmony_ci#### `NewPath()` 301cb93a386Sopenharmony_ci 302cb93a386Sopenharmony_ciReturns an empty `SkPath` object. 303cb93a386Sopenharmony_ci 304cb93a386Sopenharmony_ciExample: 305cb93a386Sopenharmony_ci 306cb93a386Sopenharmony_ci let path = PathKit.NewPath(); 307cb93a386Sopenharmony_ci path.moveTo(0, 10) 308cb93a386Sopenharmony_ci .lineTo(30, 40) 309cb93a386Sopenharmony_ci .quadTo(20, 50, 45, 60); 310cb93a386Sopenharmony_ci // don't forget to do path.delete() when it goes out of scope. 311cb93a386Sopenharmony_ci // Users can also do let path = new PathKit.SkPath(); 312cb93a386Sopenharmony_ci 313cb93a386Sopenharmony_ci#### `NewPath(pathToCopy)` 314cb93a386Sopenharmony_ci 315cb93a386Sopenharmony_ci**pathToCopy** - SkPath, a path to make a copy of. 316cb93a386Sopenharmony_ci 317cb93a386Sopenharmony_ciReturns a `SkPath` that is a copy of the passed in `SkPath`. 318cb93a386Sopenharmony_ci 319cb93a386Sopenharmony_ciExample: 320cb93a386Sopenharmony_ci 321cb93a386Sopenharmony_ci let otherPath = ...; 322cb93a386Sopenharmony_ci let clone = PathKit.NewPath(otherPath); 323cb93a386Sopenharmony_ci clone.simplify(); 324cb93a386Sopenharmony_ci // don't forget to do clone.delete() when it goes out of scope. 325cb93a386Sopenharmony_ci // Users can also do let clone = new PathKit.SkPath(otherPath); 326cb93a386Sopenharmony_ci // or let clone = otherPath.copy(); 327cb93a386Sopenharmony_ci 328cb93a386Sopenharmony_ci#### `MakeFromOp(pathOne, pathTwo, op)` 329cb93a386Sopenharmony_ci 330cb93a386Sopenharmony_ci**pathOne** - `SkPath`, a path. <br> **pathTwo** - `SkPath`, a path. <br> 331cb93a386Sopenharmony_ci**op** - `PathOp`, an op to apply 332cb93a386Sopenharmony_ci 333cb93a386Sopenharmony_ciReturns a new `SkPath` that is the result of applying the given PathOp to the 334cb93a386Sopenharmony_cifirst and second path (order matters). 335cb93a386Sopenharmony_ci 336cb93a386Sopenharmony_ciExample: 337cb93a386Sopenharmony_ci 338cb93a386Sopenharmony_ci let pathOne = PathKit.NewPath().moveTo(0, 20).lineTo(10, 10).lineTo(20, 20).close(); 339cb93a386Sopenharmony_ci let pathTwo = PathKit.NewPath().moveTo(10, 20).lineTo(20, 10).lineTo(30, 20).close(); 340cb93a386Sopenharmony_ci let mountains = PathKit.MakeFromOp(pathOne, pathTwo, PathKit.PathOp.UNION); 341cb93a386Sopenharmony_ci // don't forget to do mountains.delete() when it goes out of scope. 342cb93a386Sopenharmony_ci // Users can also do pathOne.op(pathTwo, PathKit.PathOp.UNION); 343cb93a386Sopenharmony_ci // to have the resulting path be stored to pathOne and avoid allocating another object. 344cb93a386Sopenharmony_ci 345cb93a386Sopenharmony_ci#### `cubicYFromX(cpx1, cpy1, cpx2, cpy2, X)` 346cb93a386Sopenharmony_ci 347cb93a386Sopenharmony_ci**cpx1, cpy1, cpx2, cpy2** - `Number`, coordinates for control points. <br> 348cb93a386Sopenharmony_ci**X** - `Number`, The X coordinate for which to find the corresponding Y 349cb93a386Sopenharmony_cicoordinate. 350cb93a386Sopenharmony_ci 351cb93a386Sopenharmony_ciFast evaluation of a cubic ease-in / ease-out curve. This is defined as a 352cb93a386Sopenharmony_ciparametric cubic curve inside the unit square. Makes the following assumptions: 353cb93a386Sopenharmony_ci 354cb93a386Sopenharmony_ci- pt[0] is implicitly { 0, 0 } 355cb93a386Sopenharmony_ci- pt[3] is implicitly { 1, 1 } 356cb93a386Sopenharmony_ci- pts[1, 2] are inside the unit square 357cb93a386Sopenharmony_ci 358cb93a386Sopenharmony_ciThis returns the Y coordinate for the given X coordinate. 359cb93a386Sopenharmony_ci 360cb93a386Sopenharmony_ci#### `cubicPtFromT(cpx1, cpy1, cpx2, cpy2, T)` 361cb93a386Sopenharmony_ci 362cb93a386Sopenharmony_ci**cpx1, cpy1, cpx2, cpy2** - `Number`, coordinates for control points. <br> 363cb93a386Sopenharmony_ci**T** - `Number`, The T param for which to find the corresponding (X, Y) 364cb93a386Sopenharmony_cicoordinates. 365cb93a386Sopenharmony_ci 366cb93a386Sopenharmony_ciFast evaluation of a cubic ease-in / ease-out curve. This is defined as a 367cb93a386Sopenharmony_ciparametric cubic curve inside the unit square. Makes the following assumptions: 368cb93a386Sopenharmony_ci 369cb93a386Sopenharmony_ci- pt[0] is implicitly { 0, 0 } 370cb93a386Sopenharmony_ci- pt[3] is implicitly { 1, 1 } 371cb93a386Sopenharmony_ci- pts[1, 2] are inside the unit square 372cb93a386Sopenharmony_ci 373cb93a386Sopenharmony_ciThis returns the (X, Y) coordinate for the given T value as a length 2 array. 374cb93a386Sopenharmony_ci 375cb93a386Sopenharmony_ci### SkPath (object) 376cb93a386Sopenharmony_ci 377cb93a386Sopenharmony_ci#### `addPath(otherPath)` 378cb93a386Sopenharmony_ci 379cb93a386Sopenharmony_ci**otherPath** - `SkPath`, a path to append to this path 380cb93a386Sopenharmony_ci 381cb93a386Sopenharmony_ciAdds the given path to `this` and then returns `this` for chaining purposes. 382cb93a386Sopenharmony_ci 383cb93a386Sopenharmony_ci#### `addPath(otherPath, transform)` 384cb93a386Sopenharmony_ci 385cb93a386Sopenharmony_ci**otherPath** - `SkPath`, a path to append to this path. <br> **transform** - 386cb93a386Sopenharmony_ci[SVGMatrix](https://developer.mozilla.org/en-US/docs/Web/API/SVGMatrix), a 387cb93a386Sopenharmony_citransform to apply to otherPath before appending it. 388cb93a386Sopenharmony_ci 389cb93a386Sopenharmony_ciAdds the given path to `this` after applying the transform and then returns 390cb93a386Sopenharmony_ci`this` for chaining purposes. See 391cb93a386Sopenharmony_ci[Path2D.addPath()](https://developer.mozilla.org/en-US/docs/Web/API/Path2D/addPath) 392cb93a386Sopenharmony_cifor more details. 393cb93a386Sopenharmony_ci 394cb93a386Sopenharmony_ci#### `addPath(otherPath, a, b, c, d, e, f)` 395cb93a386Sopenharmony_ci 396cb93a386Sopenharmony_ci**otherPath** - `SkPath`, a path to append to this path. <br> **a, b, c, d, e, 397cb93a386Sopenharmony_cif** - `Number`, the six components of an 398cb93a386Sopenharmony_ci[SVGMatrix](https://developer.mozilla.org/en-US/docs/Web/API/SVGMatrix), which 399cb93a386Sopenharmony_cidefine the transform to apply to otherPath before appending it. 400cb93a386Sopenharmony_ci 401cb93a386Sopenharmony_ciAdds the given path to `this` after applying the transform and then returns 402cb93a386Sopenharmony_ci`this` for chaining purposes. See 403cb93a386Sopenharmony_ci[Path2D.addPath()](https://developer.mozilla.org/en-US/docs/Web/API/Path2D/addPath) 404cb93a386Sopenharmony_cifor more details. 405cb93a386Sopenharmony_ci 406cb93a386Sopenharmony_ciExample: 407cb93a386Sopenharmony_ci 408cb93a386Sopenharmony_ci let box = PathKit.NewPath().rect(0, 0, 100, 100); 409cb93a386Sopenharmony_ci let moreBoxes = PathKit.NewPath(); 410cb93a386Sopenharmony_ci // add box un-transformed (i.e. at 0, 0) 411cb93a386Sopenharmony_ci moreBoxes.addPath(box) 412cb93a386Sopenharmony_ci // the params fill out a 2d matrix like: 413cb93a386Sopenharmony_ci // a c e 414cb93a386Sopenharmony_ci // b d f 415cb93a386Sopenharmony_ci // 0 0 1 416cb93a386Sopenharmony_ci // add box 300 points to the right 417cb93a386Sopenharmony_ci .addPath(box, 1, 0, 0, 1, 300, 0) 418cb93a386Sopenharmony_ci // add a box shrunk by 50% in both directions 419cb93a386Sopenharmony_ci .addPath(box, 0.5, 0, 0, 0.5, 0, 0); 420cb93a386Sopenharmony_ci // moreBoxes now has 3 paths appended to it 421cb93a386Sopenharmony_ci 422cb93a386Sopenharmony_ci#### `addPath(otherPath, scaleX, skewX, transX, skewY, scaleY, transY, pers0, pers1, pers2)` 423cb93a386Sopenharmony_ci 424cb93a386Sopenharmony_ci**otherPath** - `SkPath`, a path to append to this path. <br> **scaleX, skewX, 425cb93a386Sopenharmony_citransX, skewY, scaleY, transY, pers0, pers1, pers2** - `Number`, the nine 426cb93a386Sopenharmony_cicomponents of an 427cb93a386Sopenharmony_ci[Affine Matrix](https://en.wikipedia.org/wiki/Transformation_matrix#Affine_transformations), 428cb93a386Sopenharmony_ciwhich define the transform to apply to otherPath before appending it. 429cb93a386Sopenharmony_ci 430cb93a386Sopenharmony_ciAdds the given path to `this` after applying the transform and then returns 431cb93a386Sopenharmony_ci`this` for chaining purposes. 432cb93a386Sopenharmony_ci 433cb93a386Sopenharmony_ciExample: 434cb93a386Sopenharmony_ci 435cb93a386Sopenharmony_ci let box = PathKit.NewPath().rect(0, 0, 100, 100); 436cb93a386Sopenharmony_ci let moreBoxes = PathKit.NewPath(); 437cb93a386Sopenharmony_ci // add box un-transformed (i.e. at 0, 0) 438cb93a386Sopenharmony_ci moreBoxes.addPath(box) 439cb93a386Sopenharmony_ci // add box 300 points to the right 440cb93a386Sopenharmony_ci .addPath(box, 1, 0, 0, 441cb93a386Sopenharmony_ci 0, 1, 300, 442cb93a386Sopenharmony_ci 0, 0 ,1) 443cb93a386Sopenharmony_ci // add a box shrunk by 50% in both directions 444cb93a386Sopenharmony_ci .addPath(box, 0.5, 0, 0, 445cb93a386Sopenharmony_ci 0, 0.5, 0, 446cb93a386Sopenharmony_ci 0, 0, 1) 447cb93a386Sopenharmony_ci // moreBoxes now has 3 paths appended to it 448cb93a386Sopenharmony_ci 449cb93a386Sopenharmony_ci#### `arc(x, y, radius, startAngle, endAngle, ccw=false)` 450cb93a386Sopenharmony_ci 451cb93a386Sopenharmony_ci**x, y** - `Number`, The coordinates of the arc's center. <br> **radius** - 452cb93a386Sopenharmony_ci`Number`, The radius of the arc. <br> **startAngle, endAngle** - `Number`, the 453cb93a386Sopenharmony_cistart and end of the angle, measured clockwise from the positive x axis and in 454cb93a386Sopenharmony_ciradians. <br> **ccw** - `Boolean`, optional argument specifying if the arc 455cb93a386Sopenharmony_cishould be drawn counter-clockwise between **startAngle** and **endAngle** 456cb93a386Sopenharmony_ciinstead of clockwise, the default. 457cb93a386Sopenharmony_ci 458cb93a386Sopenharmony_ciAdds the described arc to `this` then returns `this` for chaining purposes. See 459cb93a386Sopenharmony_ci[Path2D.arc()](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/arc) 460cb93a386Sopenharmony_cifor more details. 461cb93a386Sopenharmony_ci 462cb93a386Sopenharmony_ciExample: 463cb93a386Sopenharmony_ci 464cb93a386Sopenharmony_ci let path = PathKit.NewPath(); 465cb93a386Sopenharmony_ci path.moveTo(20, 120); 466cb93a386Sopenharmony_ci .arc(20, 120, 18, 0, 1.75 * Math.PI); 467cb93a386Sopenharmony_ci .lineTo(20, 120); 468cb93a386Sopenharmony_ci // path looks like a pie with a 1/8th slice removed. 469cb93a386Sopenharmony_ci 470cb93a386Sopenharmony_ci#### `arcTo(x1, y1, x2, y2, radius)` 471cb93a386Sopenharmony_ci 472cb93a386Sopenharmony_ci**x1, y1, x2, y2** - `Number`, The coordinates defining the control points. <br> 473cb93a386Sopenharmony_ci**radius** - `Number`, The radius of the arc. 474cb93a386Sopenharmony_ci 475cb93a386Sopenharmony_ciAdds the described arc to `this` (appending a line, if needed) then returns 476cb93a386Sopenharmony_ci`this` for chaining purposes. See 477cb93a386Sopenharmony_ci[Path2D.arcTo()](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/arcTo) 478cb93a386Sopenharmony_cifor more details. 479cb93a386Sopenharmony_ci 480cb93a386Sopenharmony_ci#### `close()` or `closePath()` 481cb93a386Sopenharmony_ci 482cb93a386Sopenharmony_ciReturns the pen to the start of the current sub-path, then returns `this` for 483cb93a386Sopenharmony_cichaining purposes. See 484cb93a386Sopenharmony_ci[Path2D.closePath()](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/closePath) 485cb93a386Sopenharmony_cifor more details. 486cb93a386Sopenharmony_ci 487cb93a386Sopenharmony_ci#### `computeTightBounds()` 488cb93a386Sopenharmony_ci 489cb93a386Sopenharmony_ciReturns an `SkRect` that represents the minimum and maximum area of `this` path. 490cb93a386Sopenharmony_ciSee 491cb93a386Sopenharmony_ci[SkPath reference](https://api.skia.org/classSkPath.html#a597c8fcc5e4750542e2688b057a14e9e) 492cb93a386Sopenharmony_cifor more details. 493cb93a386Sopenharmony_ci 494cb93a386Sopenharmony_ci#### `conicTo(x1, y1, x2, y2, w)` 495cb93a386Sopenharmony_ci 496cb93a386Sopenharmony_ci**x1, y1, x2, y2** - `Number`, The coordinates defining the control point and 497cb93a386Sopenharmony_cithe end point. <br> **w** - `Number`, The weight of the conic. 498cb93a386Sopenharmony_ci 499cb93a386Sopenharmony_ciAdds the described conic line to `this` (appending a line, if needed) then 500cb93a386Sopenharmony_cireturns `this` for chaining purposes. See 501cb93a386Sopenharmony_ci[SkPath reference](https://api.skia.org/classSkPath.html#a9edc41978765cfe9a0b16e9ecf4d276e) 502cb93a386Sopenharmony_cifor more details. 503cb93a386Sopenharmony_ci 504cb93a386Sopenharmony_ci#### `copy()` 505cb93a386Sopenharmony_ci 506cb93a386Sopenharmony_ciReturn a copy of `this` path. 507cb93a386Sopenharmony_ci 508cb93a386Sopenharmony_ci#### `cubicTo(cp1x, cp1y, cp2x, cp2y, x, y)` or `bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)` 509cb93a386Sopenharmony_ci 510cb93a386Sopenharmony_ci**cp1x, cp1y, cp2x, cp2y** - `Number`, The coordinates defining the control 511cb93a386Sopenharmony_cipoints. <br> **x,y** - `Number`, The coordinates defining the end point 512cb93a386Sopenharmony_ci 513cb93a386Sopenharmony_ciAdds the described cubic line to `this` (appending a line, if needed) then 514cb93a386Sopenharmony_cireturns `this` for chaining purposes. See 515cb93a386Sopenharmony_ci[Path2D.bezierCurveTo](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/bezierCurveTo) 516cb93a386Sopenharmony_cifor more details. 517cb93a386Sopenharmony_ci 518cb93a386Sopenharmony_ci#### `dash(on, off, phase)` 519cb93a386Sopenharmony_ci 520cb93a386Sopenharmony_ci**on, off** - `Number`, The number of pixels the dash should be on (drawn) and 521cb93a386Sopenharmony_cioff (blank). <br> **phase** - `Number`, The number of pixels the on/off should 522cb93a386Sopenharmony_cibe offset (mod **on** + **off**) 523cb93a386Sopenharmony_ci 524cb93a386Sopenharmony_ciApplies a dashed path effect to `this` then returns `this` for chaining 525cb93a386Sopenharmony_cipurposes. See the "Dash" effect above for a visual example. 526cb93a386Sopenharmony_ci 527cb93a386Sopenharmony_ciExample: 528cb93a386Sopenharmony_ci 529cb93a386Sopenharmony_ci let box = PathKit.NewPath().rect(0, 0, 100, 100); 530cb93a386Sopenharmony_ci box.dash(20, 10, 3); 531cb93a386Sopenharmony_ci // box is now a dashed rectangle that will draw for 20 pixels, then 532cb93a386Sopenharmony_ci // stop for 10 pixels. Since phase is 3, the first line won't start 533cb93a386Sopenharmony_ci // at (0, 0), but 3 pixels around the path (3, 0) 534cb93a386Sopenharmony_ci 535cb93a386Sopenharmony_ci#### `ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, ccw=false)` 536cb93a386Sopenharmony_ci 537cb93a386Sopenharmony_ci**x, y** - `Number`, The coordinates of the center of the ellipse. <br> 538cb93a386Sopenharmony_ci**radiusX, radiusY** - `Number`, The radii in the X and Y directions. <br> 539cb93a386Sopenharmony_ci**rotation** - `Number`, The rotation in radians of this ellipse. <br> 540cb93a386Sopenharmony_ci**startAngle, endAngle** - `Number`, the starting and ending angles of which to 541cb93a386Sopenharmony_cidraw, measured in radians from the positive x axis. <br> **ccw** - `Boolean`, 542cb93a386Sopenharmony_cioptional argument specifying if the ellipse should be drawn counter-clockwise 543cb93a386Sopenharmony_cibetween **startAngle** and **endAngle** instead of clockwise, the default. 544cb93a386Sopenharmony_ci 545cb93a386Sopenharmony_ciAdds the described ellipse to `this` then returns `this` for chaining purposes. 546cb93a386Sopenharmony_ciSee 547cb93a386Sopenharmony_ci[Path2D.ellipse](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/ellipse) 548cb93a386Sopenharmony_cifor more details. 549cb93a386Sopenharmony_ci 550cb93a386Sopenharmony_ci#### `equals(otherPath)` 551cb93a386Sopenharmony_ci 552cb93a386Sopenharmony_ci**otherPath** - `SkPath`, the path to compare to. 553cb93a386Sopenharmony_ci 554cb93a386Sopenharmony_ciReturns a `Boolean` value based on if `this` path is equal to **otherPath**. 555cb93a386Sopenharmony_ci 556cb93a386Sopenharmony_ci#### `getBounds()` 557cb93a386Sopenharmony_ci 558cb93a386Sopenharmony_ciReturns an `SkRect` that represents the minimum and maximum area of `this` path. 559cb93a386Sopenharmony_ciSee 560cb93a386Sopenharmony_ci[SkPath reference](https://api.skia.org/classSkPath.html#ac60188dc6075d6ebb56b5398fbba0c10) 561cb93a386Sopenharmony_cifor more details. 562cb93a386Sopenharmony_ci 563cb93a386Sopenharmony_ci#### `getFillType()` 564cb93a386Sopenharmony_ci 565cb93a386Sopenharmony_ciReturns a `FillType` based on what this path is. This defaults to 566cb93a386Sopenharmony_ci`PathKit.FillType.WINDING`, but may change with `op()` or `simplify()`. 567cb93a386Sopenharmony_ci 568cb93a386Sopenharmony_ciClients will typically want `getFillTypeString()` because that value can be 569cb93a386Sopenharmony_cipassed directly to an SVG or Canvas. 570cb93a386Sopenharmony_ci 571cb93a386Sopenharmony_ci#### `getFillTypeString()` 572cb93a386Sopenharmony_ci 573cb93a386Sopenharmony_ciReturns a `String` representing the fillType of `this` path. The values are 574cb93a386Sopenharmony_cieither "nonzero" or "evenodd". 575cb93a386Sopenharmony_ci 576cb93a386Sopenharmony_ciExample: 577cb93a386Sopenharmony_ci 578cb93a386Sopenharmony_ci let path = ...; 579cb93a386Sopenharmony_ci let ctx = document.getElementById('canvas1').getContext('2d'); 580cb93a386Sopenharmony_ci ctx.strokeStyle = 'green'; 581cb93a386Sopenharmony_ci ctx.fill(path.toPath2D(), path.getFillTypeString()); 582cb93a386Sopenharmony_ci 583cb93a386Sopenharmony_ci#### `moveTo(x, y)` 584cb93a386Sopenharmony_ci 585cb93a386Sopenharmony_ci**x, y** - `Number`, The coordinates of where the pen should be moved to. 586cb93a386Sopenharmony_ci 587cb93a386Sopenharmony_ciMoves the pen (without drawing) to the given coordinates then returns `this` for 588cb93a386Sopenharmony_cichaining purposes. See 589cb93a386Sopenharmony_ci[Path2D.moveTo](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/moveTo) 590cb93a386Sopenharmony_cifor more details. 591cb93a386Sopenharmony_ci 592cb93a386Sopenharmony_ci#### `lineTo(x, y)` 593cb93a386Sopenharmony_ci 594cb93a386Sopenharmony_ci**x, y** - `Number`, The coordinates of where the pen should be moved to. 595cb93a386Sopenharmony_ci 596cb93a386Sopenharmony_ciDraws a straight line to the given coordinates then returns `this` for chaining 597cb93a386Sopenharmony_cipurposes. See 598cb93a386Sopenharmony_ci[Path2D.lineTo](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineTo) 599cb93a386Sopenharmony_cifor more details. 600cb93a386Sopenharmony_ci 601cb93a386Sopenharmony_ci#### `op(otherPath, operation)` 602cb93a386Sopenharmony_ci 603cb93a386Sopenharmony_ci**otherPath** - `SkPath`, The other path to be combined with `this`. <br> 604cb93a386Sopenharmony_ci**operation** - `PathOp`, The operation to apply to the two paths. 605cb93a386Sopenharmony_ci 606cb93a386Sopenharmony_ciCombines otherPath into `this` path with the given operation and returns `this` 607cb93a386Sopenharmony_cifor chaining purposes. 608cb93a386Sopenharmony_ci 609cb93a386Sopenharmony_ciExample: 610cb93a386Sopenharmony_ci 611cb93a386Sopenharmony_ci let pathOne = PathKit.NewPath().moveTo(0, 20).lineTo(10, 10).lineTo(20, 20).close(); 612cb93a386Sopenharmony_ci let pathTwo = PathKit.NewPath().moveTo(10, 20).lineTo(20, 10).lineTo(30, 20).close(); 613cb93a386Sopenharmony_ci // Combine the two triangles to look like two mountains 614cb93a386Sopenharmony_ci let mountains = pathOne.copy().op(pathOne, pathTwo, PathKit.PathOp.UNION); 615cb93a386Sopenharmony_ci // set pathOne to be the small triangle where pathOne and pathTwo overlap 616cb93a386Sopenharmony_ci pathOne.op(pathOne, pathTwo, PathKit.PathOp.INTERSECT); 617cb93a386Sopenharmony_ci // since copy() was called, don't forget to call delete() on mountains. 618cb93a386Sopenharmony_ci 619cb93a386Sopenharmony_ci#### `quadTo(cpx, cpy, x, y)` or `quadraticCurveTo(cpx, cpy, x, y)` 620cb93a386Sopenharmony_ci 621cb93a386Sopenharmony_ci**cpx, cpy** - `Number`, The coordinates for the control point. <br> **x, y** - 622cb93a386Sopenharmony_ci`Number`, The coordinates for the end point. 623cb93a386Sopenharmony_ci 624cb93a386Sopenharmony_ciDraws a quadratic Bézier curve with the given coordinates then returns `this` 625cb93a386Sopenharmony_cifor chaining purposes. See 626cb93a386Sopenharmony_ci[Path2D.quadraticCurveTo](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/quadraticCurveTo) 627cb93a386Sopenharmony_cifor more details. 628cb93a386Sopenharmony_ci 629cb93a386Sopenharmony_ci#### `rect(x, y, w, h)` 630cb93a386Sopenharmony_ci 631cb93a386Sopenharmony_ci**x, y** - `Number`, The coordinates of the upper-left corner of the rectangle. 632cb93a386Sopenharmony_ci<br> **w, h** - `Number`, The width and height of the rectangle 633cb93a386Sopenharmony_ci 634cb93a386Sopenharmony_ciDraws a rectangle on `this`, then returns `this` for chaining purposes. See 635cb93a386Sopenharmony_ci[Path2D.rect](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/rect) 636cb93a386Sopenharmony_cifor more details. 637cb93a386Sopenharmony_ci 638cb93a386Sopenharmony_ci#### `setFillType(fillType)` 639cb93a386Sopenharmony_ci 640cb93a386Sopenharmony_ci**fillType** - `FillType`, the new fillType. 641cb93a386Sopenharmony_ci 642cb93a386Sopenharmony_ciSet the fillType of the path. See 643cb93a386Sopenharmony_ci[SkPath reference](https://api.skia.org/SkPathTypes_8h.html#acc5b8721019c4a4b1beb8c759baab011) 644cb93a386Sopenharmony_cifor more details. 645cb93a386Sopenharmony_ci 646cb93a386Sopenharmony_ci#### `simplify()` 647cb93a386Sopenharmony_ci 648cb93a386Sopenharmony_ciSet `this` path to a set of _non-overlapping_ contours that describe the same 649cb93a386Sopenharmony_ciarea as the original path. See the "Simplify" effect above for a visual example. 650cb93a386Sopenharmony_ci 651cb93a386Sopenharmony_ci#### `stroke(opts)` 652cb93a386Sopenharmony_ci 653cb93a386Sopenharmony_ci**opts** - `StrokeOpts`, contains the options for stroking. 654cb93a386Sopenharmony_ci 655cb93a386Sopenharmony_ciStrokes `this` path out with the given options. This can be used for a variety 656cb93a386Sopenharmony_ciof effects. See the "Stroke", "Grow", and "Shrink" effects above for visual 657cb93a386Sopenharmony_ciexamples. 658cb93a386Sopenharmony_ci 659cb93a386Sopenharmony_ciExample: 660cb93a386Sopenharmony_ci 661cb93a386Sopenharmony_ci let box = PathKit.NewPath().rect(0, 0, 100, 100); 662cb93a386Sopenharmony_ci // Stroke the path with width 10 and rounded corners 663cb93a386Sopenharmony_ci let rounded = box.copy().stroke({width: 10, join: PathKit.StrokeJoin.ROUND}); 664cb93a386Sopenharmony_ci // Grow effect, that is, a 20 pixel expansion around the box. 665cb93a386Sopenharmony_ci let grow = box.copy().stroke({width: 20}).op(box, PathKit.PathOp.DIFFERENCE); 666cb93a386Sopenharmony_ci // Shrink effect, in which we subtract away from the original 667cb93a386Sopenharmony_ci let simplified = box.copy().simplify(); // sometimes required for complicated paths 668cb93a386Sopenharmony_ci let shrink = box.copy().stroke({width: 15, cap: PathKit.StrokeCap.BUTT}) 669cb93a386Sopenharmony_ci .op(simplified, PathKit.PathOp.REVERSE_DIFFERENCE); 670cb93a386Sopenharmony_ci // Don't forget to call delete() on each of the copies! 671cb93a386Sopenharmony_ci 672cb93a386Sopenharmony_ci#### `toCanvas(ctx)` 673cb93a386Sopenharmony_ci 674cb93a386Sopenharmony_ci**ctx** - `Canvas2DContext`, Canvas on which to draw the path. 675cb93a386Sopenharmony_ci 676cb93a386Sopenharmony_ciDraws `this` path on the passed in 677cb93a386Sopenharmony_ci[Canvas Context](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D). 678cb93a386Sopenharmony_ci 679cb93a386Sopenharmony_ciExample: 680cb93a386Sopenharmony_ci 681cb93a386Sopenharmony_ci let box = PathKit.NewPath().rect(0, 0, 100, 100); 682cb93a386Sopenharmony_ci let ctx = document.getElementById('canvas1').getContext('2d'); 683cb93a386Sopenharmony_ci ctx.strokeStyle = 'green'; 684cb93a386Sopenharmony_ci ctx.beginPath(); 685cb93a386Sopenharmony_ci box.toCanvas(ctx); 686cb93a386Sopenharmony_ci ctx.stroke(); // could also ctx.fill() 687cb93a386Sopenharmony_ci 688cb93a386Sopenharmony_ci#### `toCmds()` 689cb93a386Sopenharmony_ci 690cb93a386Sopenharmony_ciReturns a 2D Array of verbs and args. See `PathKit.FromCmds()` for more details. 691cb93a386Sopenharmony_ci 692cb93a386Sopenharmony_ci#### `toPath2D()` 693cb93a386Sopenharmony_ci 694cb93a386Sopenharmony_ciReturns a [Path2D](https://developer.mozilla.org/en-US/docs/Web/API/Path2D) 695cb93a386Sopenharmony_ciobject that has the same operations as `this` path. 696cb93a386Sopenharmony_ci 697cb93a386Sopenharmony_ciExample: 698cb93a386Sopenharmony_ci 699cb93a386Sopenharmony_ci let box = PathKit.NewPath().rect(0, 0, 100, 100); 700cb93a386Sopenharmony_ci let ctx = document.getElementById('canvas1').getContext('2d'); 701cb93a386Sopenharmony_ci ctx.strokeStyle = 'green'; 702cb93a386Sopenharmony_ci ctx.stroke(box.toPath2D()); 703cb93a386Sopenharmony_ci 704cb93a386Sopenharmony_ci#### `toSVGString()` 705cb93a386Sopenharmony_ci 706cb93a386Sopenharmony_ciReturns a `String` representing an 707cb93a386Sopenharmony_ci[SVGPath](https://www.w3schools.com/graphics/svg_path.asp) based on `this` path. 708cb93a386Sopenharmony_ci 709cb93a386Sopenharmony_ciExample: 710cb93a386Sopenharmony_ci 711cb93a386Sopenharmony_ci let box = PathKit.NewPath().rect(0, 0, 100, 100); 712cb93a386Sopenharmony_ci let svg = document.getElementById('svg1'); 713cb93a386Sopenharmony_ci let newPath = document.createElementNS('http://www.w3.org/2000/svg', 'path'); 714cb93a386Sopenharmony_ci newPath.setAttribute('stroke', 'green'); 715cb93a386Sopenharmony_ci newPath.setAttribute('fill', 'white'); 716cb93a386Sopenharmony_ci newPath.setAttribute('d', box.toSVGString()); 717cb93a386Sopenharmony_ci svg.appendChild(newPath); 718cb93a386Sopenharmony_ci 719cb93a386Sopenharmony_ci#### `transform(matr)` 720cb93a386Sopenharmony_ci 721cb93a386Sopenharmony_ci**matr** - `SkMatrix`, i.e. an `Array<Number>` of the nine numbers of an Affine 722cb93a386Sopenharmony_ciTransform Matrix. 723cb93a386Sopenharmony_ci 724cb93a386Sopenharmony_ciApplies the specified 725cb93a386Sopenharmony_ci[transform](https://en.wikipedia.org/wiki/Transformation_matrix#Affine_transformations) 726cb93a386Sopenharmony_cito `this` and then returns `this` for chaining purposes. 727cb93a386Sopenharmony_ci 728cb93a386Sopenharmony_ci#### `transform(scaleX, skewX, transX, skewY, scaleY, transY, pers0, pers1, pers2)` 729cb93a386Sopenharmony_ci 730cb93a386Sopenharmony_ci**scaleX, skewX, transX, skewY, scaleY, transY, pers0, pers1, pers2** - 731cb93a386Sopenharmony_ci`Number`, the nine numbers of an Affine Transform Matrix. 732cb93a386Sopenharmony_ci 733cb93a386Sopenharmony_ciApplies the specified 734cb93a386Sopenharmony_ci[transform](https://en.wikipedia.org/wiki/Transformation_matrix#Affine_transformations) 735cb93a386Sopenharmony_cito `this` and then returns `this` for chaining purposes. 736cb93a386Sopenharmony_ci 737cb93a386Sopenharmony_ciExample: 738cb93a386Sopenharmony_ci 739cb93a386Sopenharmony_ci let path = PathKit.NewPath().rect(0, 0, 100, 100); 740cb93a386Sopenharmony_ci // scale up the path by 5x 741cb93a386Sopenharmony_ci path.transform([5, 0, 0, 742cb93a386Sopenharmony_ci 0, 5, 0, 743cb93a386Sopenharmony_ci 0, 0, 1]); 744cb93a386Sopenharmony_ci // move the path 75 px to the right. 745cb93a386Sopenharmony_ci path.transform(1, 0, 75, 746cb93a386Sopenharmony_ci 0, 1, 0, 747cb93a386Sopenharmony_ci 0, 0, 1); 748cb93a386Sopenharmony_ci 749cb93a386Sopenharmony_ci#### `trim(startT, stopT, isComplement=false)` 750cb93a386Sopenharmony_ci 751cb93a386Sopenharmony_ci**startT, stopT** - `Number`, values in [0, 1] that indicate the start and stop 752cb93a386Sopenharmony_ci"percentages" of the path to draw <br> **isComplement** - `Boolean`, If the 753cb93a386Sopenharmony_cicomplement of the trimmed section should be drawn instead of the areas between 754cb93a386Sopenharmony_ci**startT** and **stopT**. 755cb93a386Sopenharmony_ci 756cb93a386Sopenharmony_ciSets `this` path to be a subset of the original path, then returns `this` for 757cb93a386Sopenharmony_cichaining purposes. See the "Trim" effect above for a visual example. 758cb93a386Sopenharmony_ci 759cb93a386Sopenharmony_ciExample: 760cb93a386Sopenharmony_ci 761cb93a386Sopenharmony_ci let box = PathKit.NewPath().rect(0, 0, 100, 100); 762cb93a386Sopenharmony_ci box.trim(0.25, 1.0); 763cb93a386Sopenharmony_ci // box is now the 3 segments that look like a U 764cb93a386Sopenharmony_ci // (the top segment has been removed). 765cb93a386Sopenharmony_ci 766cb93a386Sopenharmony_ci### SkOpBuilder (object) 767cb93a386Sopenharmony_ci 768cb93a386Sopenharmony_ciThis object enables chaining multiple PathOps together. Create one with 769cb93a386Sopenharmony_ci`let builder = new PathKit.SkOpBuilder();` When created, the internal state is 770cb93a386Sopenharmony_ci"empty path". Don't forget to call `delete()` on both the builder and the result 771cb93a386Sopenharmony_ciof `resolve()` 772cb93a386Sopenharmony_ci 773cb93a386Sopenharmony_ci#### `add(path, operation)` 774cb93a386Sopenharmony_ci 775cb93a386Sopenharmony_ci**path** - `SkPath`, The path to be combined with the given rule. <br> 776cb93a386Sopenharmony_ci**operation** - `PathOp`, The operation to apply to the two paths. 777cb93a386Sopenharmony_ci 778cb93a386Sopenharmony_ciAdds a path and the operand to the builder. 779cb93a386Sopenharmony_ci 780cb93a386Sopenharmony_ci#### `make()` or `resolve()` 781cb93a386Sopenharmony_ci 782cb93a386Sopenharmony_ciCreates and returns a new `SkPath` based on all the given paths and operands. 783cb93a386Sopenharmony_ci 784cb93a386Sopenharmony_ciDon't forget to call `.delete()` on the returned path when it goes out of scope. 785cb93a386Sopenharmony_ci 786cb93a386Sopenharmony_ci### SkMatrix (struct) 787cb93a386Sopenharmony_ci 788cb93a386Sopenharmony_ci`SkMatrix` translates between a C++ struct and a JS Array. It basically takes a 789cb93a386Sopenharmony_cinine element 1D Array and turns it into a 3x3 2D Affine Matrix. 790cb93a386Sopenharmony_ci 791cb93a386Sopenharmony_ci### SkRect (struct) 792cb93a386Sopenharmony_ci 793cb93a386Sopenharmony_ci`SkRect` translates between a C++ struct and a JS Object with the following keys 794cb93a386Sopenharmony_ci(all values are `Number`: 795cb93a386Sopenharmony_ci 796cb93a386Sopenharmony_ci- **fLeft**: x coordinate of top-left corner 797cb93a386Sopenharmony_ci- **fTop**: y coordinate of top-left corner 798cb93a386Sopenharmony_ci- **fRight**: x coordinate of bottom-right corner 799cb93a386Sopenharmony_ci- **fBottom**: y coordinate of bottom-rightcorner 800cb93a386Sopenharmony_ci 801cb93a386Sopenharmony_ci### StrokeOpts (struct) 802cb93a386Sopenharmony_ci 803cb93a386Sopenharmony_ci`StrokeOpts` translates between a C++ struct and a JS Object with the following 804cb93a386Sopenharmony_cikeys: 805cb93a386Sopenharmony_ci 806cb93a386Sopenharmony_ci- **width**, `Number` the width of the lines of the path. Default 1. 807cb93a386Sopenharmony_ci- **miter_limit**, `Number`, the miter limit. Defautl 4. See 808cb93a386Sopenharmony_ci [SkPaint reference](https://api.skia.org/classSkPaint.html#a2e767abfeb7795ed251a08b5ed85033f) 809cb93a386Sopenharmony_ci for more details. 810cb93a386Sopenharmony_ci- **join**, `StrokeJoin`, the join to use. Default `PathKit.StrokeJoin.MITER`. 811cb93a386Sopenharmony_ci See 812cb93a386Sopenharmony_ci [SkPaint reference](https://api.skia.org/classSkPaint.html#ac582b0cbf59909c9056de34a6b977cca) 813cb93a386Sopenharmony_ci for more details. 814cb93a386Sopenharmony_ci- **cap**, `StrokeCap`, the cap to use. Default `PathKit.StrokeCap.BUTT`. See 815cb93a386Sopenharmony_ci [SkPaint reference](https://api.skia.org/classSkPaint.html#a0f78de8559b795defba93171f6cb6333) 816cb93a386Sopenharmony_ci for more details. 817cb93a386Sopenharmony_ci 818cb93a386Sopenharmony_ci### PathOp (enum) 819cb93a386Sopenharmony_ci 820cb93a386Sopenharmony_ciThe following enum values are exposed. They are essentially constant objects, 821cb93a386Sopenharmony_cidifferentiated by their `.value` property. 822cb93a386Sopenharmony_ci 823cb93a386Sopenharmony_ci- `PathKit.PathOp.DIFFERENCE` 824cb93a386Sopenharmony_ci- `PathKit.PathOp.INTERSECT` 825cb93a386Sopenharmony_ci- `PathKit.PathOp.REVERSE_DIFFERENCE` 826cb93a386Sopenharmony_ci- `PathKit.PathOp.UNION` 827cb93a386Sopenharmony_ci- `PathKit.PathOp.XOR` 828cb93a386Sopenharmony_ci 829cb93a386Sopenharmony_ciThese are used in `PathKit.MakeFromOp()` and `SkPath.op()`. 830cb93a386Sopenharmony_ci 831cb93a386Sopenharmony_ci### FillType (enum) 832cb93a386Sopenharmony_ci 833cb93a386Sopenharmony_ciThe following enum values are exposed. They are essentially constant objects, 834cb93a386Sopenharmony_cidifferentiated by their `.value` property. 835cb93a386Sopenharmony_ci 836cb93a386Sopenharmony_ci- `PathKit.FillType.WINDING` (also known as nonzero) 837cb93a386Sopenharmony_ci- `PathKit.FillType.EVENODD` 838cb93a386Sopenharmony_ci- `PathKit.FillType.INVERSE_WINDING` 839cb93a386Sopenharmony_ci- `PathKit.FillType.INVERSE_EVENODD` 840cb93a386Sopenharmony_ci 841cb93a386Sopenharmony_ciThese are used by `SkPath.getFillType()` and `SkPath.setFillType()`, but 842cb93a386Sopenharmony_cigenerally clients will want `SkPath.getFillTypeString()`. 843cb93a386Sopenharmony_ci 844cb93a386Sopenharmony_ci### StrokeJoin (enum) 845cb93a386Sopenharmony_ci 846cb93a386Sopenharmony_ciThe following enum values are exposed. They are essentially constant objects, 847cb93a386Sopenharmony_cidifferentiated by their `.value` property. 848cb93a386Sopenharmony_ci 849cb93a386Sopenharmony_ci- `PathKit.StrokeJoin.MITER` 850cb93a386Sopenharmony_ci- `PathKit.StrokeJoin.ROUND` 851cb93a386Sopenharmony_ci- `PathKit.StrokeJoin.BEVEL` 852cb93a386Sopenharmony_ci 853cb93a386Sopenharmony_ciSee 854cb93a386Sopenharmony_ci[SkPaint reference](https://api.skia.org/classSkPaint.html#ac582b0cbf59909c9056de34a6b977cca) 855cb93a386Sopenharmony_cifor more details. 856cb93a386Sopenharmony_ci 857cb93a386Sopenharmony_ci### StrokeCap (enum) 858cb93a386Sopenharmony_ci 859cb93a386Sopenharmony_ciThe following enum values are exposed. They are essentially constant objects, 860cb93a386Sopenharmony_cidifferentiated by their `.value` property. 861cb93a386Sopenharmony_ci 862cb93a386Sopenharmony_ci- `PathKit.StrokeCap.BUTT` 863cb93a386Sopenharmony_ci- `PathKit.StrokeCap.ROUND` 864cb93a386Sopenharmony_ci- `PathKit.StrokeCap.SQUARE` 865cb93a386Sopenharmony_ci 866cb93a386Sopenharmony_ciSee 867cb93a386Sopenharmony_ci[SkPaint reference](https://api.skia.org/classSkPaint.html#a0f78de8559b795defba93171f6cb6333) 868cb93a386Sopenharmony_cifor more details. 869cb93a386Sopenharmony_ci 870cb93a386Sopenharmony_ci### Constants 871cb93a386Sopenharmony_ci 872cb93a386Sopenharmony_ciThe following constants are exposed: 873cb93a386Sopenharmony_ci 874cb93a386Sopenharmony_ci- `PathKit.MOVE_VERB` = 0 875cb93a386Sopenharmony_ci- `PathKit.LINE_VERB` = 1 876cb93a386Sopenharmony_ci- `PathKit.QUAD_VERB` = 2 877cb93a386Sopenharmony_ci- `PathKit.CONIC_VERB` = 3 878cb93a386Sopenharmony_ci- `PathKit.CUBIC_VERB` = 4 879cb93a386Sopenharmony_ci- `PathKit.CLOSE_VERB` = 5 880cb93a386Sopenharmony_ci 881cb93a386Sopenharmony_ciThese are only needed for `PathKit.FromCmds()`. 882cb93a386Sopenharmony_ci 883cb93a386Sopenharmony_ci### Functions for testing only 884cb93a386Sopenharmony_ci 885cb93a386Sopenharmony_ci#### `PathKit.LTRBRect(left, top, right, bottom)` 886cb93a386Sopenharmony_ci 887cb93a386Sopenharmony_ci**left** - `Number`, x coordinate of top-left corner of the `SkRect`. <br> 888cb93a386Sopenharmony_ci**top** - `Number`, y coordinate of top-left corner of the `SkRect`. <br> 889cb93a386Sopenharmony_ci**right** - `Number`, x coordinate of bottom-right corner of the `SkRect`. <br> 890cb93a386Sopenharmony_ci**bottom** - `Number`, y coordinate of bottom-right corner of the `SkRect`. 891cb93a386Sopenharmony_ci 892cb93a386Sopenharmony_ciReturns an `SkRect` object with the given params. 893cb93a386Sopenharmony_ci 894cb93a386Sopenharmony_ci#### `SkPath.dump()` 895cb93a386Sopenharmony_ci 896cb93a386Sopenharmony_ciPrints all the verbs and arguments to the console. Only available on Debug and 897cb93a386Sopenharmony_ciTest builds. 898