641bf8745d
Adds arc, arcTo, rect and Path2D names for quadTo, cubicTo, close. Adds conic verb support (approximated with 2 quads). Breaking changes: Some functions have been moved to be member functions: PathKit.Simplify(path) -> path.simplify() PathKit.ToCanvas(path, ctx) -> path.toCanvas(ctx) PathKit.ToSVGString(path) -> path.toSVGString() PathKit.ToPath2D(path) -> path.toPath2D() PathKit.ToCmds(path) -> path.toCmds() PathKit.ResolveBuilder(builder) -> builder.resolve() PathKit.GetBoundaryPathFromRegion(region) -> region.getBoundaryPath() Pathkit.ApplyPathOp(pathOne, pathTwo, op) still exists, but there's now also pathOne.op(pathTwo, op) for cases when that's easier. As per custom with version 0.x.y projects, I'm bumping the minor version (in npm) for these breaking changes instead of the major version (which will happen when we are version >= 1.0.0). This also has some small improvements to the output code size. The biggest jump was from enabling the closure compiler on the helper JS, which trimmed it down by about 40%. Using the closure compiler requires the JRE on the bots, which prompted the emsdk-base image change. Bug: skia:8216 Change-Id: I40902d23380093c34d1679df0255bcb0eaa77b01 Reviewed-on: https://skia-review.googlesource.com/145420 Reviewed-by: Joe Gregorio <jcgregorio@google.com> Reviewed-by: Florin Malita <fmalita@chromium.org>
162 lines
4.7 KiB
HTML
162 lines
4.7 KiB
HTML
<!DOCTYPE html>
|
|
<title>PathKit (Skia + WASM)</title>
|
|
<meta charset="utf-8" />
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
<style>
|
|
svg, canvas {
|
|
border: 1px dashed #AAA;
|
|
}
|
|
|
|
canvas {
|
|
width: 200px;
|
|
height: 200px;
|
|
}
|
|
|
|
canvas.big {
|
|
width: 300px;
|
|
height: 300px;
|
|
}
|
|
|
|
</style>
|
|
|
|
<h2> Can output to an SVG Path, a Canvas, or a Path2D object </h2>
|
|
<svg id=svg xmlns='http://www.w3.org/2000/svg' width=200 height=200></svg>
|
|
<canvas id=canvas1></canvas>
|
|
<canvas id=canvas2></canvas>
|
|
|
|
<h2> Interact with NewPath() just like a Path2D Object </h2>
|
|
<canvas class=big id=canvas3></canvas>
|
|
<canvas class=big id=canvas4></canvas>
|
|
|
|
<script type="text/javascript" src="/node_modules/experimental-pathkit-wasm/bin/pathkit.js"></script>
|
|
|
|
<script type="text/javascript" charset="utf-8">
|
|
|
|
PathKitInit({
|
|
locateFile: (file) => '/node_modules/experimental-pathkit-wasm/bin/'+file,
|
|
}).then((PathKit) => {
|
|
OutputsExample(PathKit);
|
|
Path2DExample(PathKit);
|
|
});
|
|
|
|
function setCanvasSize(ctx, width, height) {
|
|
ctx.canvas.width = width;
|
|
ctx.canvas.height = height;
|
|
}
|
|
|
|
function OutputsExample(PathKit) {
|
|
let firstPath = PathKit.FromSVGString('M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm.5-13H11v6l5.25 3.15.75-1.23-4.5-2.67z');
|
|
|
|
let secondPath = PathKit.NewPath();
|
|
// Acts somewhat like the Canvas API
|
|
secondPath.moveTo(1, 1);
|
|
secondPath.lineTo(20, 1);
|
|
secondPath.lineTo(10, 30);
|
|
secondPath.closePath();
|
|
|
|
let combinedPath = firstPath.op(secondPath, PathKit.PathOp.INTERSECT);
|
|
let simpleStr = combinedPath.toSVGString();
|
|
|
|
let newSVG = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
|
newSVG.setAttribute('stroke', 'rgb(0,0,200)');
|
|
newSVG.setAttribute('fill', 'white');
|
|
newSVG.setAttribute('transform', 'scale(8,8)');
|
|
newSVG.setAttribute('d', simpleStr);
|
|
document.getElementById('svg').appendChild(newSVG);
|
|
|
|
// Draw directly to Canvas
|
|
let ctx = document.getElementById('canvas1').getContext('2d');
|
|
setCanvasSize(ctx, 200, 200);
|
|
ctx.strokeStyle = 'green';
|
|
ctx.fillStyle = 'white';
|
|
ctx.scale(8, 8);
|
|
ctx.beginPath();
|
|
combinedPath.toCanvas(ctx);
|
|
ctx.stroke();
|
|
|
|
// create Path2D object and use it in a Canvas.
|
|
let path2D = combinedPath.toPath2D();
|
|
ctx = document.getElementById('canvas2').getContext('2d');
|
|
setCanvasSize(ctx, 200, 200);
|
|
ctx.canvas.width = 200
|
|
ctx.scale(8, 8);
|
|
ctx.fillStyle = 'purple';
|
|
ctx.strokeStyle = 'orange';
|
|
ctx.fill(path2D);
|
|
ctx.stroke(path2D);
|
|
|
|
// clean up WASM memory
|
|
// See http://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_and_javascript/embind.html?highlight=memory#memory-management
|
|
firstPath.delete();
|
|
secondPath.delete();
|
|
combinedPath.delete();
|
|
}
|
|
|
|
function Path2DExample(PathKit) {
|
|
let objs = [new Path2D(), PathKit.NewPath(), new Path2D(), PathKit.NewPath()];
|
|
let canvases = [
|
|
document.getElementById('canvas3').getContext('2d'),
|
|
document.getElementById('canvas4').getContext('2d')
|
|
];
|
|
|
|
for (i = 0; i <= 1; i++) {
|
|
let path = objs[i];
|
|
|
|
path.moveTo(20, 5);
|
|
path.lineTo(30, 20);
|
|
path.lineTo(40, 10);
|
|
path.lineTo(50, 20);
|
|
path.lineTo(60, 0);
|
|
path.lineTo(20, 5);
|
|
|
|
path.moveTo(20, 80);
|
|
path.bezierCurveTo(90, 10, 160, 150, 190, 10);
|
|
|
|
path.moveTo(36, 148);
|
|
path.quadraticCurveTo(66, 188, 120, 136);
|
|
path.lineTo(36, 148);
|
|
|
|
path.rect(5, 170, 20, 20);
|
|
|
|
path.moveTo(150, 180);
|
|
path.arcTo(150, 100, 50, 200, 20);
|
|
path.lineTo(160, 160);
|
|
|
|
path.moveTo(20, 120);
|
|
path.arc(20, 120, 18, 0, 1.75 * Math.PI);
|
|
path.lineTo(20, 120);
|
|
|
|
let secondPath = objs[i+2];
|
|
secondPath.ellipse(130, 25, 30, 10, -1*Math.PI/8, Math.PI/6, 1.5*Math.PI, false);
|
|
|
|
path.addPath(secondPath);
|
|
|
|
let m = document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGMatrix();
|
|
m.a = 1; m.b = 0;
|
|
m.c = 0; m.d = 1;
|
|
m.e = 0; m.f = 20.5;
|
|
|
|
path.addPath(secondPath, m);
|
|
// With PathKit, one can also just provide the 6 params as floats, to avoid
|
|
// the overhead of making an SVGMatrix
|
|
// path.addPath(secondPath, 1, 0, 0, 1, 0, 20.5);
|
|
|
|
canvasCtx = canvases[i];
|
|
canvasCtx.fillStyle = 'blue';
|
|
setCanvasSize(canvasCtx, 300, 300);
|
|
canvasCtx.scale(1.5, 1.5);
|
|
if (path.toPath2D) {
|
|
canvasCtx.stroke(path.toPath2D());
|
|
} else {
|
|
canvasCtx.stroke(path);
|
|
}
|
|
}
|
|
|
|
|
|
objs[1].delete();
|
|
}
|
|
|
|
</script>
|