From a7c831434d000435ea37060b1c91a0dee57bd762 Mon Sep 17 00:00:00 2001 From: Preet Shihn Date: Fri, 13 Jul 2018 20:12:29 -0700 Subject: [PATCH] refactoring to clean up interfaces --- bin/canvas-async.d.ts | 7 +- bin/canvas-async.js | 19 +- bin/canvas-base.d.ts | 13 + bin/canvas-base.js | 128 +++++++ bin/canvas.d.ts | 14 +- bin/canvas.js | 129 +------ bin/generator-async.d.ts | 4 +- bin/generator-async.js | 13 +- bin/generator-base.d.ts | 20 + bin/generator-base.js | 191 ++++++++++ bin/generator.d.ts | 20 +- bin/generator.js | 191 +--------- bin/rough.d.ts | 4 +- bin/svg-async.d.ts | 8 +- bin/svg-async.js | 22 +- bin/svg-base.d.ts | 13 + bin/svg-base.js | 108 ++++++ bin/svg.d.ts | 15 +- bin/svg.js | 113 +----- dist/rough.es5.js | 741 +++++++++++++++++++------------------- dist/rough.es5.min.js | 2 +- dist/rough.js | 450 +++++++++++------------ dist/rough.min.js | 2 +- dist/rough.umd.es5.js | 741 +++++++++++++++++++------------------- dist/rough.umd.es5.min.js | 2 +- dist/rough.umd.js | 450 +++++++++++------------ dist/rough.umd.min.js | 2 +- package.json | 2 +- src/canvas-async.ts | 22 +- src/canvas-base.ts | 137 +++++++ src/canvas.ts | 152 +------- src/generator-async.ts | 14 +- src/generator-base.ts | 209 +++++++++++ src/generator.ts | 208 +---------- src/rough.ts | 6 +- src/svg-async.ts | 26 +- src/svg-base.ts | 121 +++++++ src/svg.ts | 120 +----- 38 files changed, 2259 insertions(+), 2180 deletions(-) create mode 100644 bin/canvas-base.d.ts create mode 100644 bin/canvas-base.js create mode 100644 bin/generator-base.d.ts create mode 100644 bin/generator-base.js create mode 100644 bin/svg-base.d.ts create mode 100644 bin/svg-base.js create mode 100644 src/canvas-base.ts create mode 100644 src/generator-base.ts create mode 100644 src/svg-base.ts diff --git a/bin/canvas-async.d.ts b/bin/canvas-async.d.ts index fa20b0f..07ed0d3 100644 --- a/bin/canvas-async.d.ts +++ b/bin/canvas-async.d.ts @@ -1,11 +1,12 @@ -import { RoughCanvas } from './canvas'; -import { Config, Options, Drawable } from './core'; +import { Config, Options, ResolvedOptions, Drawable } from './core'; import { RoughGeneratorAsync } from './generator-async'; import { Point } from './geometry'; -export declare class RoughCanvasAsync extends RoughCanvas { +import { RoughCanvasBase } from './canvas-base'; +export declare class RoughCanvasAsync extends RoughCanvasBase { private genAsync; constructor(canvas: HTMLCanvasElement, config?: Config); readonly generator: RoughGeneratorAsync; + getDefaultOptions(): ResolvedOptions; line(x1: number, y1: number, x2: number, y2: number, options?: Options): Promise; rectangle(x: number, y: number, width: number, height: number, options?: Options): Promise; ellipse(x: number, y: number, width: number, height: number, options?: Options): Promise; diff --git a/bin/canvas-async.js b/bin/canvas-async.js index d04f838..e544f47 100644 --- a/bin/canvas-async.js +++ b/bin/canvas-async.js @@ -1,63 +1,56 @@ -import { RoughCanvas } from './canvas'; import { RoughGeneratorAsync } from './generator-async'; -export class RoughCanvasAsync extends RoughCanvas { +import { RoughCanvasBase } from './canvas-base'; +export class RoughCanvasAsync extends RoughCanvasBase { constructor(canvas, config) { - super(canvas, config); + super(canvas); this.genAsync = new RoughGeneratorAsync(config || null, this.canvas); } - // @ts-ignore get generator() { return this.genAsync; } - // @ts-ignore + getDefaultOptions() { + return this.genAsync.defaultOptions; + } async line(x1, y1, x2, y2, options) { const d = await this.genAsync.line(x1, y1, x2, y2, options); this.draw(d); return d; } - // @ts-ignore async rectangle(x, y, width, height, options) { const d = await this.genAsync.rectangle(x, y, width, height, options); this.draw(d); return d; } - // @ts-ignore async ellipse(x, y, width, height, options) { const d = await this.genAsync.ellipse(x, y, width, height, options); this.draw(d); return d; } - // @ts-ignore async circle(x, y, diameter, options) { const d = await this.genAsync.circle(x, y, diameter, options); this.draw(d); return d; } - // @ts-ignore async linearPath(points, options) { const d = await this.genAsync.linearPath(points, options); this.draw(d); return d; } - // @ts-ignore async polygon(points, options) { const d = await this.genAsync.polygon(points, options); this.draw(d); return d; } - // @ts-ignore async arc(x, y, width, height, start, stop, closed = false, options) { const d = await this.genAsync.arc(x, y, width, height, start, stop, closed, options); this.draw(d); return d; } - // @ts-ignore async curve(points, options) { const d = await this.genAsync.curve(points, options); this.draw(d); return d; } - // @ts-ignore async path(d, options) { const drawing = await this.genAsync.path(d, options); this.draw(drawing); diff --git a/bin/canvas-base.d.ts b/bin/canvas-base.d.ts new file mode 100644 index 0000000..2fa0ebf --- /dev/null +++ b/bin/canvas-base.d.ts @@ -0,0 +1,13 @@ +import { ResolvedOptions, Drawable } from './core'; +import { RoughRenderer } from './renderer'; +export declare abstract class RoughCanvasBase { + protected canvas: HTMLCanvasElement; + protected ctx: CanvasRenderingContext2D; + constructor(canvas: HTMLCanvasElement); + static createRenderer(): RoughRenderer; + abstract getDefaultOptions(): ResolvedOptions; + draw(drawable: Drawable): void; + private computeBBox; + private fillSketch; + private _drawToContext; +} diff --git a/bin/canvas-base.js b/bin/canvas-base.js new file mode 100644 index 0000000..017bdb7 --- /dev/null +++ b/bin/canvas-base.js @@ -0,0 +1,128 @@ +import { RoughRenderer } from './renderer'; +const hasDocument = typeof document !== 'undefined'; +export class RoughCanvasBase { + constructor(canvas) { + this.canvas = canvas; + this.ctx = this.canvas.getContext('2d'); + } + static createRenderer() { + return new RoughRenderer(); + } + draw(drawable) { + const sets = drawable.sets || []; + const o = drawable.options || this.getDefaultOptions(); + const ctx = this.ctx; + for (const drawing of sets) { + switch (drawing.type) { + case 'path': + ctx.save(); + ctx.strokeStyle = o.stroke; + ctx.lineWidth = o.strokeWidth; + this._drawToContext(ctx, drawing); + ctx.restore(); + break; + case 'fillPath': + ctx.save(); + ctx.fillStyle = o.fill || ''; + this._drawToContext(ctx, drawing); + ctx.restore(); + break; + case 'fillSketch': + this.fillSketch(ctx, drawing, o); + break; + case 'path2Dfill': { + this.ctx.save(); + this.ctx.fillStyle = o.fill || ''; + const p2d = new Path2D(drawing.path); + this.ctx.fill(p2d); + this.ctx.restore(); + break; + } + case 'path2Dpattern': { + const doc = this.canvas.ownerDocument || (hasDocument && document); + if (doc) { + const size = drawing.size; + const hcanvas = doc.createElement('canvas'); + const hcontext = hcanvas.getContext('2d'); + const bbox = this.computeBBox(drawing.path); + if (bbox && (bbox.width || bbox.height)) { + hcanvas.width = this.canvas.width; + hcanvas.height = this.canvas.height; + hcontext.translate(bbox.x || 0, bbox.y || 0); + } + else { + hcanvas.width = size[0]; + hcanvas.height = size[1]; + } + this.fillSketch(hcontext, drawing, o); + this.ctx.save(); + this.ctx.fillStyle = this.ctx.createPattern(hcanvas, 'repeat'); + const p2d = new Path2D(drawing.path); + this.ctx.fill(p2d); + this.ctx.restore(); + } + else { + console.error('Cannot render path2Dpattern. No defs/document defined.'); + } + break; + } + } + } + } + computeBBox(d) { + if (hasDocument) { + try { + const ns = 'http://www.w3.org/2000/svg'; + const svg = document.createElementNS(ns, 'svg'); + svg.setAttribute('width', '0'); + svg.setAttribute('height', '0'); + const pathNode = self.document.createElementNS(ns, 'path'); + pathNode.setAttribute('d', d); + svg.appendChild(pathNode); + document.body.appendChild(svg); + const bbox = pathNode.getBBox(); + document.body.removeChild(svg); + return bbox; + } + catch (err) { } + } + return null; + } + fillSketch(ctx, drawing, o) { + let fweight = o.fillWeight; + if (fweight < 0) { + fweight = o.strokeWidth / 2; + } + ctx.save(); + ctx.strokeStyle = o.fill || ''; + ctx.lineWidth = fweight; + this._drawToContext(ctx, drawing); + ctx.restore(); + } + _drawToContext(ctx, drawing) { + ctx.beginPath(); + for (const item of drawing.ops) { + const data = item.data; + switch (item.op) { + case 'move': + ctx.moveTo(data[0], data[1]); + break; + case 'bcurveTo': + ctx.bezierCurveTo(data[0], data[1], data[2], data[3], data[4], data[5]); + break; + case 'qcurveTo': + ctx.quadraticCurveTo(data[0], data[1], data[2], data[3]); + break; + case 'lineTo': + ctx.lineTo(data[0], data[1]); + break; + } + } + if (drawing.type === 'fillPath') { + ctx.fill(); + } + else { + ctx.stroke(); + } + } +} diff --git a/bin/canvas.d.ts b/bin/canvas.d.ts index bcc4e7e..79ad007 100644 --- a/bin/canvas.d.ts +++ b/bin/canvas.d.ts @@ -1,14 +1,12 @@ -import { Config, Options, Drawable } from './core'; +import { Config, Options, ResolvedOptions, Drawable } from './core'; import { RoughGenerator } from './generator'; -import { RoughRenderer } from './renderer'; import { Point } from './geometry'; -export declare class RoughCanvas { - protected canvas: HTMLCanvasElement; - protected ctx: CanvasRenderingContext2D; +import { RoughCanvasBase } from './canvas-base'; +export declare class RoughCanvas extends RoughCanvasBase { private gen; constructor(canvas: HTMLCanvasElement, config?: Config); readonly generator: RoughGenerator; - static createRenderer(): RoughRenderer; + getDefaultOptions(): ResolvedOptions; line(x1: number, y1: number, x2: number, y2: number, options?: Options): Drawable; rectangle(x: number, y: number, width: number, height: number, options?: Options): Drawable; ellipse(x: number, y: number, width: number, height: number, options?: Options): Drawable; @@ -18,8 +16,4 @@ export declare class RoughCanvas { arc(x: number, y: number, width: number, height: number, start: number, stop: number, closed?: boolean, options?: Options): Drawable; curve(points: Point[], options?: Options): Drawable; path(d: string, options?: Options): Drawable; - draw(drawable: Drawable): void; - private computeBBox; - private fillSketch; - private _drawToContext; } diff --git a/bin/canvas.js b/bin/canvas.js index e753bb3..d201d80 100644 --- a/bin/canvas.js +++ b/bin/canvas.js @@ -1,17 +1,15 @@ import { RoughGenerator } from './generator'; -import { RoughRenderer } from './renderer'; -const hasDocument = typeof document !== 'undefined'; -export class RoughCanvas { +import { RoughCanvasBase } from './canvas-base'; +export class RoughCanvas extends RoughCanvasBase { constructor(canvas, config) { - this.canvas = canvas; - this.ctx = this.canvas.getContext('2d'); + super(canvas); this.gen = new RoughGenerator(config || null, this.canvas); } get generator() { return this.gen; } - static createRenderer() { - return new RoughRenderer(); + getDefaultOptions() { + return this.gen.defaultOptions; } line(x1, y1, x2, y2, options) { const d = this.gen.line(x1, y1, x2, y2, options); @@ -58,121 +56,4 @@ export class RoughCanvas { this.draw(drawing); return drawing; } - draw(drawable) { - const sets = drawable.sets || []; - const o = drawable.options || this.gen.defaultOptions; - const ctx = this.ctx; - for (const drawing of sets) { - switch (drawing.type) { - case 'path': - ctx.save(); - ctx.strokeStyle = o.stroke; - ctx.lineWidth = o.strokeWidth; - this._drawToContext(ctx, drawing); - ctx.restore(); - break; - case 'fillPath': - ctx.save(); - ctx.fillStyle = o.fill || ''; - this._drawToContext(ctx, drawing); - ctx.restore(); - break; - case 'fillSketch': - this.fillSketch(ctx, drawing, o); - break; - case 'path2Dfill': { - this.ctx.save(); - this.ctx.fillStyle = o.fill || ''; - const p2d = new Path2D(drawing.path); - this.ctx.fill(p2d); - this.ctx.restore(); - break; - } - case 'path2Dpattern': { - const doc = this.canvas.ownerDocument || (hasDocument && document); - if (doc) { - const size = drawing.size; - const hcanvas = doc.createElement('canvas'); - const hcontext = hcanvas.getContext('2d'); - const bbox = this.computeBBox(drawing.path); - if (bbox && (bbox.width || bbox.height)) { - hcanvas.width = this.canvas.width; - hcanvas.height = this.canvas.height; - hcontext.translate(bbox.x || 0, bbox.y || 0); - } - else { - hcanvas.width = size[0]; - hcanvas.height = size[1]; - } - this.fillSketch(hcontext, drawing, o); - this.ctx.save(); - this.ctx.fillStyle = this.ctx.createPattern(hcanvas, 'repeat'); - const p2d = new Path2D(drawing.path); - this.ctx.fill(p2d); - this.ctx.restore(); - } - else { - console.error('Cannot render path2Dpattern. No defs/document defined.'); - } - break; - } - } - } - } - computeBBox(d) { - if (hasDocument) { - try { - const ns = 'http://www.w3.org/2000/svg'; - const svg = document.createElementNS(ns, 'svg'); - svg.setAttribute('width', '0'); - svg.setAttribute('height', '0'); - const pathNode = self.document.createElementNS(ns, 'path'); - pathNode.setAttribute('d', d); - svg.appendChild(pathNode); - document.body.appendChild(svg); - const bbox = pathNode.getBBox(); - document.body.removeChild(svg); - return bbox; - } - catch (err) { } - } - return null; - } - fillSketch(ctx, drawing, o) { - let fweight = o.fillWeight; - if (fweight < 0) { - fweight = o.strokeWidth / 2; - } - ctx.save(); - ctx.strokeStyle = o.fill || ''; - ctx.lineWidth = fweight; - this._drawToContext(ctx, drawing); - ctx.restore(); - } - _drawToContext(ctx, drawing) { - ctx.beginPath(); - for (const item of drawing.ops) { - const data = item.data; - switch (item.op) { - case 'move': - ctx.moveTo(data[0], data[1]); - break; - case 'bcurveTo': - ctx.bezierCurveTo(data[0], data[1], data[2], data[3], data[4], data[5]); - break; - case 'qcurveTo': - ctx.quadraticCurveTo(data[0], data[1], data[2], data[3]); - break; - case 'lineTo': - ctx.lineTo(data[0], data[1]); - break; - } - } - if (drawing.type === 'fillPath') { - ctx.fill(); - } - else { - ctx.stroke(); - } - } } diff --git a/bin/generator-async.d.ts b/bin/generator-async.d.ts index 954037e..f8669b6 100644 --- a/bin/generator-async.d.ts +++ b/bin/generator-async.d.ts @@ -1,7 +1,7 @@ -import { RoughGenerator } from './generator'; import { Options, Drawable } from './core'; import { Point } from './geometry.js'; -export declare class RoughGeneratorAsync extends RoughGenerator { +import { RoughGeneratorBase } from './generator-base'; +export declare class RoughGeneratorAsync extends RoughGeneratorBase { line(x1: number, y1: number, x2: number, y2: number, options?: Options): Promise; rectangle(x: number, y: number, width: number, height: number, options?: Options): Promise; ellipse(x: number, y: number, width: number, height: number, options?: Options): Promise; diff --git a/bin/generator-async.js b/bin/generator-async.js index 27ecfe8..6ccee2a 100644 --- a/bin/generator-async.js +++ b/bin/generator-async.js @@ -1,11 +1,9 @@ -import { RoughGenerator } from './generator'; -export class RoughGeneratorAsync extends RoughGenerator { - // @ts-ignore +import { RoughGeneratorBase } from './generator-base'; +export class RoughGeneratorAsync extends RoughGeneratorBase { async line(x1, y1, x2, y2, options) { const o = this._options(options); return this._drawable('line', [await this.lib.line(x1, y1, x2, y2, o)], o); } - // @ts-ignore async rectangle(x, y, width, height, options) { const o = this._options(options); const paths = []; @@ -21,7 +19,6 @@ export class RoughGeneratorAsync extends RoughGenerator { paths.push(await this.lib.rectangle(x, y, width, height, o)); return this._drawable('rectangle', paths, o); } - // @ts-ignore async ellipse(x, y, width, height, options) { const o = this._options(options); const paths = []; @@ -38,18 +35,15 @@ export class RoughGeneratorAsync extends RoughGenerator { paths.push(await this.lib.ellipse(x, y, width, height, o)); return this._drawable('ellipse', paths, o); } - // @ts-ignore async circle(x, y, diameter, options) { const ret = await this.ellipse(x, y, diameter, diameter, options); ret.shape = 'circle'; return ret; } - // @ts-ignore async linearPath(points, options) { const o = this._options(options); return this._drawable('linearPath', [await this.lib.linearPath(points, false, o)], o); } - // @ts-ignore async arc(x, y, width, height, start, stop, closed = false, options) { const o = this._options(options); const paths = []; @@ -66,12 +60,10 @@ export class RoughGeneratorAsync extends RoughGenerator { paths.push(await this.lib.arc(x, y, width, height, start, stop, closed, true, o)); return this._drawable('arc', paths, o); } - // @ts-ignore async curve(points, options) { const o = this._options(options); return this._drawable('curve', [await this.lib.curve(points, o)], o); } - // @ts-ignore async polygon(points, options) { const o = this._options(options); const paths = []; @@ -97,7 +89,6 @@ export class RoughGeneratorAsync extends RoughGenerator { paths.push(await this.lib.linearPath(points, true, o)); return this._drawable('polygon', paths, o); } - // @ts-ignore async path(d, options) { const o = this._options(options); const paths = []; diff --git a/bin/generator-base.d.ts b/bin/generator-base.d.ts new file mode 100644 index 0000000..24fbd61 --- /dev/null +++ b/bin/generator-base.d.ts @@ -0,0 +1,20 @@ +import { RoughRenderer } from './renderer.js'; +import { Config, DrawingSurface, Options, ResolvedOptions, Drawable, OpSet, PathInfo } from './core'; +import { Point } from './geometry.js'; +export declare abstract class RoughGeneratorBase { + protected config: Config; + protected surface: DrawingSurface; + protected renderer: RoughRenderer; + defaultOptions: ResolvedOptions; + constructor(config: Config | null, surface: DrawingSurface); + protected _options(options?: Options): ResolvedOptions; + protected _drawable(shape: string, sets: OpSet[], options: ResolvedOptions): Drawable; + protected readonly lib: RoughRenderer; + private getCanvasSize; + protected computePolygonSize(points: Point[]): Point; + protected polygonPath(points: Point[]): string; + protected computePathSize(d: string): Point; + toPaths(drawable: Drawable): PathInfo[]; + private fillSketch; + opsToPath(drawing: OpSet): string; +} diff --git a/bin/generator-base.js b/bin/generator-base.js new file mode 100644 index 0000000..2fb76ef --- /dev/null +++ b/bin/generator-base.js @@ -0,0 +1,191 @@ +import { createRenderer } from './renderer-factory.js'; +const hasSelf = typeof self !== 'undefined'; +export class RoughGeneratorBase { + constructor(config, surface) { + this.defaultOptions = { + maxRandomnessOffset: 2, + roughness: 1, + bowing: 1, + stroke: '#000', + strokeWidth: 1, + curveTightness: 0, + curveStepCount: 9, + fillStyle: 'hachure', + fillWeight: -1, + hachureAngle: -41, + hachureGap: -1 + }; + this.config = config || {}; + this.surface = surface; + this.renderer = createRenderer(this.config); + if (this.config.options) { + this.defaultOptions = this._options(this.config.options); + } + } + _options(options) { + return options ? Object.assign({}, this.defaultOptions, options) : this.defaultOptions; + } + _drawable(shape, sets, options) { + return { shape, sets: sets || [], options: options || this.defaultOptions }; + } + get lib() { + return this.renderer; + } + getCanvasSize() { + const val = (w) => { + if (w && typeof w === 'object') { + if (w.baseVal && w.baseVal.value) { + return w.baseVal.value; + } + } + return w || 100; + }; + if (this.surface) { + return [val(this.surface.width), val(this.surface.height)]; + } + return [100, 100]; + } + computePolygonSize(points) { + if (points.length) { + let left = points[0][0]; + let right = points[0][0]; + let top = points[0][1]; + let bottom = points[0][1]; + for (let i = 1; i < points.length; i++) { + left = Math.min(left, points[i][0]); + right = Math.max(right, points[i][0]); + top = Math.min(top, points[i][1]); + bottom = Math.max(bottom, points[i][1]); + } + return [(right - left), (bottom - top)]; + } + return [0, 0]; + } + polygonPath(points) { + let d = ''; + if (points.length) { + d = `M${points[0][0]},${points[0][1]}`; + for (let i = 1; i < points.length; i++) { + d = `${d} L${points[i][0]},${points[i][1]}`; + } + } + return d; + } + computePathSize(d) { + let size = [0, 0]; + if (hasSelf && self.document) { + try { + const ns = 'http://www.w3.org/2000/svg'; + const svg = self.document.createElementNS(ns, 'svg'); + svg.setAttribute('width', '0'); + svg.setAttribute('height', '0'); + const pathNode = self.document.createElementNS(ns, 'path'); + pathNode.setAttribute('d', d); + svg.appendChild(pathNode); + self.document.body.appendChild(svg); + const bb = pathNode.getBBox(); + if (bb) { + size[0] = bb.width || 0; + size[1] = bb.height || 0; + } + self.document.body.removeChild(svg); + } + catch (err) { } + } + const canvasSize = this.getCanvasSize(); + if (!(size[0] * size[1])) { + size = canvasSize; + } + return size; + } + toPaths(drawable) { + const sets = drawable.sets || []; + const o = drawable.options || this.defaultOptions; + const paths = []; + for (const drawing of sets) { + let path = null; + switch (drawing.type) { + case 'path': + path = { + d: this.opsToPath(drawing), + stroke: o.stroke, + strokeWidth: o.strokeWidth, + fill: 'none' + }; + break; + case 'fillPath': + path = { + d: this.opsToPath(drawing), + stroke: 'none', + strokeWidth: 0, + fill: o.fill || 'none' + }; + break; + case 'fillSketch': + path = this.fillSketch(drawing, o); + break; + case 'path2Dfill': + path = { + d: drawing.path || '', + stroke: 'none', + strokeWidth: 0, + fill: o.fill || 'none' + }; + break; + case 'path2Dpattern': { + const size = drawing.size; + const pattern = { + x: 0, y: 0, width: 1, height: 1, + viewBox: `0 0 ${Math.round(size[0])} ${Math.round(size[1])}`, + patternUnits: 'objectBoundingBox', + path: this.fillSketch(drawing, o) + }; + path = { + d: drawing.path, + stroke: 'none', + strokeWidth: 0, + pattern: pattern + }; + break; + } + } + if (path) { + paths.push(path); + } + } + return paths; + } + fillSketch(drawing, o) { + let fweight = o.fillWeight; + if (fweight < 0) { + fweight = o.strokeWidth / 2; + } + return { + d: this.opsToPath(drawing), + stroke: o.fill || 'none', + strokeWidth: fweight, + fill: 'none' + }; + } + opsToPath(drawing) { + let path = ''; + for (const item of drawing.ops) { + const data = item.data; + switch (item.op) { + case 'move': + path += `M${data[0]} ${data[1]} `; + break; + case 'bcurveTo': + path += `C${data[0]} ${data[1]}, ${data[2]} ${data[3]}, ${data[4]} ${data[5]} `; + break; + case 'qcurveTo': + path += `Q${data[0]} ${data[1]}, ${data[2]} ${data[3]} `; + break; + case 'lineTo': + path += `L${data[0]} ${data[1]} `; + break; + } + } + return path.trim(); + } +} diff --git a/bin/generator.d.ts b/bin/generator.d.ts index 0914346..4b4e4af 100644 --- a/bin/generator.d.ts +++ b/bin/generator.d.ts @@ -1,19 +1,8 @@ -import { RoughRenderer } from './renderer.js'; -import { Config, DrawingSurface, Options, ResolvedOptions, Drawable, OpSet, PathInfo } from './core'; +import { Config, DrawingSurface, Options, Drawable } from './core'; import { Point } from './geometry.js'; -export declare class RoughGenerator { - private config; - private surface; - private renderer; - defaultOptions: ResolvedOptions; +import { RoughGeneratorBase } from './generator-base'; +export declare class RoughGenerator extends RoughGeneratorBase { constructor(config: Config | null, surface: DrawingSurface); - protected _options(options?: Options): ResolvedOptions; - protected _drawable(shape: string, sets: OpSet[], options: ResolvedOptions): Drawable; - protected readonly lib: RoughRenderer; - private getCanvasSize; - protected computePolygonSize(points: Point[]): Point; - protected polygonPath(points: Point[]): string; - protected computePathSize(d: string): Point; line(x1: number, y1: number, x2: number, y2: number, options?: Options): Drawable; rectangle(x: number, y: number, width: number, height: number, options?: Options): Drawable; ellipse(x: number, y: number, width: number, height: number, options?: Options): Drawable; @@ -23,7 +12,4 @@ export declare class RoughGenerator { curve(points: Point[], options?: Options): Drawable; polygon(points: Point[], options?: Options): Drawable; path(d: string, options?: Options): Drawable; - toPaths(drawable: Drawable): PathInfo[]; - private fillSketch; - opsToPath(drawing: OpSet): string; } diff --git a/bin/generator.js b/bin/generator.js index e9540dc..3b4661c 100644 --- a/bin/generator.js +++ b/bin/generator.js @@ -1,102 +1,7 @@ -import { createRenderer } from './renderer-factory.js'; -const hasSelf = typeof self !== 'undefined'; -export class RoughGenerator { +import { RoughGeneratorBase } from './generator-base'; +export class RoughGenerator extends RoughGeneratorBase { constructor(config, surface) { - this.defaultOptions = { - maxRandomnessOffset: 2, - roughness: 1, - bowing: 1, - stroke: '#000', - strokeWidth: 1, - curveTightness: 0, - curveStepCount: 9, - fillStyle: 'hachure', - fillWeight: -1, - hachureAngle: -41, - hachureGap: -1 - }; - this.config = config || {}; - this.surface = surface; - this.renderer = createRenderer(this.config); - if (this.config.options) { - this.defaultOptions = this._options(this.config.options); - } - } - _options(options) { - return options ? Object.assign({}, this.defaultOptions, options) : this.defaultOptions; - } - _drawable(shape, sets, options) { - return { shape, sets: sets || [], options: options || this.defaultOptions }; - } - get lib() { - return this.renderer; - } - getCanvasSize() { - const val = (w) => { - if (w && typeof w === 'object') { - if (w.baseVal && w.baseVal.value) { - return w.baseVal.value; - } - } - return w || 100; - }; - if (this.surface) { - return [val(this.surface.width), val(this.surface.height)]; - } - return [100, 100]; - } - computePolygonSize(points) { - if (points.length) { - let left = points[0][0]; - let right = points[0][0]; - let top = points[0][1]; - let bottom = points[0][1]; - for (let i = 1; i < points.length; i++) { - left = Math.min(left, points[i][0]); - right = Math.max(right, points[i][0]); - top = Math.min(top, points[i][1]); - bottom = Math.max(bottom, points[i][1]); - } - return [(right - left), (bottom - top)]; - } - return [0, 0]; - } - polygonPath(points) { - let d = ''; - if (points.length) { - d = `M${points[0][0]},${points[0][1]}`; - for (let i = 1; i < points.length; i++) { - d = `${d} L${points[i][0]},${points[i][1]}`; - } - } - return d; - } - computePathSize(d) { - let size = [0, 0]; - if (hasSelf && self.document) { - try { - const ns = 'http://www.w3.org/2000/svg'; - const svg = self.document.createElementNS(ns, 'svg'); - svg.setAttribute('width', '0'); - svg.setAttribute('height', '0'); - const pathNode = self.document.createElementNS(ns, 'path'); - pathNode.setAttribute('d', d); - svg.appendChild(pathNode); - self.document.body.appendChild(svg); - const bb = pathNode.getBBox(); - if (bb) { - size[0] = bb.width || 0; - size[1] = bb.height || 0; - } - self.document.body.removeChild(svg); - } - catch (err) { } - } - const canvasSize = this.getCanvasSize(); - if (!(size[0] * size[1])) { - size = canvasSize; - } - return size; + super(config, surface); } line(x1, y1, x2, y2, options) { const o = this._options(options); @@ -216,94 +121,4 @@ export class RoughGenerator { paths.push(this.lib.svgPath(d, o)); return this._drawable('path', paths, o); } - toPaths(drawable) { - const sets = drawable.sets || []; - const o = drawable.options || this.defaultOptions; - const paths = []; - for (const drawing of sets) { - let path = null; - switch (drawing.type) { - case 'path': - path = { - d: this.opsToPath(drawing), - stroke: o.stroke, - strokeWidth: o.strokeWidth, - fill: 'none' - }; - break; - case 'fillPath': - path = { - d: this.opsToPath(drawing), - stroke: 'none', - strokeWidth: 0, - fill: o.fill || 'none' - }; - break; - case 'fillSketch': - path = this.fillSketch(drawing, o); - break; - case 'path2Dfill': - path = { - d: drawing.path || '', - stroke: 'none', - strokeWidth: 0, - fill: o.fill || 'none' - }; - break; - case 'path2Dpattern': { - const size = drawing.size; - const pattern = { - x: 0, y: 0, width: 1, height: 1, - viewBox: `0 0 ${Math.round(size[0])} ${Math.round(size[1])}`, - patternUnits: 'objectBoundingBox', - path: this.fillSketch(drawing, o) - }; - path = { - d: drawing.path, - stroke: 'none', - strokeWidth: 0, - pattern: pattern - }; - break; - } - } - if (path) { - paths.push(path); - } - } - return paths; - } - fillSketch(drawing, o) { - let fweight = o.fillWeight; - if (fweight < 0) { - fweight = o.strokeWidth / 2; - } - return { - d: this.opsToPath(drawing), - stroke: o.fill || 'none', - strokeWidth: fweight, - fill: 'none' - }; - } - opsToPath(drawing) { - let path = ''; - for (const item of drawing.ops) { - const data = item.data; - switch (item.op) { - case 'move': - path += `M${data[0]} ${data[1]} `; - break; - case 'bcurveTo': - path += `C${data[0]} ${data[1]}, ${data[2]} ${data[3]}, ${data[4]} ${data[5]} `; - break; - case 'qcurveTo': - path += `Q${data[0]} ${data[1]}, ${data[2]} ${data[3]} `; - break; - case 'lineTo': - path += `L${data[0]} ${data[1]} `; - break; - } - } - return path.trim(); - } } diff --git a/bin/rough.d.ts b/bin/rough.d.ts index b9a0af7..afb6b25 100644 --- a/bin/rough.d.ts +++ b/bin/rough.d.ts @@ -7,9 +7,9 @@ import { RoughCanvasAsync } from './canvas-async'; import { RoughSVG } from './svg'; import { RoughSVGAsync } from './svg-async'; declare const _default: { - canvas(canvas: HTMLCanvasElement, config?: Config | undefined): RoughCanvas | RoughCanvasAsync; + canvas(canvas: HTMLCanvasElement, config?: Config | undefined): RoughCanvasAsync | RoughCanvas; svg(svg: SVGSVGElement, config?: Config | undefined): RoughSVG | RoughSVGAsync; createRenderer(): RoughRenderer; - generator(config: Config | null, surface: DrawingSurface): RoughGenerator | RoughGeneratorAsync; + generator(config: Config | null, surface: DrawingSurface): RoughGeneratorAsync | RoughGenerator; }; export default _default; diff --git a/bin/svg-async.d.ts b/bin/svg-async.d.ts index 8a9e54b..b0ba0f3 100644 --- a/bin/svg-async.d.ts +++ b/bin/svg-async.d.ts @@ -1,11 +1,13 @@ -import { RoughSVG } from './svg'; -import { Config, Options } from './core'; +import { Config, Options, ResolvedOptions, OpSet } from './core'; import { RoughGeneratorAsync } from './generator-async'; import { Point } from './geometry'; -export declare class RoughSVGAsync extends RoughSVG { +import { RoughSVGBase } from './svg-base'; +export declare class RoughSVGAsync extends RoughSVGBase { private genAsync; constructor(svg: SVGSVGElement, config?: Config); readonly generator: RoughGeneratorAsync; + getDefaultOptions(): ResolvedOptions; + opsToPath(drawing: OpSet): string; line(x1: number, y1: number, x2: number, y2: number, options?: Options): Promise; rectangle(x: number, y: number, width: number, height: number, options?: Options): Promise; ellipse(x: number, y: number, width: number, height: number, options?: Options): Promise; diff --git a/bin/svg-async.js b/bin/svg-async.js index 666cde8..543785c 100644 --- a/bin/svg-async.js +++ b/bin/svg-async.js @@ -1,55 +1,51 @@ -import { RoughSVG } from './svg'; import { RoughGeneratorAsync } from './generator-async'; -export class RoughSVGAsync extends RoughSVG { +import { RoughSVGBase } from './svg-base'; +export class RoughSVGAsync extends RoughSVGBase { constructor(svg, config) { - super(svg, config); + super(svg); this.genAsync = new RoughGeneratorAsync(config || null, this.svg); } - // @ts-ignore get generator() { return this.genAsync; } - // @ts-ignore + getDefaultOptions() { + return this.genAsync.defaultOptions; + } + opsToPath(drawing) { + return this.genAsync.opsToPath(drawing); + } async line(x1, y1, x2, y2, options) { const d = await this.genAsync.line(x1, y1, x2, y2, options); return this.draw(d); } - // @ts-ignore async rectangle(x, y, width, height, options) { const d = await this.genAsync.rectangle(x, y, width, height, options); return this.draw(d); } - // @ts-ignore async ellipse(x, y, width, height, options) { const d = await this.genAsync.ellipse(x, y, width, height, options); return this.draw(d); } - // @ts-ignore async circle(x, y, diameter, options) { const d = await this.genAsync.circle(x, y, diameter, options); return this.draw(d); } - // @ts-ignore async linearPath(points, options) { const d = await this.genAsync.linearPath(points, options); return this.draw(d); } - // @ts-ignore async polygon(points, options) { const d = await this.genAsync.polygon(points, options); return this.draw(d); } - // @ts-ignore async arc(x, y, width, height, start, stop, closed = false, options) { const d = await this.genAsync.arc(x, y, width, height, start, stop, closed, options); return this.draw(d); } - // @ts-ignore async curve(points, options) { const d = await this.genAsync.curve(points, options); return this.draw(d); } - // @ts-ignore async path(d, options) { const drawing = await this.genAsync.path(d, options); return this.draw(drawing); diff --git a/bin/svg-base.d.ts b/bin/svg-base.d.ts new file mode 100644 index 0000000..28e5bef --- /dev/null +++ b/bin/svg-base.d.ts @@ -0,0 +1,13 @@ +import { Drawable, OpSet, ResolvedOptions } from './core'; +import { RoughRenderer } from './renderer'; +export declare abstract class RoughSVGBase { + protected svg: SVGSVGElement; + protected _defs?: SVGDefsElement; + constructor(svg: SVGSVGElement); + abstract getDefaultOptions(): ResolvedOptions; + abstract opsToPath(drawing: OpSet): string; + static createRenderer(): RoughRenderer; + readonly defs: SVGDefsElement | null; + draw(drawable: Drawable): SVGGElement; + private fillSketch; +} diff --git a/bin/svg-base.js b/bin/svg-base.js new file mode 100644 index 0000000..741cb96 --- /dev/null +++ b/bin/svg-base.js @@ -0,0 +1,108 @@ +import { RoughRenderer } from './renderer'; +const hasDocument = typeof document !== 'undefined'; +export class RoughSVGBase { + constructor(svg) { + this.svg = svg; + } + static createRenderer() { + return new RoughRenderer(); + } + get defs() { + const doc = this.svg.ownerDocument || (hasDocument && document); + if (doc) { + if (!this._defs) { + const dnode = doc.createElementNS('http://www.w3.org/2000/svg', 'defs'); + if (this.svg.firstChild) { + this.svg.insertBefore(dnode, this.svg.firstChild); + } + else { + this.svg.appendChild(dnode); + } + this._defs = dnode; + } + } + return this._defs || null; + } + draw(drawable) { + const sets = drawable.sets || []; + const o = drawable.options || this.getDefaultOptions(); + const doc = this.svg.ownerDocument || (hasDocument && document); + const g = doc.createElementNS('http://www.w3.org/2000/svg', 'g'); + for (const drawing of sets) { + let path = null; + switch (drawing.type) { + case 'path': { + path = doc.createElementNS('http://www.w3.org/2000/svg', 'path'); + path.setAttribute('d', this.opsToPath(drawing)); + path.style.stroke = o.stroke; + path.style.strokeWidth = o.strokeWidth + ''; + path.style.fill = 'none'; + break; + } + case 'fillPath': { + path = doc.createElementNS('http://www.w3.org/2000/svg', 'path'); + path.setAttribute('d', this.opsToPath(drawing)); + path.style.stroke = 'none'; + path.style.strokeWidth = '0'; + path.style.fill = o.fill || null; + break; + } + case 'fillSketch': { + path = this.fillSketch(doc, drawing, o); + break; + } + case 'path2Dfill': { + path = doc.createElementNS('http://www.w3.org/2000/svg', 'path'); + path.setAttribute('d', drawing.path || ''); + path.style.stroke = 'none'; + path.style.strokeWidth = '0'; + path.style.fill = o.fill || null; + break; + } + case 'path2Dpattern': { + if (!this.defs) { + console.error('Cannot render path2Dpattern. No defs/document defined.'); + } + else { + const size = drawing.size; + const pattern = doc.createElementNS('http://www.w3.org/2000/svg', 'pattern'); + const id = `rough-${Math.floor(Math.random() * (Number.MAX_SAFE_INTEGER || 999999))}`; + pattern.setAttribute('id', id); + pattern.setAttribute('x', '0'); + pattern.setAttribute('y', '0'); + pattern.setAttribute('width', '1'); + pattern.setAttribute('height', '1'); + pattern.setAttribute('height', '1'); + pattern.setAttribute('viewBox', `0 0 ${Math.round(size[0])} ${Math.round(size[1])}`); + pattern.setAttribute('patternUnits', 'objectBoundingBox'); + const patternPath = this.fillSketch(doc, drawing, o); + pattern.appendChild(patternPath); + this.defs.appendChild(pattern); + path = doc.createElementNS('http://www.w3.org/2000/svg', 'path'); + path.setAttribute('d', drawing.path || ''); + path.style.stroke = 'none'; + path.style.strokeWidth = '0'; + path.style.fill = `url(#${id})`; + } + break; + } + } + if (path) { + g.appendChild(path); + } + } + return g; + } + fillSketch(doc, drawing, o) { + let fweight = o.fillWeight; + if (fweight < 0) { + fweight = o.strokeWidth / 2; + } + const path = doc.createElementNS('http://www.w3.org/2000/svg', 'path'); + path.setAttribute('d', this.opsToPath(drawing)); + path.style.stroke = o.fill || null; + path.style.strokeWidth = fweight + ''; + path.style.fill = 'none'; + return path; + } +} diff --git a/bin/svg.d.ts b/bin/svg.d.ts index 085f25f..43add01 100644 --- a/bin/svg.d.ts +++ b/bin/svg.d.ts @@ -1,15 +1,13 @@ -import { Config, Options, Drawable } from './core'; +import { Config, Options, OpSet, ResolvedOptions } from './core'; import { RoughGenerator } from './generator'; -import { RoughRenderer } from './renderer'; import { Point } from './geometry'; -export declare class RoughSVG { - protected svg: SVGSVGElement; +import { RoughSVGBase } from './svg-base'; +export declare class RoughSVG extends RoughSVGBase { private gen; - protected _defs?: SVGDefsElement; constructor(svg: SVGSVGElement, config?: Config); readonly generator: RoughGenerator; - static createRenderer(): RoughRenderer; - readonly defs: SVGDefsElement | null; + getDefaultOptions(): ResolvedOptions; + opsToPath(drawing: OpSet): string; line(x1: number, y1: number, x2: number, y2: number, options?: Options): SVGGElement; rectangle(x: number, y: number, width: number, height: number, options?: Options): SVGGElement; ellipse(x: number, y: number, width: number, height: number, options?: Options): SVGGElement; @@ -19,7 +17,4 @@ export declare class RoughSVG { arc(x: number, y: number, width: number, height: number, start: number, stop: number, closed?: boolean, options?: Options): SVGGElement; curve(points: Point[], options?: Options): SVGGElement; path(d: string, options?: Options): SVGGElement; - draw(drawable: Drawable): SVGGElement; - private opsToPath; - private fillSketch; } diff --git a/bin/svg.js b/bin/svg.js index b5a3f70..8c7dbc3 100644 --- a/bin/svg.js +++ b/bin/svg.js @@ -1,32 +1,18 @@ import { RoughGenerator } from './generator'; -import { RoughRenderer } from './renderer'; -const hasDocument = typeof document !== 'undefined'; -export class RoughSVG { +import { RoughSVGBase } from './svg-base'; +export class RoughSVG extends RoughSVGBase { constructor(svg, config) { - this.svg = svg; + super(svg); this.gen = new RoughGenerator(config || null, this.svg); } get generator() { return this.gen; } - static createRenderer() { - return new RoughRenderer(); + getDefaultOptions() { + return this.gen.defaultOptions; } - get defs() { - const doc = this.svg.ownerDocument || (hasDocument && document); - if (doc) { - if (!this._defs) { - const dnode = doc.createElementNS('http://www.w3.org/2000/svg', 'defs'); - if (this.svg.firstChild) { - this.svg.insertBefore(dnode, this.svg.firstChild); - } - else { - this.svg.appendChild(dnode); - } - this._defs = dnode; - } - } - return this._defs || null; + opsToPath(drawing) { + return this.gen.opsToPath(drawing); } line(x1, y1, x2, y2, options) { const d = this.gen.line(x1, y1, x2, y2, options); @@ -64,89 +50,4 @@ export class RoughSVG { const drawing = this.gen.path(d, options); return this.draw(drawing); } - draw(drawable) { - const sets = drawable.sets || []; - const o = drawable.options || this.gen.defaultOptions; - const doc = this.svg.ownerDocument || (hasDocument && document); - const g = doc.createElementNS('http://www.w3.org/2000/svg', 'g'); - for (const drawing of sets) { - let path = null; - switch (drawing.type) { - case 'path': { - path = doc.createElementNS('http://www.w3.org/2000/svg', 'path'); - path.setAttribute('d', this.opsToPath(drawing)); - path.style.stroke = o.stroke; - path.style.strokeWidth = o.strokeWidth + ''; - path.style.fill = 'none'; - break; - } - case 'fillPath': { - path = doc.createElementNS('http://www.w3.org/2000/svg', 'path'); - path.setAttribute('d', this.opsToPath(drawing)); - path.style.stroke = 'none'; - path.style.strokeWidth = '0'; - path.style.fill = o.fill || null; - break; - } - case 'fillSketch': { - path = this.fillSketch(doc, drawing, o); - break; - } - case 'path2Dfill': { - path = doc.createElementNS('http://www.w3.org/2000/svg', 'path'); - path.setAttribute('d', drawing.path || ''); - path.style.stroke = 'none'; - path.style.strokeWidth = '0'; - path.style.fill = o.fill || null; - break; - } - case 'path2Dpattern': { - if (!this.defs) { - console.error('Cannot render path2Dpattern. No defs/document defined.'); - } - else { - const size = drawing.size; - const pattern = doc.createElementNS('http://www.w3.org/2000/svg', 'pattern'); - const id = `rough-${Math.floor(Math.random() * (Number.MAX_SAFE_INTEGER || 999999))}`; - pattern.setAttribute('id', id); - pattern.setAttribute('x', '0'); - pattern.setAttribute('y', '0'); - pattern.setAttribute('width', '1'); - pattern.setAttribute('height', '1'); - pattern.setAttribute('height', '1'); - pattern.setAttribute('viewBox', `0 0 ${Math.round(size[0])} ${Math.round(size[1])}`); - pattern.setAttribute('patternUnits', 'objectBoundingBox'); - const patternPath = this.fillSketch(doc, drawing, o); - pattern.appendChild(patternPath); - this.defs.appendChild(pattern); - path = doc.createElementNS('http://www.w3.org/2000/svg', 'path'); - path.setAttribute('d', drawing.path || ''); - path.style.stroke = 'none'; - path.style.strokeWidth = '0'; - path.style.fill = `url(#${id})`; - } - break; - } - } - if (path) { - g.appendChild(path); - } - } - return g; - } - opsToPath(drawing) { - return this.gen.opsToPath(drawing); - } - fillSketch(doc, drawing, o) { - let fweight = o.fillWeight; - if (fweight < 0) { - fweight = o.strokeWidth / 2; - } - const path = doc.createElementNS('http://www.w3.org/2000/svg', 'path'); - path.setAttribute('d', this.opsToPath(drawing)); - path.style.stroke = o.fill || null; - path.style.strokeWidth = fweight + ''; - path.style.fill = 'none'; - return path; - } } diff --git a/dist/rough.es5.js b/dist/rough.es5.js index b0deb63..907d49d 100644 --- a/dist/rough.es5.js +++ b/dist/rough.es5.js @@ -1705,9 +1705,9 @@ var rough = (function () { } var hasSelf$1 = typeof self !== 'undefined'; - var RoughGenerator = function () { - function RoughGenerator(config, surface) { - classCallCheck(this, RoughGenerator); + var RoughGeneratorBase = function () { + function RoughGeneratorBase(config, surface) { + classCallCheck(this, RoughGeneratorBase); this.defaultOptions = { maxRandomnessOffset: 2, @@ -1730,7 +1730,7 @@ var rough = (function () { } } - createClass(RoughGenerator, [{ + createClass(RoughGeneratorBase, [{ key: '_options', value: function _options(options) { return options ? Object.assign({}, this.defaultOptions, options) : this.defaultOptions; @@ -1814,130 +1814,6 @@ var rough = (function () { } return size; } - }, { - key: 'line', - value: function line(x1, y1, x2, y2, options) { - var o = this._options(options); - return this._drawable('line', [this.lib.line(x1, y1, x2, y2, o)], o); - } - }, { - key: 'rectangle', - value: function rectangle(x, y, width, height, options) { - var o = this._options(options); - var paths = []; - if (o.fill) { - var points = [[x, y], [x + width, y], [x + width, y + height], [x, y + height]]; - if (o.fillStyle === 'solid') { - paths.push(this.lib.solidFillPolygon(points, o)); - } else { - paths.push(this.lib.patternFillPolygon(points, o)); - } - } - paths.push(this.lib.rectangle(x, y, width, height, o)); - return this._drawable('rectangle', paths, o); - } - }, { - key: 'ellipse', - value: function ellipse(x, y, width, height, options) { - var o = this._options(options); - var paths = []; - if (o.fill) { - if (o.fillStyle === 'solid') { - var shape = this.lib.ellipse(x, y, width, height, o); - shape.type = 'fillPath'; - paths.push(shape); - } else { - paths.push(this.lib.patternFillEllipse(x, y, width, height, o)); - } - } - paths.push(this.lib.ellipse(x, y, width, height, o)); - return this._drawable('ellipse', paths, o); - } - }, { - key: 'circle', - value: function circle(x, y, diameter, options) { - var ret = this.ellipse(x, y, diameter, diameter, options); - ret.shape = 'circle'; - return ret; - } - }, { - key: 'linearPath', - value: function linearPath(points, options) { - var o = this._options(options); - return this._drawable('linearPath', [this.lib.linearPath(points, false, o)], o); - } - }, { - key: 'arc', - value: function arc(x, y, width, height, start, stop) { - var closed = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false; - var options = arguments[7]; - - var o = this._options(options); - var paths = []; - if (closed && o.fill) { - if (o.fillStyle === 'solid') { - var shape = this.lib.arc(x, y, width, height, start, stop, true, false, o); - shape.type = 'fillPath'; - paths.push(shape); - } else { - paths.push(this.lib.patternFillArc(x, y, width, height, start, stop, o)); - } - } - paths.push(this.lib.arc(x, y, width, height, start, stop, closed, true, o)); - return this._drawable('arc', paths, o); - } - }, { - key: 'curve', - value: function curve(points, options) { - var o = this._options(options); - return this._drawable('curve', [this.lib.curve(points, o)], o); - } - }, { - key: 'polygon', - value: function polygon(points, options) { - var o = this._options(options); - var paths = []; - if (o.fill) { - if (o.fillStyle === 'solid') { - paths.push(this.lib.solidFillPolygon(points, o)); - } else { - var size = this.computePolygonSize(points); - var fillPoints = [[0, 0], [size[0], 0], [size[0], size[1]], [0, size[1]]]; - var shape = this.lib.patternFillPolygon(fillPoints, o); - shape.type = 'path2Dpattern'; - shape.size = size; - shape.path = this.polygonPath(points); - paths.push(shape); - } - } - paths.push(this.lib.linearPath(points, true, o)); - return this._drawable('polygon', paths, o); - } - }, { - key: 'path', - value: function path(d, options) { - var o = this._options(options); - var paths = []; - if (!d) { - return this._drawable('path', paths, o); - } - if (o.fill) { - if (o.fillStyle === 'solid') { - var shape = { type: 'path2Dfill', path: d, ops: [] }; - paths.push(shape); - } else { - var size = this.computePathSize(d); - var points = [[0, 0], [size[0], 0], [size[0], size[1]], [0, size[1]]]; - var _shape = this.lib.patternFillPolygon(points, o); - _shape.type = 'path2Dpattern'; - _shape.size = size; - _shape.path = d; - paths.push(_shape); - } - } - paths.push(this.lib.svgPath(d, o)); - return this._drawable('path', paths, o); - } }, { key: 'toPaths', value: function toPaths(drawable) { @@ -2085,60 +1961,68 @@ var rough = (function () { return this.renderer; } }]); - return RoughGenerator; + return RoughGeneratorBase; }(); - var hasDocument = typeof document !== 'undefined'; - var RoughCanvas = function () { - function RoughCanvas(canvas, config) { - classCallCheck(this, RoughCanvas); + var RoughGenerator = function (_RoughGeneratorBase) { + inherits(RoughGenerator, _RoughGeneratorBase); - this.canvas = canvas; - this.ctx = this.canvas.getContext('2d'); - this.gen = new RoughGenerator(config || null, this.canvas); + function RoughGenerator(config, surface) { + classCallCheck(this, RoughGenerator); + return possibleConstructorReturn(this, (RoughGenerator.__proto__ || Object.getPrototypeOf(RoughGenerator)).call(this, config, surface)); } - createClass(RoughCanvas, [{ + createClass(RoughGenerator, [{ key: 'line', value: function line(x1, y1, x2, y2, options) { - var d = this.gen.line(x1, y1, x2, y2, options); - this.draw(d); - return d; + var o = this._options(options); + return this._drawable('line', [this.lib.line(x1, y1, x2, y2, o)], o); } }, { key: 'rectangle', value: function rectangle(x, y, width, height, options) { - var d = this.gen.rectangle(x, y, width, height, options); - this.draw(d); - return d; + var o = this._options(options); + var paths = []; + if (o.fill) { + var points = [[x, y], [x + width, y], [x + width, y + height], [x, y + height]]; + if (o.fillStyle === 'solid') { + paths.push(this.lib.solidFillPolygon(points, o)); + } else { + paths.push(this.lib.patternFillPolygon(points, o)); + } + } + paths.push(this.lib.rectangle(x, y, width, height, o)); + return this._drawable('rectangle', paths, o); } }, { key: 'ellipse', value: function ellipse(x, y, width, height, options) { - var d = this.gen.ellipse(x, y, width, height, options); - this.draw(d); - return d; + var o = this._options(options); + var paths = []; + if (o.fill) { + if (o.fillStyle === 'solid') { + var shape = this.lib.ellipse(x, y, width, height, o); + shape.type = 'fillPath'; + paths.push(shape); + } else { + paths.push(this.lib.patternFillEllipse(x, y, width, height, o)); + } + } + paths.push(this.lib.ellipse(x, y, width, height, o)); + return this._drawable('ellipse', paths, o); } }, { key: 'circle', value: function circle(x, y, diameter, options) { - var d = this.gen.circle(x, y, diameter, options); - this.draw(d); - return d; + var ret = this.ellipse(x, y, diameter, diameter, options); + ret.shape = 'circle'; + return ret; } }, { key: 'linearPath', value: function linearPath(points, options) { - var d = this.gen.linearPath(points, options); - this.draw(d); - return d; - } - }, { - key: 'polygon', - value: function polygon(points, options) { - var d = this.gen.polygon(points, options); - this.draw(d); - return d; + var o = this._options(options); + return this._drawable('linearPath', [this.lib.linearPath(points, false, o)], o); } }, { key: 'arc', @@ -2146,29 +2030,90 @@ var rough = (function () { var closed = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false; var options = arguments[7]; - var d = this.gen.arc(x, y, width, height, start, stop, closed, options); - this.draw(d); - return d; + var o = this._options(options); + var paths = []; + if (closed && o.fill) { + if (o.fillStyle === 'solid') { + var shape = this.lib.arc(x, y, width, height, start, stop, true, false, o); + shape.type = 'fillPath'; + paths.push(shape); + } else { + paths.push(this.lib.patternFillArc(x, y, width, height, start, stop, o)); + } + } + paths.push(this.lib.arc(x, y, width, height, start, stop, closed, true, o)); + return this._drawable('arc', paths, o); } }, { key: 'curve', value: function curve(points, options) { - var d = this.gen.curve(points, options); - this.draw(d); - return d; + var o = this._options(options); + return this._drawable('curve', [this.lib.curve(points, o)], o); + } + }, { + key: 'polygon', + value: function polygon(points, options) { + var o = this._options(options); + var paths = []; + if (o.fill) { + if (o.fillStyle === 'solid') { + paths.push(this.lib.solidFillPolygon(points, o)); + } else { + var size = this.computePolygonSize(points); + var fillPoints = [[0, 0], [size[0], 0], [size[0], size[1]], [0, size[1]]]; + var shape = this.lib.patternFillPolygon(fillPoints, o); + shape.type = 'path2Dpattern'; + shape.size = size; + shape.path = this.polygonPath(points); + paths.push(shape); + } + } + paths.push(this.lib.linearPath(points, true, o)); + return this._drawable('polygon', paths, o); } }, { key: 'path', value: function path(d, options) { - var drawing = this.gen.path(d, options); - this.draw(drawing); - return drawing; + var o = this._options(options); + var paths = []; + if (!d) { + return this._drawable('path', paths, o); + } + if (o.fill) { + if (o.fillStyle === 'solid') { + var shape = { type: 'path2Dfill', path: d, ops: [] }; + paths.push(shape); + } else { + var size = this.computePathSize(d); + var points = [[0, 0], [size[0], 0], [size[0], size[1]], [0, size[1]]]; + var _shape = this.lib.patternFillPolygon(points, o); + _shape.type = 'path2Dpattern'; + _shape.size = size; + _shape.path = d; + paths.push(_shape); + } + } + paths.push(this.lib.svgPath(d, o)); + return this._drawable('path', paths, o); } - }, { + }]); + return RoughGenerator; + }(RoughGeneratorBase); + + var hasDocument = typeof document !== 'undefined'; + var RoughCanvasBase = function () { + function RoughCanvasBase(canvas) { + classCallCheck(this, RoughCanvasBase); + + this.canvas = canvas; + this.ctx = this.canvas.getContext('2d'); + } + + createClass(RoughCanvasBase, [{ key: 'draw', value: function draw(drawable) { var sets = drawable.sets || []; - var o = drawable.options || this.gen.defaultOptions; + var o = drawable.options || this.getDefaultOptions(); var ctx = this.ctx; var _iteratorNormalCompletion = true; var _didIteratorError = false; @@ -2282,70 +2227,157 @@ var rough = (function () { ctx.restore(); } }, { - key: '_drawToContext', - value: function _drawToContext(ctx, drawing) { - ctx.beginPath(); - var _iteratorNormalCompletion2 = true; - var _didIteratorError2 = false; - var _iteratorError2 = undefined; - - try { - for (var _iterator2 = drawing.ops[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { - var item = _step2.value; - - var data = item.data; - switch (item.op) { - case 'move': - ctx.moveTo(data[0], data[1]); - break; - case 'bcurveTo': - ctx.bezierCurveTo(data[0], data[1], data[2], data[3], data[4], data[5]); - break; - case 'qcurveTo': - ctx.quadraticCurveTo(data[0], data[1], data[2], data[3]); - break; - case 'lineTo': - ctx.lineTo(data[0], data[1]); - break; - } - } - } catch (err) { - _didIteratorError2 = true; - _iteratorError2 = err; - } finally { - try { - if (!_iteratorNormalCompletion2 && _iterator2.return) { - _iterator2.return(); - } - } finally { - if (_didIteratorError2) { - throw _iteratorError2; - } - } - } - - if (drawing.type === 'fillPath') { - ctx.fill(); - } else { - ctx.stroke(); - } + key: '_drawToContext', + value: function _drawToContext(ctx, drawing) { + ctx.beginPath(); + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = drawing.ops[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var item = _step2.value; + + var data = item.data; + switch (item.op) { + case 'move': + ctx.moveTo(data[0], data[1]); + break; + case 'bcurveTo': + ctx.bezierCurveTo(data[0], data[1], data[2], data[3], data[4], data[5]); + break; + case 'qcurveTo': + ctx.quadraticCurveTo(data[0], data[1], data[2], data[3]); + break; + case 'lineTo': + ctx.lineTo(data[0], data[1]); + break; + } + } + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2.return) { + _iterator2.return(); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } + + if (drawing.type === 'fillPath') { + ctx.fill(); + } else { + ctx.stroke(); + } + } + }], [{ + key: 'createRenderer', + value: function createRenderer() { + return new RoughRenderer(); + } + }]); + return RoughCanvasBase; + }(); + + var RoughCanvas = function (_RoughCanvasBase) { + inherits(RoughCanvas, _RoughCanvasBase); + + function RoughCanvas(canvas, config) { + classCallCheck(this, RoughCanvas); + + var _this = possibleConstructorReturn(this, (RoughCanvas.__proto__ || Object.getPrototypeOf(RoughCanvas)).call(this, canvas)); + + _this.gen = new RoughGenerator(config || null, _this.canvas); + return _this; + } + + createClass(RoughCanvas, [{ + key: 'getDefaultOptions', + value: function getDefaultOptions() { + return this.gen.defaultOptions; + } + }, { + key: 'line', + value: function line(x1, y1, x2, y2, options) { + var d = this.gen.line(x1, y1, x2, y2, options); + this.draw(d); + return d; + } + }, { + key: 'rectangle', + value: function rectangle(x, y, width, height, options) { + var d = this.gen.rectangle(x, y, width, height, options); + this.draw(d); + return d; + } + }, { + key: 'ellipse', + value: function ellipse(x, y, width, height, options) { + var d = this.gen.ellipse(x, y, width, height, options); + this.draw(d); + return d; + } + }, { + key: 'circle', + value: function circle(x, y, diameter, options) { + var d = this.gen.circle(x, y, diameter, options); + this.draw(d); + return d; + } + }, { + key: 'linearPath', + value: function linearPath(points, options) { + var d = this.gen.linearPath(points, options); + this.draw(d); + return d; + } + }, { + key: 'polygon', + value: function polygon(points, options) { + var d = this.gen.polygon(points, options); + this.draw(d); + return d; + } + }, { + key: 'arc', + value: function arc(x, y, width, height, start, stop) { + var closed = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false; + var options = arguments[7]; + + var d = this.gen.arc(x, y, width, height, start, stop, closed, options); + this.draw(d); + return d; + } + }, { + key: 'curve', + value: function curve(points, options) { + var d = this.gen.curve(points, options); + this.draw(d); + return d; + } + }, { + key: 'path', + value: function path(d, options) { + var drawing = this.gen.path(d, options); + this.draw(drawing); + return drawing; } }, { key: 'generator', get: function get$$1() { return this.gen; } - }], [{ - key: 'createRenderer', - value: function createRenderer() { - return new RoughRenderer(); - } }]); return RoughCanvas; - }(); + }(RoughCanvasBase); - var RoughGeneratorAsync = function (_RoughGenerator) { - inherits(RoughGeneratorAsync, _RoughGenerator); + var RoughGeneratorAsync = function (_RoughGeneratorBase) { + inherits(RoughGeneratorAsync, _RoughGeneratorBase); function RoughGeneratorAsync() { classCallCheck(this, RoughGeneratorAsync); @@ -2354,14 +2386,10 @@ var rough = (function () { createClass(RoughGeneratorAsync, [{ key: 'line', - - // @ts-ignore value: async function line(x1, y1, x2, y2, options) { var o = this._options(options); return this._drawable('line', [await this.lib.line(x1, y1, x2, y2, o)], o); } - // @ts-ignore - }, { key: 'rectangle', value: async function rectangle(x, y, width, height, options) { @@ -2378,8 +2406,6 @@ var rough = (function () { paths.push((await this.lib.rectangle(x, y, width, height, o))); return this._drawable('rectangle', paths, o); } - // @ts-ignore - }, { key: 'ellipse', value: async function ellipse(x, y, width, height, options) { @@ -2397,8 +2423,6 @@ var rough = (function () { paths.push((await this.lib.ellipse(x, y, width, height, o))); return this._drawable('ellipse', paths, o); } - // @ts-ignore - }, { key: 'circle', value: async function circle(x, y, diameter, options) { @@ -2406,16 +2430,12 @@ var rough = (function () { ret.shape = 'circle'; return ret; } - // @ts-ignore - }, { key: 'linearPath', value: async function linearPath(points, options) { var o = this._options(options); return this._drawable('linearPath', [await this.lib.linearPath(points, false, o)], o); } - // @ts-ignore - }, { key: 'arc', value: async function arc(x, y, width, height, start, stop) { @@ -2436,16 +2456,12 @@ var rough = (function () { paths.push((await this.lib.arc(x, y, width, height, start, stop, closed, true, o))); return this._drawable('arc', paths, o); } - // @ts-ignore - }, { key: 'curve', value: async function curve(points, options) { var o = this._options(options); return this._drawable('curve', [await this.lib.curve(points, o)], o); } - // @ts-ignore - }, { key: 'polygon', value: async function polygon(points, options) { @@ -2467,8 +2483,6 @@ var rough = (function () { paths.push((await this.lib.linearPath(points, true, o))); return this._drawable('polygon', paths, o); } - // @ts-ignore - }, { key: 'path', value: async function path(d, options) { @@ -2496,33 +2510,32 @@ var rough = (function () { } }]); return RoughGeneratorAsync; - }(RoughGenerator); + }(RoughGeneratorBase); - var RoughCanvasAsync = function (_RoughCanvas) { - inherits(RoughCanvasAsync, _RoughCanvas); + var RoughCanvasAsync = function (_RoughCanvasBase) { + inherits(RoughCanvasAsync, _RoughCanvasBase); function RoughCanvasAsync(canvas, config) { classCallCheck(this, RoughCanvasAsync); - var _this = possibleConstructorReturn(this, (RoughCanvasAsync.__proto__ || Object.getPrototypeOf(RoughCanvasAsync)).call(this, canvas, config)); + var _this = possibleConstructorReturn(this, (RoughCanvasAsync.__proto__ || Object.getPrototypeOf(RoughCanvasAsync)).call(this, canvas)); _this.genAsync = new RoughGeneratorAsync(config || null, _this.canvas); return _this; } - // @ts-ignore - createClass(RoughCanvasAsync, [{ + key: 'getDefaultOptions', + value: function getDefaultOptions() { + return this.genAsync.defaultOptions; + } + }, { key: 'line', - - // @ts-ignore value: async function line(x1, y1, x2, y2, options) { var d = await this.genAsync.line(x1, y1, x2, y2, options); this.draw(d); return d; } - // @ts-ignore - }, { key: 'rectangle', value: async function rectangle(x, y, width, height, options) { @@ -2530,8 +2543,6 @@ var rough = (function () { this.draw(d); return d; } - // @ts-ignore - }, { key: 'ellipse', value: async function ellipse(x, y, width, height, options) { @@ -2539,8 +2550,6 @@ var rough = (function () { this.draw(d); return d; } - // @ts-ignore - }, { key: 'circle', value: async function circle(x, y, diameter, options) { @@ -2548,8 +2557,6 @@ var rough = (function () { this.draw(d); return d; } - // @ts-ignore - }, { key: 'linearPath', value: async function linearPath(points, options) { @@ -2557,8 +2564,6 @@ var rough = (function () { this.draw(d); return d; } - // @ts-ignore - }, { key: 'polygon', value: async function polygon(points, options) { @@ -2566,8 +2571,6 @@ var rough = (function () { this.draw(d); return d; } - // @ts-ignore - }, { key: 'arc', value: async function arc(x, y, width, height, start, stop) { @@ -2578,8 +2581,6 @@ var rough = (function () { this.draw(d); return d; } - // @ts-ignore - }, { key: 'curve', value: async function curve(points, options) { @@ -2587,8 +2588,6 @@ var rough = (function () { this.draw(d); return d; } - // @ts-ignore - }, { key: 'path', value: async function path(d, options) { @@ -2603,79 +2602,21 @@ var rough = (function () { } }]); return RoughCanvasAsync; - }(RoughCanvas); + }(RoughCanvasBase); var hasDocument$1 = typeof document !== 'undefined'; - var RoughSVG = function () { - function RoughSVG(svg, config) { - classCallCheck(this, RoughSVG); + var RoughSVGBase = function () { + function RoughSVGBase(svg) { + classCallCheck(this, RoughSVGBase); this.svg = svg; - this.gen = new RoughGenerator(config || null, this.svg); } - createClass(RoughSVG, [{ - key: 'line', - value: function line(x1, y1, x2, y2, options) { - var d = this.gen.line(x1, y1, x2, y2, options); - return this.draw(d); - } - }, { - key: 'rectangle', - value: function rectangle(x, y, width, height, options) { - var d = this.gen.rectangle(x, y, width, height, options); - return this.draw(d); - } - }, { - key: 'ellipse', - value: function ellipse(x, y, width, height, options) { - var d = this.gen.ellipse(x, y, width, height, options); - return this.draw(d); - } - }, { - key: 'circle', - value: function circle(x, y, diameter, options) { - var d = this.gen.circle(x, y, diameter, options); - return this.draw(d); - } - }, { - key: 'linearPath', - value: function linearPath(points, options) { - var d = this.gen.linearPath(points, options); - return this.draw(d); - } - }, { - key: 'polygon', - value: function polygon(points, options) { - var d = this.gen.polygon(points, options); - return this.draw(d); - } - }, { - key: 'arc', - value: function arc(x, y, width, height, start, stop) { - var closed = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false; - var options = arguments[7]; - - var d = this.gen.arc(x, y, width, height, start, stop, closed, options); - return this.draw(d); - } - }, { - key: 'curve', - value: function curve(points, options) { - var d = this.gen.curve(points, options); - return this.draw(d); - } - }, { - key: 'path', - value: function path(d, options) { - var drawing = this.gen.path(d, options); - return this.draw(drawing); - } - }, { + createClass(RoughSVGBase, [{ key: 'draw', value: function draw(drawable) { var sets = drawable.sets || []; - var o = drawable.options || this.gen.defaultOptions; + var o = drawable.options || this.getDefaultOptions(); var doc = this.svg.ownerDocument || hasDocument$1 && document; var g = doc.createElementNS('http://www.w3.org/2000/svg', 'g'); var _iteratorNormalCompletion = true; @@ -2769,11 +2710,6 @@ var rough = (function () { return g; } - }, { - key: 'opsToPath', - value: function opsToPath(drawing) { - return this.gen.opsToPath(drawing); - } }, { key: 'fillSketch', value: function fillSketch(doc, drawing, o) { @@ -2788,11 +2724,6 @@ var rough = (function () { path.style.fill = 'none'; return path; } - }, { - key: 'generator', - get: function get$$1() { - return this.gen; - } }, { key: 'defs', get: function get$$1() { @@ -2816,73 +2747,155 @@ var rough = (function () { return new RoughRenderer(); } }]); - return RoughSVG; + return RoughSVGBase; }(); - var RoughSVGAsync = function (_RoughSVG) { - inherits(RoughSVGAsync, _RoughSVG); + var RoughSVG = function (_RoughSVGBase) { + inherits(RoughSVG, _RoughSVGBase); + + function RoughSVG(svg, config) { + classCallCheck(this, RoughSVG); + + var _this = possibleConstructorReturn(this, (RoughSVG.__proto__ || Object.getPrototypeOf(RoughSVG)).call(this, svg)); + + _this.gen = new RoughGenerator(config || null, _this.svg); + return _this; + } + + createClass(RoughSVG, [{ + key: 'getDefaultOptions', + value: function getDefaultOptions() { + return this.gen.defaultOptions; + } + }, { + key: 'opsToPath', + value: function opsToPath(drawing) { + return this.gen.opsToPath(drawing); + } + }, { + key: 'line', + value: function line(x1, y1, x2, y2, options) { + var d = this.gen.line(x1, y1, x2, y2, options); + return this.draw(d); + } + }, { + key: 'rectangle', + value: function rectangle(x, y, width, height, options) { + var d = this.gen.rectangle(x, y, width, height, options); + return this.draw(d); + } + }, { + key: 'ellipse', + value: function ellipse(x, y, width, height, options) { + var d = this.gen.ellipse(x, y, width, height, options); + return this.draw(d); + } + }, { + key: 'circle', + value: function circle(x, y, diameter, options) { + var d = this.gen.circle(x, y, diameter, options); + return this.draw(d); + } + }, { + key: 'linearPath', + value: function linearPath(points, options) { + var d = this.gen.linearPath(points, options); + return this.draw(d); + } + }, { + key: 'polygon', + value: function polygon(points, options) { + var d = this.gen.polygon(points, options); + return this.draw(d); + } + }, { + key: 'arc', + value: function arc(x, y, width, height, start, stop) { + var closed = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false; + var options = arguments[7]; + + var d = this.gen.arc(x, y, width, height, start, stop, closed, options); + return this.draw(d); + } + }, { + key: 'curve', + value: function curve(points, options) { + var d = this.gen.curve(points, options); + return this.draw(d); + } + }, { + key: 'path', + value: function path(d, options) { + var drawing = this.gen.path(d, options); + return this.draw(drawing); + } + }, { + key: 'generator', + get: function get$$1() { + return this.gen; + } + }]); + return RoughSVG; + }(RoughSVGBase); + + var RoughSVGAsync = function (_RoughSVGBase) { + inherits(RoughSVGAsync, _RoughSVGBase); function RoughSVGAsync(svg, config) { classCallCheck(this, RoughSVGAsync); - var _this = possibleConstructorReturn(this, (RoughSVGAsync.__proto__ || Object.getPrototypeOf(RoughSVGAsync)).call(this, svg, config)); + var _this = possibleConstructorReturn(this, (RoughSVGAsync.__proto__ || Object.getPrototypeOf(RoughSVGAsync)).call(this, svg)); _this.genAsync = new RoughGeneratorAsync(config || null, _this.svg); return _this; } - // @ts-ignore - createClass(RoughSVGAsync, [{ + key: 'getDefaultOptions', + value: function getDefaultOptions() { + return this.genAsync.defaultOptions; + } + }, { + key: 'opsToPath', + value: function opsToPath(drawing) { + return this.genAsync.opsToPath(drawing); + } + }, { key: 'line', - - // @ts-ignore value: async function line(x1, y1, x2, y2, options) { var d = await this.genAsync.line(x1, y1, x2, y2, options); return this.draw(d); } - // @ts-ignore - }, { key: 'rectangle', value: async function rectangle(x, y, width, height, options) { var d = await this.genAsync.rectangle(x, y, width, height, options); return this.draw(d); } - // @ts-ignore - }, { key: 'ellipse', value: async function ellipse(x, y, width, height, options) { var d = await this.genAsync.ellipse(x, y, width, height, options); return this.draw(d); } - // @ts-ignore - }, { key: 'circle', value: async function circle(x, y, diameter, options) { var d = await this.genAsync.circle(x, y, diameter, options); return this.draw(d); } - // @ts-ignore - }, { key: 'linearPath', value: async function linearPath(points, options) { var d = await this.genAsync.linearPath(points, options); return this.draw(d); } - // @ts-ignore - }, { key: 'polygon', value: async function polygon(points, options) { var d = await this.genAsync.polygon(points, options); return this.draw(d); } - // @ts-ignore - }, { key: 'arc', value: async function arc(x, y, width, height, start, stop) { @@ -2892,16 +2905,12 @@ var rough = (function () { var d = await this.genAsync.arc(x, y, width, height, start, stop, closed, options); return this.draw(d); } - // @ts-ignore - }, { key: 'curve', value: async function curve(points, options) { var d = await this.genAsync.curve(points, options); return this.draw(d); } - // @ts-ignore - }, { key: 'path', value: async function path(d, options) { @@ -2915,7 +2924,7 @@ var rough = (function () { } }]); return RoughSVGAsync; - }(RoughSVG); + }(RoughSVGBase); var rough = { canvas: function canvas(_canvas, config) { diff --git a/dist/rough.es5.min.js b/dist/rough.es5.min.js index c74dd5d..9003fc6 100644 --- a/dist/rough.es5.min.js +++ b/dist/rough.es5.min.js @@ -1 +1 @@ -var rough=function(){"use strict";function e(e,t){return e.type===t}function t(e){var t=e[0],l=e[1];return y(f(t[0]-l[0],2)+f(t[1]-l[1],2))}function l(e,t){for(var l,a=[],n=new z([e[0],e[1]],[e[2],e[3]]),s=0;sg&&(g=4*t.strokeWidth),g=d(g,.1);for(var y=h%180*(c/180),k=v(y),x=_(y),b=p(y),m=new E(o-1,r+1,n-1,s+1,g,x,k,b),w=void 0;null!=(w=m.nextLine());)for(var P=l(w,e),O=0;O=f&&(f=4*i.strokeWidth);var h=i.fillWeight;0>h&&(h=i.strokeWidth/2);for(var g=p(u%180*(c/180)),v=d/r,_=y(v*g*v*g+1),x=v*g/_,b=1/_,m=f/(r*d/y(d*b*(d*b)+r*x*(r*x))/r),w=y(r*r-(e-r+m)*(e-r+m)),P=e-r+m;Pf){var h=y(1-f/(this._rx*this._rx*this._ry*this._ry));this._rx*=h,this._ry*=h,u=0}else u=(i===o?-1:1)*y(f/(this._rx*this._rx*d*d+this._ry*this._ry*p*p));var s=u*this._rx*d/this._ry,x=-u*this._ry*p/this._rx;this._C=[0,0],this._C[0]=this._cosPhi*s-this._sinPhi*x+(t[0]+l[0])/2,this._C[1]=this._sinPhi*s+this._cosPhi*x+(t[1]+l[1])/2,this._theta=this.calculateVectorAngle(1,0,(p-s)/this._rx,(d-x)/this._ry);var m=this.calculateVectorAngle((p-s)/this._rx,(d-x)/this._ry,(-p-s)/this._rx,(-d-x)/this._ry);!o&&0m&&(m+=2*c),this._numSegs=g(k(m/(c/2))),this._delta=m/this._numSegs,this._T=8/3*_(this._delta/4)*_(this._delta/4)/_(this._delta/2)}}return m(e,[{key:"getNextSegment",value:function(){if(this._segIndex===this._numSegs)return null;var e=v(this._theta),t=_(this._theta),l=this._theta+this._delta,a=v(l),n=_(l),i=[this._cosPhi*this._rx*a-this._sinPhi*this._ry*n+this._C[0],this._sinPhi*this._rx*a+this._cosPhi*this._ry*n+this._C[1]],s=[this._from[0]+this._T*(-this._cosPhi*this._rx*t-this._sinPhi*this._ry*e),this._from[1]+this._T*(-this._sinPhi*this._rx*t+this._cosPhi*this._ry*e)],o=[i[0]+this._T*(this._cosPhi*this._rx*n+this._sinPhi*this._ry*a),i[1]+this._T*(this._sinPhi*this._rx*n-this._cosPhi*this._ry*a)];return this._theta=l,this._from=[i[0],i[1]],this._segIndex++,{cp1:s,cp2:o,to:i}}},{key:"calculateVectorAngle",value:function(e,t,l,a){var n=Math.atan2,i=n(t,e),s=n(a,l);return s>=i?s-i:2*c-(i-s)}}]),e}(),C=function(){function e(t,l){b(this,e),this.sets=t,this.closed=l}return m(e,[{key:"fit",value:function(e){var t=[],l=!0,a=!1,n=void 0;try{for(var s,o=this.sets[Symbol.iterator]();!(l=(s=o.next()).done);l=!0){var r=s.value,p=r.length,u=h(e*p);if(5>u){if(5>=p)continue;u=5}t.push(this.reduce(r,u))}}catch(e){a=!0,n=e}finally{try{!l&&o.return&&o.return()}finally{if(a)throw n}}var f="",g=!0,y=!1,c=void 0;try{for(var v,_,k=t[Symbol.iterator]();!(g=(v=k.next()).done);g=!0){_=v.value;for(var x,b=0;b<_.length;b++)x=_[b],f+=0===b?"M"+x[0]+","+x[1]:"L"+x[0]+","+x[1];this.closed&&(f+="z ")}}catch(e){y=!0,c=e}finally{try{!g&&k.return&&k.return()}finally{if(y)throw c}}return f}},{key:"distance",value:function(e,t){return y(f(e[0]-t[0],2)+f(e[1]-t[1],2))}},{key:"reduce",value:function(e,t){if(e.length<=t)return e;for(var l=e.slice(0);l.length>t;){for(var n=-1,o=-1,r=1;rn||s=u(e.py1,e.py2)&&this.py1<=d(e.py1,e.py2)?(this.xi=this.px1,this.yi=this.py1,!0):!!(this.py2>=u(e.py1,e.py2)&&this.py2<=d(e.py1,e.py2))&&(this.xi=this.px2,this.yi=this.py2,!0)):(this.xi=this.px1,this.yi=n*this.xi+s,!(-1e-5>(this.py1-this.yi)*(this.yi-this.py2)||-1e-5>(e.py1-this.yi)*(this.yi-e.py2))&&(!(1e-5>k(e.a))||!(-1e-5>(e.px1-this.xi)*(this.xi-e.px2)))):n===t?(this.xi=e.px1,this.yi=l*this.xi+i,!(-1e-5>(e.py1-this.yi)*(this.yi-e.py2)||-1e-5>(this.py1-this.yi)*(this.yi-this.py2))&&(!(1e-5>k(o))||!(-1e-5>(this.px1-this.xi)*(this.xi-this.px2)))):l===n?i==s&&(this.px1>=u(e.px1,e.px2)&&this.px1<=d(e.py1,e.py2)?(this.xi=this.px1,this.yi=this.py1,!0):!!(this.px2>=u(e.px1,e.px2)&&this.px2<=d(e.px1,e.px2))&&(this.xi=this.px2,this.yi=this.py2,!0)):(this.xi=(s-i)/(l-n),this.yi=l*this.xi+i,!(-1e-5>(this.px1-this.xi)*(this.xi-this.px2)||-1e-5>(e.px1-this.xi)*(this.xi-e.px2)))}}]),e}(),E=function(){function e(t,l,a,n,i,s,o,r){b(this,e),this.deltaX=0,this.hGap=0,this.top=t,this.bottom=l,this.left=a,this.right=n,this.gap=i,this.sinAngle=s,this.tanAngle=r,1e-4>k(s)?this.pos=a+i:.9999k(this.sinAngle)){if(this.posthis.right&&l>this.right;)if(this.pos+=this.hGap,t=this.pos-this.deltaX/2,l=this.pos+this.deltaX/2,this.pos>this.right+this.deltaX)return null;var i=new z([t,a],[l,n]);this.sLeft&&i.intersects(this.sLeft)&&(t=i.xi,a=i.yi),this.sRight&&i.intersects(this.sRight)&&(l=i.xi,n=i.yi),0s&&(s=4*a.strokeWidth),s=d(s,.1);var o=a.fillWeight;0>o&&(o=a.strokeWidth/2);var r=!0,p=!1,u=void 0;try{for(var f,h=e[Symbol.iterator]();!(r=(f=h.next()).done);r=!0)for(var y=f.value,k=t(y),x=k/s,b=g(x)-1,m=Math.atan((y[1][1]-y[0][1])/(y[1][0]-y[0][0])),w=0;wg;)g+=2*c,y+=2*c;y-g>2*c&&(g=0,y=2*c);var x=2*c/p.curveStepCount,b=u(x/2,(y-g)/2),m=this._arc(b,o,d,f,h,g,y,1,p),w=this._arc(b,o,d,f,h,g,y,1.5,p),P=m.concat(w);return s&&(r?(P=P.concat(this.doubleLine(o,d,o+f*v(g),d+h*_(g),p)),P=P.concat(this.doubleLine(o,d,o+f*v(y),d+h*_(y),p))):(P.push({op:"lineTo",data:[o,d]}),P.push({op:"lineTo",data:[o+f*v(g),d+h*_(g)]}))),{type:"path",ops:P}}},{key:"svgPath",value:function(e,t){e=(e||"").replace(/\n/g," ").replace(/(-\s)/g,"-").replace("/(ss)/g"," ");var l=new A(e);if(t.simplification){var a=new C(l.linearPoints,l.closed),n=a.fit(t.simplification);l=new A(n)}for(var o=[],r=l.segments||[],d=0;du;)u+=2*c,f+=2*c;f-u>2*c&&(u=0,f=2*c);for(var h=(f-u)/s.curveStepCount,g=[],y=u;y<=f;y+=h)g.push([o+p*v(y),r+d*_(y)]);return g.push([o+p*v(f),r+d*_(f)]),g.push([o,r]),this.patternFillPolygon(g,s)}},{key:"getOffset",value:function(e,t,l){return l.roughness*(Math.random()*(t-e)+e)}},{key:"doubleLine",value:function(e,t,l,a,n){var i=this._line(e,t,l,a,n,!0,!1),s=this._line(e,t,l,a,n,!0,!0);return i.concat(s)}},{key:"_line",value:function(e,t,l,a,n,i,s){var o=f(e-l,2)+f(t-a,2),r=n.maxRandomnessOffset||0;100*(r*r)>o&&(r=y(o)/10);var p=r/2,d=.2+.2*Math.random(),u=n.bowing*n.maxRandomnessOffset*(a-t)/200,h=n.bowing*n.maxRandomnessOffset*(e-l)/200;u=this.getOffset(-u,u,n),h=this.getOffset(-h,h,n);var g=[];return i&&(s?g.push({op:"move",data:[e+this.getOffset(-p,p,n),t+this.getOffset(-p,p,n)]}):g.push({op:"move",data:[e+this.getOffset(-r,r,n),t+this.getOffset(-r,r,n)]})),s?g.push({op:"bcurveTo",data:[u+e+(l-e)*d+this.getOffset(-p,p,n),h+t+(a-t)*d+this.getOffset(-p,p,n),u+e+2*(l-e)*d+this.getOffset(-p,p,n),h+t+2*(a-t)*d+this.getOffset(-p,p,n),l+this.getOffset(-p,p,n),a+this.getOffset(-p,p,n)]}):g.push({op:"bcurveTo",data:[u+e+(l-e)*d+this.getOffset(-r,r,n),h+t+(a-t)*d+this.getOffset(-r,r,n),u+e+2*(l-e)*d+this.getOffset(-r,r,n),h+t+2*(a-t)*d+this.getOffset(-r,r,n),l+this.getOffset(-r,r,n),a+this.getOffset(-r,r,n)]}),g}},{key:"_curve",value:function(e,t,l){var a=e.length,n=[];if(3h;h++)0===h?o.push({op:"move",data:[r.x,r.y]}):o.push({op:"move",data:[r.x+this.getOffset(-d[0],d[0],p),r.y+this.getOffset(-d[0],d[0],p)]}),u=[n+this.getOffset(-d[h],d[h],p),s+this.getOffset(-d[h],d[h],p)],o.push({op:"bcurveTo",data:[e+this.getOffset(-d[h],d[h],p),t+this.getOffset(-d[h],d[h],p),l+this.getOffset(-d[h],d[h],p),a+this.getOffset(-d[h],d[h],p),u[0],u[1]]});return r.setPosition(u[0],u[1]),o}},{key:"_processSegment",value:function(e,t,l,a){var n=[];switch(t.key){case"M":case"m":{var s="m"===t.key;if(2<=t.data.length){var o=+t.data[0],r=+t.data[1];s&&(o+=e.x,r+=e.y);var p=1*(a.maxRandomnessOffset||0);o+=this.getOffset(-p,p,a),r+=this.getOffset(-p,p,a),e.setPosition(o,r),n.push({op:"move",data:[o,r]})}break}case"L":case"l":{var d="l"===t.key;if(2<=t.data.length){var u=+t.data[0],h=+t.data[1];d&&(u+=e.x,h+=e.y),n=n.concat(this.doubleLine(e.x,e.y,u,h,a)),e.setPosition(u,h)}break}case"H":case"h":{var g="h"===t.key;if(t.data.length){var c=+t.data[0];g&&(c+=e.x),n=n.concat(this.doubleLine(e.x,e.y,c,e.y,a)),e.setPosition(c,e.y)}break}case"V":case"v":{var v="v"===t.key;if(t.data.length){var _=+t.data[0];v&&(_+=e.y),n=n.concat(this.doubleLine(e.x,e.y,e.x,_,a)),e.setPosition(e.x,_)}break}case"Z":case"z":{e.first&&(n=n.concat(this.doubleLine(e.x,e.y,e.first[0],e.first[1],a)),e.setPosition(e.first[0],e.first[1]),e.first=null);break}case"C":case"c":{var k="c"===t.key;if(6<=t.data.length){var b=+t.data[0],m=+t.data[1],w=+t.data[2],P=+t.data[3],O=+t.data[4],S=+t.data[5];k&&(b+=e.x,w+=e.x,O+=e.x,m+=e.y,P+=e.y,S+=e.y);var A=this._bezierTo(b,m,w,P,O,S,e,a);n=n.concat(A),e.bezierReflectionPoint=[O+(O-w),S+(S-P)]}break}case"S":case"s":{var C="s"===t.key;if(4<=t.data.length){var z=+t.data[0],E=+t.data[1],L=+t.data[2],W=+t.data[3];C&&(z+=e.x,L+=e.x,E+=e.y,W+=e.y);var N=z,R=E,D=l?l.key:"",B=null;("c"===D||"C"===D||"s"===D||"S"===D)&&(B=e.bezierReflectionPoint),B&&(N=B[0],R=B[1]);var F=this._bezierTo(N,R,z,E,L,W,e,a);n=n.concat(F),e.bezierReflectionPoint=[L+(L-z),W+(W-E)]}break}case"Q":case"q":{var M="q"===t.key;if(4<=t.data.length){var q=+t.data[0],U=+t.data[1],X=+t.data[2],V=+t.data[3];M&&(q+=e.x,X+=e.x,U+=e.y,V+=e.y);var G=1*(1+.2*a.roughness),j=1.5*(1+.22*a.roughness);n.push({op:"move",data:[e.x+this.getOffset(-G,G,a),e.y+this.getOffset(-G,G,a)]});var I=[X+this.getOffset(-G,G,a),V+this.getOffset(-G,G,a)];n.push({op:"qcurveTo",data:[q+this.getOffset(-G,G,a),U+this.getOffset(-G,G,a),I[0],I[1]]}),n.push({op:"move",data:[e.x+this.getOffset(-j,j,a),e.y+this.getOffset(-j,j,a)]}),I=[X+this.getOffset(-j,j,a),V+this.getOffset(-j,j,a)],n.push({op:"qcurveTo",data:[q+this.getOffset(-j,j,a),U+this.getOffset(-j,j,a),I[0],I[1]]}),e.setPosition(I[0],I[1]),e.quadReflectionPoint=[X+(X-q),V+(V-U)]}break}case"T":case"t":{var Q="t"===t.key;if(2<=t.data.length){var $=+t.data[0],Z=+t.data[1];Q&&($+=e.x,Z+=e.y);var H=$,J=Z,Y=l?l.key:"",K=null;("q"===Y||"Q"===Y||"t"===Y||"T"===Y)&&(K=e.quadReflectionPoint),K&&(H=K[0],J=K[1]);var ee=1*(1+.2*a.roughness),te=1.5*(1+.22*a.roughness);n.push({op:"move",data:[e.x+this.getOffset(-ee,ee,a),e.y+this.getOffset(-ee,ee,a)]});var le=[$+this.getOffset(-ee,ee,a),Z+this.getOffset(-ee,ee,a)];n.push({op:"qcurveTo",data:[H+this.getOffset(-ee,ee,a),J+this.getOffset(-ee,ee,a),le[0],le[1]]}),n.push({op:"move",data:[e.x+this.getOffset(-te,te,a),e.y+this.getOffset(-te,te,a)]}),le=[$+this.getOffset(-te,te,a),Z+this.getOffset(-te,te,a)],n.push({op:"qcurveTo",data:[H+this.getOffset(-te,te,a),J+this.getOffset(-te,te,a),le[0],le[1]]}),e.setPosition(le[0],le[1]),e.quadReflectionPoint=[$+($-H),Z+(Z-J)]}break}case"A":case"a":{var ae="a"===t.key;if(7<=t.data.length){var ne=+t.data[0],ie=+t.data[1],se=+t.data[2],oe=+t.data[3],re=+t.data[4],pe=+t.data[5],de=+t.data[6];if(ae&&(pe+=e.x,de+=e.y),pe===e.x&&de===e.y)break;if(0==ne||0==ie)n=n.concat(this.doubleLine(e.x,e.y,pe,de,a)),e.setPosition(pe,de);else for(var ue=0;1>ue;ue++)for(var fe,he=new T([e.x,e.y],[pe,de],[ne,ie],se,!!oe,!!re),ge=he.getNextSegment();ge;)fe=this._bezierTo(ge.cp1[0],ge.cp1[1],ge.cp2[0],ge.cp2[1],ge.to[0],ge.to[1],e,a),n=n.concat(fe),ge=he.getNextSegment()}break}default:}return n}}]),e}(),F="undefined"!=typeof self,M=F&&self&&self.document&&self.document.currentScript&&self.document.currentScript.src,q="undefined"!=typeof self,U=function(){function e(t,l){b(this,e),this.defaultOptions={maxRandomnessOffset:2,roughness:1,bowing:1,stroke:"#000",strokeWidth:1,curveTightness:0,curveStepCount:9,fillStyle:"hachure",fillWeight:-1,hachureAngle:-41,hachureGap:-1},this.config=t||{},this.surface=l,this.renderer=o(this.config),this.config.options&&(this.defaultOptions=this._options(this.config.options))}return m(e,[{key:"_options",value:function(e){return e?Object.assign({},this.defaultOptions,e):this.defaultOptions}},{key:"_drawable",value:function(e,t,l){return{shape:e,sets:t||[],options:l||this.defaultOptions}}},{key:"getCanvasSize",value:function(){var e=function(e){return e&&"object"===("undefined"==typeof e?"undefined":x(e))&&e.baseVal&&e.baseVal.value?e.baseVal.value:e||100};return this.surface?[e(this.surface.width),e(this.surface.height)]:[100,100]}},{key:"computePolygonSize",value:function(e){if(e.length){for(var t=e[0][0],l=e[0][0],a=e[0][1],n=e[0][1],s=1;sl&&(l=t.strokeWidth/2),{d:this.opsToPath(e),stroke:t.fill||"none",strokeWidth:l,fill:"none"}}},{key:"opsToPath",value:function(e){var t="",l=!0,a=!1,n=void 0;try{for(var i,s=e.ops[Symbol.iterator]();!(l=(i=s.next()).done);l=!0){var o=i.value,r=o.data;switch(o.op){case"move":t+="M"+r[0]+" "+r[1]+" ";break;case"bcurveTo":t+="C"+r[0]+" "+r[1]+", "+r[2]+" "+r[3]+", "+r[4]+" "+r[5]+" ";break;case"qcurveTo":t+="Q"+r[0]+" "+r[1]+", "+r[2]+" "+r[3]+" ";break;case"lineTo":t+="L"+r[0]+" "+r[1]+" ";}}}catch(e){a=!0,n=e}finally{try{!l&&s.return&&s.return()}finally{if(a)throw n}}return t.trim()}},{key:"lib",get:function(){return this.renderer}}]),e}(),X="undefined"!=typeof document,V=function(){function e(t,l){b(this,e),this.canvas=t,this.ctx=this.canvas.getContext("2d"),this.gen=new U(l||null,this.canvas)}return m(e,[{key:"line",value:function(e,t,l,a,n){var i=this.gen.line(e,t,l,a,n);return this.draw(i),i}},{key:"rectangle",value:function(e,t,l,a,n){var i=this.gen.rectangle(e,t,l,a,n);return this.draw(i),i}},{key:"ellipse",value:function(e,t,l,a,n){var i=this.gen.ellipse(e,t,l,a,n);return this.draw(i),i}},{key:"circle",value:function(e,t,l,a){var n=this.gen.circle(e,t,l,a);return this.draw(n),n}},{key:"linearPath",value:function(e,t){var l=this.gen.linearPath(e,t);return this.draw(l),l}},{key:"polygon",value:function(e,t){var l=this.gen.polygon(e,t);return this.draw(l),l}},{key:"arc",value:function(e,t,l,a,n,i){var s=!!(6a&&(a=l.strokeWidth/2),e.save(),e.strokeStyle=l.fill||"",e.lineWidth=a,this._drawToContext(e,t),e.restore()}},{key:"_drawToContext",value:function(e,t){e.beginPath();var l=!0,a=!1,n=void 0;try{for(var i,s=t.ops[Symbol.iterator]();!(l=(i=s.next()).done);l=!0){var o=i.value,r=o.data;switch(o.op){case"move":e.moveTo(r[0],r[1]);break;case"bcurveTo":e.bezierCurveTo(r[0],r[1],r[2],r[3],r[4],r[5]);break;case"qcurveTo":e.quadraticCurveTo(r[0],r[1],r[2],r[3]);break;case"lineTo":e.lineTo(r[0],r[1]);}}}catch(e){a=!0,n=e}finally{try{!l&&s.return&&s.return()}finally{if(a)throw n}}"fillPath"===t.type?e.fill():e.stroke()}},{key:"generator",get:function(){return this.gen}}],[{key:"createRenderer",value:function(){return new B}}]),e}(),G=function(e){function t(){return b(this,t),P(this,(t.__proto__||Object.getPrototypeOf(t)).apply(this,arguments))}return w(t,e),m(t,[{key:"line",value:async function(e,t,l,a,n){var i=this._options(n);return this._drawable("line",[await this.lib.line(e,t,l,a,i)],i)}},{key:"rectangle",value:async function(e,t,l,a,n){var i=this._options(n),s=[];if(i.fill){var o=[[e,t],[e+l,t],[e+l,t+a],[e,t+a]];"solid"===i.fillStyle?s.push((await this.lib.solidFillPolygon(o,i))):s.push((await this.lib.patternFillPolygon(o,i)))}return s.push((await this.lib.rectangle(e,t,l,a,i))),this._drawable("rectangle",s,i)}},{key:"ellipse",value:async function(e,t,l,a,n){var i=this._options(n),s=[];if(i.fill)if("solid"===i.fillStyle){var o=await this.lib.ellipse(e,t,l,a,i);o.type="fillPath",s.push(o)}else s.push((await this.lib.patternFillEllipse(e,t,l,a,i)));return s.push((await this.lib.ellipse(e,t,l,a,i))),this._drawable("ellipse",s,i)}},{key:"circle",value:async function(e,t,l,a){var n=await this.ellipse(e,t,l,l,a);return n.shape="circle",n}},{key:"linearPath",value:async function(e,t){var l=this._options(t);return this._drawable("linearPath",[await this.lib.linearPath(e,!1,l)],l)}},{key:"arc",value:async function(e,t,l,a,n,i){var s=!!(6a&&(a=l.strokeWidth/2);var n=e.createElementNS("http://www.w3.org/2000/svg","path");return n.setAttribute("d",this.opsToPath(t)),n.style.stroke=l.fill||null,n.style.strokeWidth=a+"",n.style.fill="none",n}},{key:"generator",get:function(){return this.gen}},{key:"defs",get:function(){var e=this.svg.ownerDocument||I&&document;if(e&&!this._defs){var t=e.createElementNS("http://www.w3.org/2000/svg","defs");this.svg.firstChild?this.svg.insertBefore(t,this.svg.firstChild):this.svg.appendChild(t),this._defs=t}return this._defs||null}}],[{key:"createRenderer",value:function(){return new B}}]),e}(),$=function(e){function t(e,l){b(this,t);var a=P(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,l));return a.genAsync=new G(l||null,a.svg),a}return w(t,e),m(t,[{key:"line",value:async function(e,t,l,a,n){var i=await this.genAsync.line(e,t,l,a,n);return this.draw(i)}},{key:"rectangle",value:async function(e,t,l,a,n){var i=await this.genAsync.rectangle(e,t,l,a,n);return this.draw(i)}},{key:"ellipse",value:async function(e,t,l,a,n){var i=await this.genAsync.ellipse(e,t,l,a,n);return this.draw(i)}},{key:"circle",value:async function(e,t,l,a){var n=await this.genAsync.circle(e,t,l,a);return this.draw(n)}},{key:"linearPath",value:async function(e,t){var l=await this.genAsync.linearPath(e,t);return this.draw(l)}},{key:"polygon",value:async function(e,t){var l=await this.genAsync.polygon(e,t);return this.draw(l)}},{key:"arc",value:async function(e,t,l,a,n,i){var s=!!(6g&&(g=4*t.strokeWidth),g=d(g,.1);for(var y=h%180*(c/180),k=v(y),x=_(y),b=p(y),O=new E(o-1,r+1,n-1,s+1,g,x,k,b),m=void 0;null!=(m=O.nextLine());)for(var P=l(m,e),w=0;w=f&&(f=4*i.strokeWidth);var h=i.fillWeight;0>h&&(h=i.strokeWidth/2);for(var g=p(u%180*(c/180)),v=d/r,_=y(v*g*v*g+1),x=v*g/_,b=1/_,O=f/(r*d/y(d*b*(d*b)+r*x*(r*x))/r),m=y(r*r-(e-r+O)*(e-r+O)),P=e-r+O;Pf){var h=y(1-f/(this._rx*this._rx*this._ry*this._ry));this._rx*=h,this._ry*=h,u=0}else u=(i===o?-1:1)*y(f/(this._rx*this._rx*d*d+this._ry*this._ry*p*p));var s=u*this._rx*d/this._ry,x=-u*this._ry*p/this._rx;this._C=[0,0],this._C[0]=this._cosPhi*s-this._sinPhi*x+(t[0]+l[0])/2,this._C[1]=this._sinPhi*s+this._cosPhi*x+(t[1]+l[1])/2,this._theta=this.calculateVectorAngle(1,0,(p-s)/this._rx,(d-x)/this._ry);var O=this.calculateVectorAngle((p-s)/this._rx,(d-x)/this._ry,(-p-s)/this._rx,(-d-x)/this._ry);!o&&0O&&(O+=2*c),this._numSegs=g(k(O/(c/2))),this._delta=O/this._numSegs,this._T=8/3*_(this._delta/4)*_(this._delta/4)/_(this._delta/2)}}return O(e,[{key:"getNextSegment",value:function(){if(this._segIndex===this._numSegs)return null;var e=v(this._theta),t=_(this._theta),l=this._theta+this._delta,a=v(l),n=_(l),i=[this._cosPhi*this._rx*a-this._sinPhi*this._ry*n+this._C[0],this._sinPhi*this._rx*a+this._cosPhi*this._ry*n+this._C[1]],s=[this._from[0]+this._T*(-this._cosPhi*this._rx*t-this._sinPhi*this._ry*e),this._from[1]+this._T*(-this._sinPhi*this._rx*t+this._cosPhi*this._ry*e)],o=[i[0]+this._T*(this._cosPhi*this._rx*n+this._sinPhi*this._ry*a),i[1]+this._T*(this._sinPhi*this._rx*n-this._cosPhi*this._ry*a)];return this._theta=l,this._from=[i[0],i[1]],this._segIndex++,{cp1:s,cp2:o,to:i}}},{key:"calculateVectorAngle",value:function(e,t,l,a){var n=Math.atan2,i=n(t,e),s=n(a,l);return s>=i?s-i:2*c-(i-s)}}]),e}(),C=function(){function e(t,l){b(this,e),this.sets=t,this.closed=l}return O(e,[{key:"fit",value:function(e){var t=[],l=!0,a=!1,n=void 0;try{for(var s,o=this.sets[Symbol.iterator]();!(l=(s=o.next()).done);l=!0){var r=s.value,p=r.length,u=h(e*p);if(5>u){if(5>=p)continue;u=5}t.push(this.reduce(r,u))}}catch(e){a=!0,n=e}finally{try{!l&&o.return&&o.return()}finally{if(a)throw n}}var f="",g=!0,y=!1,c=void 0;try{for(var v,_,k=t[Symbol.iterator]();!(g=(v=k.next()).done);g=!0){_=v.value;for(var x,b=0;b<_.length;b++)x=_[b],f+=0===b?"M"+x[0]+","+x[1]:"L"+x[0]+","+x[1];this.closed&&(f+="z ")}}catch(e){y=!0,c=e}finally{try{!g&&k.return&&k.return()}finally{if(y)throw c}}return f}},{key:"distance",value:function(e,t){return y(f(e[0]-t[0],2)+f(e[1]-t[1],2))}},{key:"reduce",value:function(e,t){if(e.length<=t)return e;for(var l=e.slice(0);l.length>t;){for(var n=-1,o=-1,r=1;rn||s=u(e.py1,e.py2)&&this.py1<=d(e.py1,e.py2)?(this.xi=this.px1,this.yi=this.py1,!0):!!(this.py2>=u(e.py1,e.py2)&&this.py2<=d(e.py1,e.py2))&&(this.xi=this.px2,this.yi=this.py2,!0)):(this.xi=this.px1,this.yi=n*this.xi+s,!(-1e-5>(this.py1-this.yi)*(this.yi-this.py2)||-1e-5>(e.py1-this.yi)*(this.yi-e.py2))&&(!(1e-5>k(e.a))||!(-1e-5>(e.px1-this.xi)*(this.xi-e.px2)))):n===t?(this.xi=e.px1,this.yi=l*this.xi+i,!(-1e-5>(e.py1-this.yi)*(this.yi-e.py2)||-1e-5>(this.py1-this.yi)*(this.yi-this.py2))&&(!(1e-5>k(o))||!(-1e-5>(this.px1-this.xi)*(this.xi-this.px2)))):l===n?i==s&&(this.px1>=u(e.px1,e.px2)&&this.px1<=d(e.py1,e.py2)?(this.xi=this.px1,this.yi=this.py1,!0):!!(this.px2>=u(e.px1,e.px2)&&this.px2<=d(e.px1,e.px2))&&(this.xi=this.px2,this.yi=this.py2,!0)):(this.xi=(s-i)/(l-n),this.yi=l*this.xi+i,!(-1e-5>(this.px1-this.xi)*(this.xi-this.px2)||-1e-5>(e.px1-this.xi)*(this.xi-e.px2)))}}]),e}(),E=function(){function e(t,l,a,n,i,s,o,r){b(this,e),this.deltaX=0,this.hGap=0,this.top=t,this.bottom=l,this.left=a,this.right=n,this.gap=i,this.sinAngle=s,this.tanAngle=r,1e-4>k(s)?this.pos=a+i:.9999k(this.sinAngle)){if(this.posthis.right&&l>this.right;)if(this.pos+=this.hGap,t=this.pos-this.deltaX/2,l=this.pos+this.deltaX/2,this.pos>this.right+this.deltaX)return null;var i=new z([t,a],[l,n]);this.sLeft&&i.intersects(this.sLeft)&&(t=i.xi,a=i.yi),this.sRight&&i.intersects(this.sRight)&&(l=i.xi,n=i.yi),0s&&(s=4*a.strokeWidth),s=d(s,.1);var o=a.fillWeight;0>o&&(o=a.strokeWidth/2);var r=!0,p=!1,u=void 0;try{for(var f,h=e[Symbol.iterator]();!(r=(f=h.next()).done);r=!0)for(var y=f.value,k=t(y),x=k/s,b=g(x)-1,O=Math.atan((y[1][1]-y[0][1])/(y[1][0]-y[0][0])),m=0;mg;)g+=2*c,y+=2*c;y-g>2*c&&(g=0,y=2*c);var x=2*c/p.curveStepCount,b=u(x/2,(y-g)/2),O=this._arc(b,o,d,f,h,g,y,1,p),m=this._arc(b,o,d,f,h,g,y,1.5,p),P=O.concat(m);return s&&(r?(P=P.concat(this.doubleLine(o,d,o+f*v(g),d+h*_(g),p)),P=P.concat(this.doubleLine(o,d,o+f*v(y),d+h*_(y),p))):(P.push({op:"lineTo",data:[o,d]}),P.push({op:"lineTo",data:[o+f*v(g),d+h*_(g)]}))),{type:"path",ops:P}}},{key:"svgPath",value:function(e,t){e=(e||"").replace(/\n/g," ").replace(/(-\s)/g,"-").replace("/(ss)/g"," ");var l=new A(e);if(t.simplification){var a=new C(l.linearPoints,l.closed),n=a.fit(t.simplification);l=new A(n)}for(var o=[],r=l.segments||[],d=0;du;)u+=2*c,f+=2*c;f-u>2*c&&(u=0,f=2*c);for(var h=(f-u)/s.curveStepCount,g=[],y=u;y<=f;y+=h)g.push([o+p*v(y),r+d*_(y)]);return g.push([o+p*v(f),r+d*_(f)]),g.push([o,r]),this.patternFillPolygon(g,s)}},{key:"getOffset",value:function(e,t,l){return l.roughness*(Math.random()*(t-e)+e)}},{key:"doubleLine",value:function(e,t,l,a,n){var i=this._line(e,t,l,a,n,!0,!1),s=this._line(e,t,l,a,n,!0,!0);return i.concat(s)}},{key:"_line",value:function(e,t,l,a,n,i,s){var o=f(e-l,2)+f(t-a,2),r=n.maxRandomnessOffset||0;100*(r*r)>o&&(r=y(o)/10);var p=r/2,d=.2+.2*Math.random(),u=n.bowing*n.maxRandomnessOffset*(a-t)/200,h=n.bowing*n.maxRandomnessOffset*(e-l)/200;u=this.getOffset(-u,u,n),h=this.getOffset(-h,h,n);var g=[];return i&&(s?g.push({op:"move",data:[e+this.getOffset(-p,p,n),t+this.getOffset(-p,p,n)]}):g.push({op:"move",data:[e+this.getOffset(-r,r,n),t+this.getOffset(-r,r,n)]})),s?g.push({op:"bcurveTo",data:[u+e+(l-e)*d+this.getOffset(-p,p,n),h+t+(a-t)*d+this.getOffset(-p,p,n),u+e+2*(l-e)*d+this.getOffset(-p,p,n),h+t+2*(a-t)*d+this.getOffset(-p,p,n),l+this.getOffset(-p,p,n),a+this.getOffset(-p,p,n)]}):g.push({op:"bcurveTo",data:[u+e+(l-e)*d+this.getOffset(-r,r,n),h+t+(a-t)*d+this.getOffset(-r,r,n),u+e+2*(l-e)*d+this.getOffset(-r,r,n),h+t+2*(a-t)*d+this.getOffset(-r,r,n),l+this.getOffset(-r,r,n),a+this.getOffset(-r,r,n)]}),g}},{key:"_curve",value:function(e,t,l){var a=e.length,n=[];if(3h;h++)0===h?o.push({op:"move",data:[r.x,r.y]}):o.push({op:"move",data:[r.x+this.getOffset(-d[0],d[0],p),r.y+this.getOffset(-d[0],d[0],p)]}),u=[n+this.getOffset(-d[h],d[h],p),s+this.getOffset(-d[h],d[h],p)],o.push({op:"bcurveTo",data:[e+this.getOffset(-d[h],d[h],p),t+this.getOffset(-d[h],d[h],p),l+this.getOffset(-d[h],d[h],p),a+this.getOffset(-d[h],d[h],p),u[0],u[1]]});return r.setPosition(u[0],u[1]),o}},{key:"_processSegment",value:function(e,t,l,a){var n=[];switch(t.key){case"M":case"m":{var s="m"===t.key;if(2<=t.data.length){var o=+t.data[0],r=+t.data[1];s&&(o+=e.x,r+=e.y);var p=1*(a.maxRandomnessOffset||0);o+=this.getOffset(-p,p,a),r+=this.getOffset(-p,p,a),e.setPosition(o,r),n.push({op:"move",data:[o,r]})}break}case"L":case"l":{var d="l"===t.key;if(2<=t.data.length){var u=+t.data[0],h=+t.data[1];d&&(u+=e.x,h+=e.y),n=n.concat(this.doubleLine(e.x,e.y,u,h,a)),e.setPosition(u,h)}break}case"H":case"h":{var g="h"===t.key;if(t.data.length){var c=+t.data[0];g&&(c+=e.x),n=n.concat(this.doubleLine(e.x,e.y,c,e.y,a)),e.setPosition(c,e.y)}break}case"V":case"v":{var v="v"===t.key;if(t.data.length){var _=+t.data[0];v&&(_+=e.y),n=n.concat(this.doubleLine(e.x,e.y,e.x,_,a)),e.setPosition(e.x,_)}break}case"Z":case"z":{e.first&&(n=n.concat(this.doubleLine(e.x,e.y,e.first[0],e.first[1],a)),e.setPosition(e.first[0],e.first[1]),e.first=null);break}case"C":case"c":{var k="c"===t.key;if(6<=t.data.length){var b=+t.data[0],O=+t.data[1],m=+t.data[2],P=+t.data[3],w=+t.data[4],S=+t.data[5];k&&(b+=e.x,m+=e.x,w+=e.x,O+=e.y,P+=e.y,S+=e.y);var A=this._bezierTo(b,O,m,P,w,S,e,a);n=n.concat(A),e.bezierReflectionPoint=[w+(w-m),S+(S-P)]}break}case"S":case"s":{var C="s"===t.key;if(4<=t.data.length){var z=+t.data[0],E=+t.data[1],L=+t.data[2],W=+t.data[3];C&&(z+=e.x,L+=e.x,E+=e.y,W+=e.y);var N=z,D=E,R=l?l.key:"",B=null;("c"===R||"C"===R||"s"===R||"S"===R)&&(B=e.bezierReflectionPoint),B&&(N=B[0],D=B[1]);var F=this._bezierTo(N,D,z,E,L,W,e,a);n=n.concat(F),e.bezierReflectionPoint=[L+(L-z),W+(W-E)]}break}case"Q":case"q":{var M="q"===t.key;if(4<=t.data.length){var q=+t.data[0],U=+t.data[1],X=+t.data[2],V=+t.data[3];M&&(q+=e.x,X+=e.x,U+=e.y,V+=e.y);var G=1*(1+.2*a.roughness),j=1.5*(1+.22*a.roughness);n.push({op:"move",data:[e.x+this.getOffset(-G,G,a),e.y+this.getOffset(-G,G,a)]});var I=[X+this.getOffset(-G,G,a),V+this.getOffset(-G,G,a)];n.push({op:"qcurveTo",data:[q+this.getOffset(-G,G,a),U+this.getOffset(-G,G,a),I[0],I[1]]}),n.push({op:"move",data:[e.x+this.getOffset(-j,j,a),e.y+this.getOffset(-j,j,a)]}),I=[X+this.getOffset(-j,j,a),V+this.getOffset(-j,j,a)],n.push({op:"qcurveTo",data:[q+this.getOffset(-j,j,a),U+this.getOffset(-j,j,a),I[0],I[1]]}),e.setPosition(I[0],I[1]),e.quadReflectionPoint=[X+(X-q),V+(V-U)]}break}case"T":case"t":{var Q="t"===t.key;if(2<=t.data.length){var $=+t.data[0],Z=+t.data[1];Q&&($+=e.x,Z+=e.y);var H=$,J=Z,Y=l?l.key:"",K=null;("q"===Y||"Q"===Y||"t"===Y||"T"===Y)&&(K=e.quadReflectionPoint),K&&(H=K[0],J=K[1]);var ee=1*(1+.2*a.roughness),te=1.5*(1+.22*a.roughness);n.push({op:"move",data:[e.x+this.getOffset(-ee,ee,a),e.y+this.getOffset(-ee,ee,a)]});var le=[$+this.getOffset(-ee,ee,a),Z+this.getOffset(-ee,ee,a)];n.push({op:"qcurveTo",data:[H+this.getOffset(-ee,ee,a),J+this.getOffset(-ee,ee,a),le[0],le[1]]}),n.push({op:"move",data:[e.x+this.getOffset(-te,te,a),e.y+this.getOffset(-te,te,a)]}),le=[$+this.getOffset(-te,te,a),Z+this.getOffset(-te,te,a)],n.push({op:"qcurveTo",data:[H+this.getOffset(-te,te,a),J+this.getOffset(-te,te,a),le[0],le[1]]}),e.setPosition(le[0],le[1]),e.quadReflectionPoint=[$+($-H),Z+(Z-J)]}break}case"A":case"a":{var ae="a"===t.key;if(7<=t.data.length){var ne=+t.data[0],ie=+t.data[1],se=+t.data[2],oe=+t.data[3],re=+t.data[4],pe=+t.data[5],de=+t.data[6];if(ae&&(pe+=e.x,de+=e.y),pe===e.x&&de===e.y)break;if(0==ne||0==ie)n=n.concat(this.doubleLine(e.x,e.y,pe,de,a)),e.setPosition(pe,de);else for(var ue=0;1>ue;ue++)for(var fe,he=new T([e.x,e.y],[pe,de],[ne,ie],se,!!oe,!!re),ge=he.getNextSegment();ge;)fe=this._bezierTo(ge.cp1[0],ge.cp1[1],ge.cp2[0],ge.cp2[1],ge.to[0],ge.to[1],e,a),n=n.concat(fe),ge=he.getNextSegment()}break}default:}return n}}]),e}(),F="undefined"!=typeof self,M=F&&self&&self.document&&self.document.currentScript&&self.document.currentScript.src,q="undefined"!=typeof self,U=function(){function e(t,l){b(this,e),this.defaultOptions={maxRandomnessOffset:2,roughness:1,bowing:1,stroke:"#000",strokeWidth:1,curveTightness:0,curveStepCount:9,fillStyle:"hachure",fillWeight:-1,hachureAngle:-41,hachureGap:-1},this.config=t||{},this.surface=l,this.renderer=o(this.config),this.config.options&&(this.defaultOptions=this._options(this.config.options))}return O(e,[{key:"_options",value:function(e){return e?Object.assign({},this.defaultOptions,e):this.defaultOptions}},{key:"_drawable",value:function(e,t,l){return{shape:e,sets:t||[],options:l||this.defaultOptions}}},{key:"getCanvasSize",value:function(){var e=function(e){return e&&"object"===("undefined"==typeof e?"undefined":x(e))&&e.baseVal&&e.baseVal.value?e.baseVal.value:e||100};return this.surface?[e(this.surface.width),e(this.surface.height)]:[100,100]}},{key:"computePolygonSize",value:function(e){if(e.length){for(var t=e[0][0],l=e[0][0],a=e[0][1],n=e[0][1],s=1;sl&&(l=t.strokeWidth/2),{d:this.opsToPath(e),stroke:t.fill||"none",strokeWidth:l,fill:"none"}}},{key:"opsToPath",value:function(e){var t="",l=!0,a=!1,n=void 0;try{for(var i,s=e.ops[Symbol.iterator]();!(l=(i=s.next()).done);l=!0){var o=i.value,r=o.data;switch(o.op){case"move":t+="M"+r[0]+" "+r[1]+" ";break;case"bcurveTo":t+="C"+r[0]+" "+r[1]+", "+r[2]+" "+r[3]+", "+r[4]+" "+r[5]+" ";break;case"qcurveTo":t+="Q"+r[0]+" "+r[1]+", "+r[2]+" "+r[3]+" ";break;case"lineTo":t+="L"+r[0]+" "+r[1]+" ";}}}catch(e){a=!0,n=e}finally{try{!l&&s.return&&s.return()}finally{if(a)throw n}}return t.trim()}},{key:"lib",get:function(){return this.renderer}}]),e}(),X=function(e){function t(e,l){return b(this,t),P(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,l))}return m(t,e),O(t,[{key:"line",value:function(e,t,l,a,n){var i=this._options(n);return this._drawable("line",[this.lib.line(e,t,l,a,i)],i)}},{key:"rectangle",value:function(e,t,l,a,n){var i=this._options(n),s=[];if(i.fill){var o=[[e,t],[e+l,t],[e+l,t+a],[e,t+a]];"solid"===i.fillStyle?s.push(this.lib.solidFillPolygon(o,i)):s.push(this.lib.patternFillPolygon(o,i))}return s.push(this.lib.rectangle(e,t,l,a,i)),this._drawable("rectangle",s,i)}},{key:"ellipse",value:function(e,t,l,a,n){var i=this._options(n),s=[];if(i.fill)if("solid"===i.fillStyle){var o=this.lib.ellipse(e,t,l,a,i);o.type="fillPath",s.push(o)}else s.push(this.lib.patternFillEllipse(e,t,l,a,i));return s.push(this.lib.ellipse(e,t,l,a,i)),this._drawable("ellipse",s,i)}},{key:"circle",value:function(e,t,l,a){var n=this.ellipse(e,t,l,l,a);return n.shape="circle",n}},{key:"linearPath",value:function(e,t){var l=this._options(t);return this._drawable("linearPath",[this.lib.linearPath(e,!1,l)],l)}},{key:"arc",value:function(e,t,l,a,n,i){var s=!!(6a&&(a=l.strokeWidth/2),e.save(),e.strokeStyle=l.fill||"",e.lineWidth=a,this._drawToContext(e,t),e.restore()}},{key:"_drawToContext",value:function(e,t){e.beginPath();var l=!0,a=!1,n=void 0;try{for(var i,s=t.ops[Symbol.iterator]();!(l=(i=s.next()).done);l=!0){var o=i.value,r=o.data;switch(o.op){case"move":e.moveTo(r[0],r[1]);break;case"bcurveTo":e.bezierCurveTo(r[0],r[1],r[2],r[3],r[4],r[5]);break;case"qcurveTo":e.quadraticCurveTo(r[0],r[1],r[2],r[3]);break;case"lineTo":e.lineTo(r[0],r[1]);}}}catch(e){a=!0,n=e}finally{try{!l&&s.return&&s.return()}finally{if(a)throw n}}"fillPath"===t.type?e.fill():e.stroke()}}],[{key:"createRenderer",value:function(){return new B}}]),e}(),j=function(e){function t(e,l){b(this,t);var a=P(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e));return a.gen=new X(l||null,a.canvas),a}return m(t,e),O(t,[{key:"getDefaultOptions",value:function(){return this.gen.defaultOptions}},{key:"line",value:function(e,t,l,a,n){var i=this.gen.line(e,t,l,a,n);return this.draw(i),i}},{key:"rectangle",value:function(e,t,l,a,n){var i=this.gen.rectangle(e,t,l,a,n);return this.draw(i),i}},{key:"ellipse",value:function(e,t,l,a,n){var i=this.gen.ellipse(e,t,l,a,n);return this.draw(i),i}},{key:"circle",value:function(e,t,l,a){var n=this.gen.circle(e,t,l,a);return this.draw(n),n}},{key:"linearPath",value:function(e,t){var l=this.gen.linearPath(e,t);return this.draw(l),l}},{key:"polygon",value:function(e,t){var l=this.gen.polygon(e,t);return this.draw(l),l}},{key:"arc",value:function(e,t,l,a,n,i){var s=!!(6a&&(a=l.strokeWidth/2);var n=e.createElementNS("http://www.w3.org/2000/svg","path");return n.setAttribute("d",this.opsToPath(t)),n.style.stroke=l.fill||null,n.style.strokeWidth=a+"",n.style.fill="none",n}},{key:"defs",get:function(){var e=this.svg.ownerDocument||$&&document;if(e&&!this._defs){var t=e.createElementNS("http://www.w3.org/2000/svg","defs");this.svg.firstChild?this.svg.insertBefore(t,this.svg.firstChild):this.svg.appendChild(t),this._defs=t}return this._defs||null}}],[{key:"createRenderer",value:function(){return new B}}]),e}(),H=function(e){function t(e,l){b(this,t);var a=P(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e));return a.gen=new X(l||null,a.svg),a}return m(t,e),O(t,[{key:"getDefaultOptions",value:function(){return this.gen.defaultOptions}},{key:"opsToPath",value:function(e){return this.gen.opsToPath(e)}},{key:"line",value:function(e,t,l,a,n){var i=this.gen.line(e,t,l,a,n);return this.draw(i)}},{key:"rectangle",value:function(e,t,l,a,n){var i=this.gen.rectangle(e,t,l,a,n);return this.draw(i)}},{key:"ellipse",value:function(e,t,l,a,n){var i=this.gen.ellipse(e,t,l,a,n);return this.draw(i)}},{key:"circle",value:function(e,t,l,a){var n=this.gen.circle(e,t,l,a);return this.draw(n)}},{key:"linearPath",value:function(e,t){var l=this.gen.linearPath(e,t);return this.draw(l)}},{key:"polygon",value:function(e,t){var l=this.gen.polygon(e,t);return this.draw(l)}},{key:"arc",value:function(e,t,l,a,n,i){var s=!!(6h&&(h=4*t.strokeWidth),h=d(h,.1);const g=r%180*(b/180),c=_(g),u=w(g),y=p(g),x=new S(l-1,o+1,n-1,a+1,h,u,c,y);for(let t;null!=(t=x.nextLine());){const n=i(t,e);for(let e=0;e=h&&(h=4*a.strokeWidth);let g=a.fillWeight;0>g&&(g=a.strokeWidth/2);const c=p(f%180*(b/180)),u=d/r,_=y(u*c*u*c+1),x=u*c/_,w=1/_,O=h/(r*d/y(d*w*(d*w)+r*x*(r*x))/r);let P=y(r*r-(e-r+O)*(e-r+O));for(let p=e-r+O;pd){const e=y(1-d/(this._rx*this._rx*this._ry*this._ry));this._rx*=e,this._ry*=e,p=0}else p=(n===a?-1:1)*y(d/(this._rx*this._rx*r*r+this._ry*this._ry*o*o));const f=p*this._rx*r/this._ry,h=-p*this._ry*o/this._rx;this._C=[0,0],this._C[0]=this._cosPhi*f-this._sinPhi*h+(e[0]+t[0])/2,this._C[1]=this._sinPhi*f+this._cosPhi*h+(e[1]+t[1])/2,this._theta=this.calculateVectorAngle(1,0,(o-f)/this._rx,(r-h)/this._ry);let g=this.calculateVectorAngle((o-f)/this._rx,(r-h)/this._ry,(-o-f)/this._rx,(-r-h)/this._ry);!a&&0g&&(g+=2*b),this._numSegs=u(m(g/(b/2))),this._delta=g/this._numSegs,this._T=8/3*w(this._delta/4)*w(this._delta/4)/w(this._delta/2)}getNextSegment(){if(this._segIndex===this._numSegs)return null;const e=_(this._theta),t=w(this._theta),i=this._theta+this._delta,s=_(i),n=w(i),a=[this._cosPhi*this._rx*s-this._sinPhi*this._ry*n+this._C[0],this._sinPhi*this._rx*s+this._cosPhi*this._ry*n+this._C[1]],l=[this._from[0]+this._T*(-this._cosPhi*this._rx*t-this._sinPhi*this._ry*e),this._from[1]+this._T*(-this._sinPhi*this._rx*t+this._cosPhi*this._ry*e)],o=[a[0]+this._T*(this._cosPhi*this._rx*n+this._sinPhi*this._ry*s),a[1]+this._T*(this._sinPhi*this._rx*n-this._cosPhi*this._ry*s)];return this._theta=i,this._from=[a[0],a[1]],this._segIndex++,{cp1:l,cp2:o,to:a}}calculateVectorAngle(e,t,i,s){var n=Math.atan2;const a=n(t,e),l=n(s,i);return l>=a?l-a:2*b-(a-l)}}class k{constructor(e,t){this.sets=e,this.closed=t}fit(e){const t=[];for(const i of this.sets){const s=i.length;let n=c(e*s);if(5>n){if(5>=s)continue;n=5}t.push(this.reduce(i,n))}let s='';for(const n of t){for(let e=0;et;){let e=-1,t=-1;for(let l=1;le||s=f(e.py1,e.py2)&&this.py1<=d(e.py1,e.py2)?(this.xi=this.px1,this.yi=this.py1,!0):!!(this.py2>=f(e.py1,e.py2)&&this.py2<=d(e.py1,e.py2))&&(this.xi=this.px2,this.yi=this.py2,!0)):(this.xi=this.px1,this.yi=i*this.xi+n,!(-1e-5>(this.py1-this.yi)*(this.yi-this.py2)||-1e-5>(e.py1-this.yi)*(this.yi-e.py2))&&(!(1e-5>m(e.a))||!(-1e-5>(e.px1-this.xi)*(this.xi-e.px2)))):i===h?(this.xi=e.px1,this.yi=t*this.xi+s,!(-1e-5>(e.py1-this.yi)*(this.yi-e.py2)||-1e-5>(this.py1-this.yi)*(this.yi-this.py2))&&(!(1e-5>m(l))||!(-1e-5>(this.px1-this.xi)*(this.xi-this.px2)))):t===i?s==n&&(this.px1>=f(e.px1,e.px2)&&this.px1<=d(e.py1,e.py2)?(this.xi=this.px1,this.yi=this.py1,!0):!!(this.px2>=f(e.px1,e.px2)&&this.px2<=d(e.px1,e.px2))&&(this.xi=this.px2,this.yi=this.py2,!0)):(this.xi=(n-s)/(t-i),this.yi=t*this.xi+s,!(-1e-5>(this.px1-this.xi)*(this.xi-this.px2)||-1e-5>(e.px1-this.xi)*(this.xi-e.px2)))}}class S{constructor(e,t,i,s,n,a,l,o){this.deltaX=0,this.hGap=0,this.top=e,this.bottom=t,this.left=i,this.right=s,this.gap=n,this.sinAngle=a,this.tanAngle=o,1e-4>m(a)?this.pos=i+n:.9999m(this.sinAngle)){if(this.posthis.right&&t>this.right;)if(this.pos+=this.hGap,e=this.pos-this.deltaX/2,t=this.pos+this.deltaX/2,this.pos>this.right+this.deltaX)return null;const a=new A([e,i],[t,n]);this.sLeft&&a.intersects(this.sLeft)&&(e=a.xi,i=a.yi),this.sRight&&a.intersects(this.sRight)&&(t=a.xi,n=a.yi),0a&&(a=4*s.strokeWidth),a=d(a,.1);let o=s.fillWeight;0>o&&(o=s.strokeWidth/2);for(const r of e){const e=t(r),i=e/a,l=u(i)-1,p=Math.atan((r[1][1]-r[0][1])/(r[1][0]-r[0][0]));for(let e=0;ec;)c+=2*b,u+=2*b;u-c>2*b&&(c=0,u=2*b);const y=2*b/p.curveStepCount,x=f(y/2,(u-c)/2),O=this._arc(x,o,d,h,g,c,u,1,p),P=this._arc(x,o,d,h,g,c,u,1.5,p);let v=O.concat(P);return l&&(r?(v=v.concat(this.doubleLine(o,d,o+h*_(c),d+g*w(c),p)),v=v.concat(this.doubleLine(o,d,o+h*_(u),d+g*w(u),p))):(v.push({op:'lineTo',data:[o,d]}),v.push({op:'lineTo',data:[o+h*_(c),d+g*w(c)]}))),{type:'path',ops:v}}svgPath(e,t){e=(e||'').replace(/\n/g,' ').replace(/(-\s)/g,'-').replace('/(ss)/g',' ');let n=new P(e);if(t.simplification){const e=new k(n.linearPoints,n.closed),i=e.fit(t.simplification);n=new P(i)}let a=[];const l=n.segments||[];for(let o=0;of;)f+=2*b,h+=2*b;h-f>2*b&&(f=0,h=2*b);const g=(h-f)/l.curveStepCount,c=[];for(let u=f;u<=h;u+=g)c.push([o+p*_(u),r+d*w(u)]);return c.push([o+p*_(h),r+d*w(h)]),c.push([o,r]),this.patternFillPolygon(c,l)}getOffset(e,t,i){return i.roughness*(Math.random()*(t-e)+e)}doubleLine(e,t,i,s,n){const a=this._line(e,t,i,s,n,!0,!1),l=this._line(e,t,i,s,n,!0,!0);return a.concat(l)}_line(e,t,i,s,n,a,l){const o=g(e-i,2)+g(t-s,2);let r=n.maxRandomnessOffset||0;100*(r*r)>o&&(r=y(o)/10);const p=r/2,d=.2+.2*Math.random();let f=n.bowing*n.maxRandomnessOffset*(s-t)/200,h=n.bowing*n.maxRandomnessOffset*(e-i)/200;f=this.getOffset(-f,f,n),h=this.getOffset(-h,h,n);const c=[];return a&&(l?c.push({op:'move',data:[e+this.getOffset(-p,p,n),t+this.getOffset(-p,p,n)]}):c.push({op:'move',data:[e+this.getOffset(-r,r,n),t+this.getOffset(-r,r,n)]})),l?c.push({op:'bcurveTo',data:[f+e+(i-e)*d+this.getOffset(-p,p,n),h+t+(s-t)*d+this.getOffset(-p,p,n),f+e+2*(i-e)*d+this.getOffset(-p,p,n),h+t+2*(s-t)*d+this.getOffset(-p,p,n),i+this.getOffset(-p,p,n),s+this.getOffset(-p,p,n)]}):c.push({op:'bcurveTo',data:[f+e+(i-e)*d+this.getOffset(-r,r,n),h+t+(s-t)*d+this.getOffset(-r,r,n),f+e+2*(i-e)*d+this.getOffset(-r,r,n),h+t+2*(s-t)*d+this.getOffset(-r,r,n),i+this.getOffset(-r,r,n),s+this.getOffset(-r,r,n)]}),c}_curve(e,t,i){const n=e.length;let a=[];if(3f;f++)0===f?o.push({op:'move',data:[r.x,r.y]}):o.push({op:'move',data:[r.x+this.getOffset(-d[0],d[0],p),r.y+this.getOffset(-d[0],d[0],p)]}),h=[a+this.getOffset(-d[f],d[f],p),l+this.getOffset(-d[f],d[f],p)],o.push({op:'bcurveTo',data:[e+this.getOffset(-d[f],d[f],p),t+this.getOffset(-d[f],d[f],p),s+this.getOffset(-d[f],d[f],p),n+this.getOffset(-d[f],d[f],p),h[0],h[1]]});return r.setPosition(h[0],h[1]),o}_processSegment(e,t,i,s){let n=[];switch(t.key){case'M':case'm':{const i='m'===t.key;if(2<=t.data.length){let a=+t.data[0],l=+t.data[1];i&&(a+=e.x,l+=e.y);const o=1*(s.maxRandomnessOffset||0);a+=this.getOffset(-o,o,s),l+=this.getOffset(-o,o,s),e.setPosition(a,l),n.push({op:'move',data:[a,l]})}break}case'L':case'l':{const i='l'===t.key;if(2<=t.data.length){let a=+t.data[0],l=+t.data[1];i&&(a+=e.x,l+=e.y),n=n.concat(this.doubleLine(e.x,e.y,a,l,s)),e.setPosition(a,l)}break}case'H':case'h':{const i='h'===t.key;if(t.data.length){let a=+t.data[0];i&&(a+=e.x),n=n.concat(this.doubleLine(e.x,e.y,a,e.y,s)),e.setPosition(a,e.y)}break}case'V':case'v':{const i='v'===t.key;if(t.data.length){let a=+t.data[0];i&&(a+=e.y),n=n.concat(this.doubleLine(e.x,e.y,e.x,a,s)),e.setPosition(e.x,a)}break}case'Z':case'z':{e.first&&(n=n.concat(this.doubleLine(e.x,e.y,e.first[0],e.first[1],s)),e.setPosition(e.first[0],e.first[1]),e.first=null);break}case'C':case'c':{const i='c'===t.key;if(6<=t.data.length){let a=+t.data[0],l=+t.data[1],o=+t.data[2],r=+t.data[3],p=+t.data[4],d=+t.data[5];i&&(a+=e.x,o+=e.x,p+=e.x,l+=e.y,r+=e.y,d+=e.y);const f=this._bezierTo(a,l,o,r,p,d,e,s);n=n.concat(f),e.bezierReflectionPoint=[p+(p-o),d+(d-r)]}break}case'S':case's':{const a='s'===t.key;if(4<=t.data.length){let l=+t.data[0],o=+t.data[1],r=+t.data[2],p=+t.data[3];a&&(l+=e.x,r+=e.x,o+=e.y,p+=e.y);let d=l,f=o;const h=i?i.key:'';let g=null;('c'===h||'C'===h||'s'===h||'S'===h)&&(g=e.bezierReflectionPoint),g&&(d=g[0],f=g[1]);const c=this._bezierTo(d,f,l,o,r,p,e,s);n=n.concat(c),e.bezierReflectionPoint=[r+(r-l),p+(p-o)]}break}case'Q':case'q':{const i='q'===t.key;if(4<=t.data.length){let a=+t.data[0],l=+t.data[1],o=+t.data[2],r=+t.data[3];i&&(a+=e.x,o+=e.x,l+=e.y,r+=e.y);const p=1*(1+.2*s.roughness),d=1.5*(1+.22*s.roughness);n.push({op:'move',data:[e.x+this.getOffset(-p,p,s),e.y+this.getOffset(-p,p,s)]});let h=[o+this.getOffset(-p,p,s),r+this.getOffset(-p,p,s)];n.push({op:'qcurveTo',data:[a+this.getOffset(-p,p,s),l+this.getOffset(-p,p,s),h[0],h[1]]}),n.push({op:'move',data:[e.x+this.getOffset(-d,d,s),e.y+this.getOffset(-d,d,s)]}),h=[o+this.getOffset(-d,d,s),r+this.getOffset(-d,d,s)],n.push({op:'qcurveTo',data:[a+this.getOffset(-d,d,s),l+this.getOffset(-d,d,s),h[0],h[1]]}),e.setPosition(h[0],h[1]),e.quadReflectionPoint=[o+(o-a),r+(r-l)]}break}case'T':case't':{const a='t'===t.key;if(2<=t.data.length){let l=+t.data[0],o=+t.data[1];a&&(l+=e.x,o+=e.y);let r=l,p=o;const d=i?i.key:'';let h=null;('q'===d||'Q'===d||'t'===d||'T'===d)&&(h=e.quadReflectionPoint),h&&(r=h[0],p=h[1]);const g=1*(1+.2*s.roughness),c=1.5*(1+.22*s.roughness);n.push({op:'move',data:[e.x+this.getOffset(-g,g,s),e.y+this.getOffset(-g,g,s)]});let u=[l+this.getOffset(-g,g,s),o+this.getOffset(-g,g,s)];n.push({op:'qcurveTo',data:[r+this.getOffset(-g,g,s),p+this.getOffset(-g,g,s),u[0],u[1]]}),n.push({op:'move',data:[e.x+this.getOffset(-c,c,s),e.y+this.getOffset(-c,c,s)]}),u=[l+this.getOffset(-c,c,s),o+this.getOffset(-c,c,s)],n.push({op:'qcurveTo',data:[r+this.getOffset(-c,c,s),p+this.getOffset(-c,c,s),u[0],u[1]]}),e.setPosition(u[0],u[1]),e.quadReflectionPoint=[l+(l-r),o+(o-p)]}break}case'A':case'a':{const i='a'===t.key;if(7<=t.data.length){const a=+t.data[0],l=+t.data[1],o=+t.data[2],r=+t.data[3],p=+t.data[4];let d=+t.data[5],f=+t.data[6];if(i&&(d+=e.x,f+=e.y),d===e.x&&f===e.y)break;if(0==a||0==l)n=n.concat(this.doubleLine(e.x,e.y,d,f,s)),e.setPosition(d,f);else for(let t=0;1>t;t++){const t=new v([e.x,e.y],[d,f],[a,l],o,!!r,!!p);for(let i=t.getNextSegment();i;){const a=this._bezierTo(i.cp1[0],i.cp1[1],i.cp2[0],i.cp2[1],i.to[0],i.to[1],e,s);n=n.concat(a),i=t.getNextSegment()}}}break}default:}return n}}const L='undefined'!=typeof self,R=L&&self&&self.document&&self.document.currentScript&&self.document.currentScript.src,D='undefined'!=typeof self;class B{constructor(e,t){this.defaultOptions={maxRandomnessOffset:2,roughness:1,bowing:1,stroke:'#000',strokeWidth:1,curveTightness:0,curveStepCount:9,fillStyle:'hachure',fillWeight:-1,hachureAngle:-41,hachureGap:-1},this.config=e||{},this.surface=t,this.renderer=o(this.config),this.config.options&&(this.defaultOptions=this._options(this.config.options))}_options(e){return e?Object.assign({},this.defaultOptions,e):this.defaultOptions}_drawable(e,t,i){return{shape:e,sets:t||[],options:i||this.defaultOptions}}get lib(){return this.renderer}getCanvasSize(){const e=e=>e&&'object'==typeof e&&e.baseVal&&e.baseVal.value?e.baseVal.value:e||100;return this.surface?[e(this.surface.width),e(this.surface.height)]:[100,100]}computePolygonSize(e){if(e.length){let t=e[0][0],s=e[0][0],n=e[0][1],a=e[0][1];for(let l=1;li&&(i=t.strokeWidth/2),{d:this.opsToPath(e),stroke:t.fill||'none',strokeWidth:i,fill:'none'}}opsToPath(e){let t='';for(const i of e.ops){const e=i.data;switch(i.op){case'move':t+=`M${e[0]} ${e[1]} `;break;case'bcurveTo':t+=`C${e[0]} ${e[1]}, ${e[2]} ${e[3]}, ${e[4]} ${e[5]} `;break;case'qcurveTo':t+=`Q${e[0]} ${e[1]}, ${e[2]} ${e[3]} `;break;case'lineTo':t+=`L${e[0]} ${e[1]} `;}}return t.trim()}}const M='undefined'!=typeof document;class q{constructor(e,t){this.canvas=e,this.ctx=this.canvas.getContext('2d'),this.gen=new B(t||null,this.canvas)}get generator(){return this.gen}static createRenderer(){return new E}line(e,t,i,s,n){const a=this.gen.line(e,t,i,s,n);return this.draw(a),a}rectangle(e,t,i,s,n){const a=this.gen.rectangle(e,t,i,s,n);return this.draw(a),a}ellipse(e,t,i,s,n){const a=this.gen.ellipse(e,t,i,s,n);return this.draw(a),a}circle(e,t,i,s){const n=this.gen.circle(e,t,i,s);return this.draw(n),n}linearPath(e,t){const i=this.gen.linearPath(e,t);return this.draw(i),i}polygon(e,t){const i=this.gen.polygon(e,t);return this.draw(i),i}arc(e,t,i,s,n,a,l=!1,o){const r=this.gen.arc(e,t,i,s,n,a,l,o);return this.draw(r),r}curve(e,t){const i=this.gen.curve(e,t);return this.draw(i),i}path(e,t){const i=this.gen.path(e,t);return this.draw(i),i}draw(e){const t=e.sets||[],i=e.options||this.gen.defaultOptions,s=this.ctx;for(const n of t)switch(n.type){case'path':s.save(),s.strokeStyle=i.stroke,s.lineWidth=i.strokeWidth,this._drawToContext(s,n),s.restore();break;case'fillPath':s.save(),s.fillStyle=i.fill||'',this._drawToContext(s,n),s.restore();break;case'fillSketch':this.fillSketch(s,n,i);break;case'path2Dfill':{this.ctx.save(),this.ctx.fillStyle=i.fill||'';const e=new Path2D(n.path);this.ctx.fill(e),this.ctx.restore();break}case'path2Dpattern':{const e=this.canvas.ownerDocument||M&&document;if(e){const t=n.size,s=e.createElement('canvas'),a=s.getContext('2d'),l=this.computeBBox(n.path);l&&(l.width||l.height)?(s.width=this.canvas.width,s.height=this.canvas.height,a.translate(l.x||0,l.y||0)):(s.width=t[0],s.height=t[1]),this.fillSketch(a,n,i),this.ctx.save(),this.ctx.fillStyle=this.ctx.createPattern(s,'repeat');const o=new Path2D(n.path);this.ctx.fill(o),this.ctx.restore()}else console.error('Cannot render path2Dpattern. No defs/document defined.');break}}}computeBBox(e){if(M)try{const t=document.createElementNS('http://www.w3.org/2000/svg','svg');t.setAttribute('width','0'),t.setAttribute('height','0');const i=self.document.createElementNS('http://www.w3.org/2000/svg','path');i.setAttribute('d',e),t.appendChild(i),document.body.appendChild(t);const s=i.getBBox();return document.body.removeChild(t),s}catch(e){}return null}fillSketch(e,t,i){let s=i.fillWeight;0>s&&(s=i.strokeWidth/2),e.save(),e.strokeStyle=i.fill||'',e.lineWidth=s,this._drawToContext(e,t),e.restore()}_drawToContext(e,t){e.beginPath();for(const i of t.ops){const t=i.data;switch(i.op){case'move':e.moveTo(t[0],t[1]);break;case'bcurveTo':e.bezierCurveTo(t[0],t[1],t[2],t[3],t[4],t[5]);break;case'qcurveTo':e.quadraticCurveTo(t[0],t[1],t[2],t[3]);break;case'lineTo':e.lineTo(t[0],t[1]);}}'fillPath'===t.type?e.fill():e.stroke()}}class F extends B{async line(e,t,i,s,n){const a=this._options(n);return this._drawable('line',[await this.lib.line(e,t,i,s,a)],a)}async rectangle(e,t,i,s,n){const a=this._options(n),l=[];if(a.fill){const n=[[e,t],[e+i,t],[e+i,t+s],[e,t+s]];'solid'===a.fillStyle?l.push((await this.lib.solidFillPolygon(n,a))):l.push((await this.lib.patternFillPolygon(n,a)))}return l.push((await this.lib.rectangle(e,t,i,s,a))),this._drawable('rectangle',l,a)}async ellipse(e,t,i,s,n){const a=this._options(n),l=[];if(a.fill)if('solid'===a.fillStyle){const n=await this.lib.ellipse(e,t,i,s,a);n.type='fillPath',l.push(n)}else l.push((await this.lib.patternFillEllipse(e,t,i,s,a)));return l.push((await this.lib.ellipse(e,t,i,s,a))),this._drawable('ellipse',l,a)}async circle(e,t,i,s){const n=await this.ellipse(e,t,i,i,s);return n.shape='circle',n}async linearPath(e,t){const i=this._options(t);return this._drawable('linearPath',[await this.lib.linearPath(e,!1,i)],i)}async arc(e,t,i,s,n,a,l=!1,r){const p=this._options(r),o=[];if(l&&p.fill)if('solid'===p.fillStyle){const l=await this.lib.arc(e,t,i,s,n,a,!0,!1,p);l.type='fillPath',o.push(l)}else o.push((await this.lib.patternFillArc(e,t,i,s,n,a,p)));return o.push((await this.lib.arc(e,t,i,s,n,a,l,!0,p))),this._drawable('arc',o,p)}async curve(e,t){const i=this._options(t);return this._drawable('curve',[await this.lib.curve(e,i)],i)}async polygon(e,t){const i=this._options(t),s=[];if(i.fill)if('solid'===i.fillStyle)s.push((await this.lib.solidFillPolygon(e,i)));else{const t=this.computePolygonSize(e),n=[[0,0],[t[0],0],[t[0],t[1]],[0,t[1]]],a=await this.lib.patternFillPolygon(n,i);a.type='path2Dpattern',a.size=t,a.path=this.polygonPath(e),s.push(a)}return s.push((await this.lib.linearPath(e,!0,i))),this._drawable('polygon',s,i)}async path(e,t){const i=this._options(t),s=[];if(!e)return this._drawable('path',s,i);if(i.fill)if('solid'===i.fillStyle){s.push({type:'path2Dfill',path:e,ops:[]})}else{const t=this.computePathSize(e),n=[[0,0],[t[0],0],[t[0],t[1]],[0,t[1]]],a=await this.lib.patternFillPolygon(n,i);a.type='path2Dpattern',a.size=t,a.path=e,s.push(a)}return s.push((await this.lib.svgPath(e,i))),this._drawable('path',s,i)}}class U extends q{constructor(e,t){super(e,t),this.genAsync=new F(t||null,this.canvas)}get generator(){return this.genAsync}async line(e,t,i,s,n){const a=await this.genAsync.line(e,t,i,s,n);return this.draw(a),a}async rectangle(e,t,i,s,n){const a=await this.genAsync.rectangle(e,t,i,s,n);return this.draw(a),a}async ellipse(e,t,i,s,n){const a=await this.genAsync.ellipse(e,t,i,s,n);return this.draw(a),a}async circle(e,t,i,s){const n=await this.genAsync.circle(e,t,i,s);return this.draw(n),n}async linearPath(e,t){const i=await this.genAsync.linearPath(e,t);return this.draw(i),i}async polygon(e,t){const i=await this.genAsync.polygon(e,t);return this.draw(i),i}async arc(e,t,i,s,n,a,l=!1,o){const r=await this.genAsync.arc(e,t,i,s,n,a,l,o);return this.draw(r),r}async curve(e,t){const i=await this.genAsync.curve(e,t);return this.draw(i),i}async path(e,t){const i=await this.genAsync.path(e,t);return this.draw(i),i}}const X='undefined'!=typeof document;class G{constructor(e,t){this.svg=e,this.gen=new B(t||null,this.svg)}get generator(){return this.gen}static createRenderer(){return new E}get defs(){const e=this.svg.ownerDocument||X&&document;if(e&&!this._defs){const t=e.createElementNS('http://www.w3.org/2000/svg','defs');this.svg.firstChild?this.svg.insertBefore(t,this.svg.firstChild):this.svg.appendChild(t),this._defs=t}return this._defs||null}line(e,t,i,s,n){const a=this.gen.line(e,t,i,s,n);return this.draw(a)}rectangle(e,t,i,s,n){const a=this.gen.rectangle(e,t,i,s,n);return this.draw(a)}ellipse(e,t,i,s,n){const a=this.gen.ellipse(e,t,i,s,n);return this.draw(a)}circle(e,t,i,s){const n=this.gen.circle(e,t,i,s);return this.draw(n)}linearPath(e,t){const i=this.gen.linearPath(e,t);return this.draw(i)}polygon(e,t){const i=this.gen.polygon(e,t);return this.draw(i)}arc(e,t,i,s,n,a,l=!1,o){const r=this.gen.arc(e,t,i,s,n,a,l,o);return this.draw(r)}curve(e,t){const i=this.gen.curve(e,t);return this.draw(i)}path(e,t){const i=this.gen.path(e,t);return this.draw(i)}draw(e){const t=e.sets||[],i=e.options||this.gen.defaultOptions,s=this.svg.ownerDocument||X&&document,n=s.createElementNS('http://www.w3.org/2000/svg','g');for(const a of t){let e=null;switch(a.type){case'path':{e=s.createElementNS('http://www.w3.org/2000/svg','path'),e.setAttribute('d',this.opsToPath(a)),e.style.stroke=i.stroke,e.style.strokeWidth=i.strokeWidth+'',e.style.fill='none';break}case'fillPath':{e=s.createElementNS('http://www.w3.org/2000/svg','path'),e.setAttribute('d',this.opsToPath(a)),e.style.stroke='none',e.style.strokeWidth='0',e.style.fill=i.fill||null;break}case'fillSketch':{e=this.fillSketch(s,a,i);break}case'path2Dfill':{e=s.createElementNS('http://www.w3.org/2000/svg','path'),e.setAttribute('d',a.path||''),e.style.stroke='none',e.style.strokeWidth='0',e.style.fill=i.fill||null;break}case'path2Dpattern':{if(!this.defs)console.error('Cannot render path2Dpattern. No defs/document defined.');else{const t=a.size,n=s.createElementNS('http://www.w3.org/2000/svg','pattern'),l=`rough-${c(Math.random()*(Number.MAX_SAFE_INTEGER||999999))}`;n.setAttribute('id',l),n.setAttribute('x','0'),n.setAttribute('y','0'),n.setAttribute('width','1'),n.setAttribute('height','1'),n.setAttribute('height','1'),n.setAttribute('viewBox',`0 0 ${r(t[0])} ${r(t[1])}`),n.setAttribute('patternUnits','objectBoundingBox');const o=this.fillSketch(s,a,i);n.appendChild(o),this.defs.appendChild(n),e=s.createElementNS('http://www.w3.org/2000/svg','path'),e.setAttribute('d',a.path||''),e.style.stroke='none',e.style.strokeWidth='0',e.style.fill=`url(#${l})`}break}}e&&n.appendChild(e)}return n}opsToPath(e){return this.gen.opsToPath(e)}fillSketch(e,t,i){let s=i.fillWeight;0>s&&(s=i.strokeWidth/2);const n=e.createElementNS('http://www.w3.org/2000/svg','path');return n.setAttribute('d',this.opsToPath(t)),n.style.stroke=i.fill||null,n.style.strokeWidth=s+'',n.style.fill='none',n}}class V extends G{constructor(e,t){super(e,t),this.genAsync=new F(t||null,this.svg)}get generator(){return this.genAsync}async line(e,t,i,s,n){const a=await this.genAsync.line(e,t,i,s,n);return this.draw(a)}async rectangle(e,t,i,s,n){const a=await this.genAsync.rectangle(e,t,i,s,n);return this.draw(a)}async ellipse(e,t,i,s,n){const a=await this.genAsync.ellipse(e,t,i,s,n);return this.draw(a)}async circle(e,t,i,s){const n=await this.genAsync.circle(e,t,i,s);return this.draw(n)}async linearPath(e,t){const i=await this.genAsync.linearPath(e,t);return this.draw(i)}async polygon(e,t){const i=await this.genAsync.polygon(e,t);return this.draw(i)}async arc(e,t,i,s,n,a,l=!1,o){const r=await this.genAsync.arc(e,t,i,s,n,a,l,o);return this.draw(r)}async curve(e,t){const i=await this.genAsync.curve(e,t);return this.draw(i)}async path(e,t){const i=await this.genAsync.path(e,t);return this.draw(i)}}var j={canvas(e,t){return t&&t.async?new U(e,t):new q(e,t)},svg(e,t){return t&&t.async?new V(e,t):new G(e,t)},createRenderer(){return q.createRenderer()},generator(e,t){return e&&e.async?new F(e,t):new B(e,t)}};return j}(); +var rough=function(){'use strict';function e(e,t){return e.type===t}function t(e){const t=e[0],i=e[1];return y(g(t[0]-i[0],2)+g(t[1]-i[1],2))}function i(e,t){const s=[],n=new A([e[0],e[1]],[e[2],e[3]]);for(let a=0;ah&&(h=4*t.strokeWidth),h=d(h,.1);const g=p%180*(b/180),c=_(g),u=w(g),y=r(g),x=new S(l-1,o+1,n-1,a+1,h,u,c,y);for(let t;null!=(t=x.nextLine());){const n=i(t,e);for(let e=0;e=h&&(h=4*a.strokeWidth);let g=a.fillWeight;0>g&&(g=a.strokeWidth/2);const c=r(f%180*(b/180)),u=d/p,_=y(u*c*u*c+1),x=u*c/_,w=1/_,O=h/(p*d/y(d*w*(d*w)+p*x*(p*x))/p);let P=y(p*p-(e-p+O)*(e-p+O));for(let r=e-p+O;rd){const e=y(1-d/(this._rx*this._rx*this._ry*this._ry));this._rx*=e,this._ry*=e,r=0}else r=(n===a?-1:1)*y(d/(this._rx*this._rx*p*p+this._ry*this._ry*o*o));const f=r*this._rx*p/this._ry,h=-r*this._ry*o/this._rx;this._C=[0,0],this._C[0]=this._cosPhi*f-this._sinPhi*h+(e[0]+t[0])/2,this._C[1]=this._sinPhi*f+this._cosPhi*h+(e[1]+t[1])/2,this._theta=this.calculateVectorAngle(1,0,(o-f)/this._rx,(p-h)/this._ry);let g=this.calculateVectorAngle((o-f)/this._rx,(p-h)/this._ry,(-o-f)/this._rx,(-p-h)/this._ry);!a&&0g&&(g+=2*b),this._numSegs=u(m(g/(b/2))),this._delta=g/this._numSegs,this._T=8/3*w(this._delta/4)*w(this._delta/4)/w(this._delta/2)}getNextSegment(){if(this._segIndex===this._numSegs)return null;const e=_(this._theta),t=w(this._theta),i=this._theta+this._delta,s=_(i),n=w(i),a=[this._cosPhi*this._rx*s-this._sinPhi*this._ry*n+this._C[0],this._sinPhi*this._rx*s+this._cosPhi*this._ry*n+this._C[1]],l=[this._from[0]+this._T*(-this._cosPhi*this._rx*t-this._sinPhi*this._ry*e),this._from[1]+this._T*(-this._sinPhi*this._rx*t+this._cosPhi*this._ry*e)],o=[a[0]+this._T*(this._cosPhi*this._rx*n+this._sinPhi*this._ry*s),a[1]+this._T*(this._sinPhi*this._rx*n-this._cosPhi*this._ry*s)];return this._theta=i,this._from=[a[0],a[1]],this._segIndex++,{cp1:l,cp2:o,to:a}}calculateVectorAngle(e,t,i,s){var n=Math.atan2;const a=n(t,e),l=n(s,i);return l>=a?l-a:2*b-(a-l)}}class k{constructor(e,t){this.sets=e,this.closed=t}fit(e){const t=[];for(const i of this.sets){const s=i.length;let n=c(e*s);if(5>n){if(5>=s)continue;n=5}t.push(this.reduce(i,n))}let s='';for(const n of t){for(let e=0;et;){let e=-1,t=-1;for(let l=1;le||s=f(e.py1,e.py2)&&this.py1<=d(e.py1,e.py2)?(this.xi=this.px1,this.yi=this.py1,!0):!!(this.py2>=f(e.py1,e.py2)&&this.py2<=d(e.py1,e.py2))&&(this.xi=this.px2,this.yi=this.py2,!0)):(this.xi=this.px1,this.yi=i*this.xi+n,!(-1e-5>(this.py1-this.yi)*(this.yi-this.py2)||-1e-5>(e.py1-this.yi)*(this.yi-e.py2))&&(!(1e-5>m(e.a))||!(-1e-5>(e.px1-this.xi)*(this.xi-e.px2)))):i===h?(this.xi=e.px1,this.yi=t*this.xi+s,!(-1e-5>(e.py1-this.yi)*(this.yi-e.py2)||-1e-5>(this.py1-this.yi)*(this.yi-this.py2))&&(!(1e-5>m(l))||!(-1e-5>(this.px1-this.xi)*(this.xi-this.px2)))):t===i?s==n&&(this.px1>=f(e.px1,e.px2)&&this.px1<=d(e.py1,e.py2)?(this.xi=this.px1,this.yi=this.py1,!0):!!(this.px2>=f(e.px1,e.px2)&&this.px2<=d(e.px1,e.px2))&&(this.xi=this.px2,this.yi=this.py2,!0)):(this.xi=(n-s)/(t-i),this.yi=t*this.xi+s,!(-1e-5>(this.px1-this.xi)*(this.xi-this.px2)||-1e-5>(e.px1-this.xi)*(this.xi-e.px2)))}}class S{constructor(e,t,i,s,n,a,l,o){this.deltaX=0,this.hGap=0,this.top=e,this.bottom=t,this.left=i,this.right=s,this.gap=n,this.sinAngle=a,this.tanAngle=o,1e-4>m(a)?this.pos=i+n:.9999m(this.sinAngle)){if(this.posthis.right&&t>this.right;)if(this.pos+=this.hGap,e=this.pos-this.deltaX/2,t=this.pos+this.deltaX/2,this.pos>this.right+this.deltaX)return null;const a=new A([e,i],[t,n]);this.sLeft&&a.intersects(this.sLeft)&&(e=a.xi,i=a.yi),this.sRight&&a.intersects(this.sRight)&&(t=a.xi,n=a.yi),0a&&(a=4*s.strokeWidth),a=d(a,.1);let o=s.fillWeight;0>o&&(o=s.strokeWidth/2);for(const p of e){const e=t(p),i=e/a,l=u(i)-1,r=Math.atan((p[1][1]-p[0][1])/(p[1][0]-p[0][0]));for(let e=0;ec;)c+=2*b,u+=2*b;u-c>2*b&&(c=0,u=2*b);const y=2*b/r.curveStepCount,x=f(y/2,(u-c)/2),O=this._arc(x,o,d,h,g,c,u,1,r),P=this._arc(x,o,d,h,g,c,u,1.5,r);let v=O.concat(P);return l&&(p?(v=v.concat(this.doubleLine(o,d,o+h*_(c),d+g*w(c),r)),v=v.concat(this.doubleLine(o,d,o+h*_(u),d+g*w(u),r))):(v.push({op:'lineTo',data:[o,d]}),v.push({op:'lineTo',data:[o+h*_(c),d+g*w(c)]}))),{type:'path',ops:v}}svgPath(e,t){e=(e||'').replace(/\n/g,' ').replace(/(-\s)/g,'-').replace('/(ss)/g',' ');let n=new P(e);if(t.simplification){const e=new k(n.linearPoints,n.closed),i=e.fit(t.simplification);n=new P(i)}let a=[];const l=n.segments||[];for(let o=0;of;)f+=2*b,h+=2*b;h-f>2*b&&(f=0,h=2*b);const g=(h-f)/l.curveStepCount,c=[];for(let u=f;u<=h;u+=g)c.push([o+r*_(u),p+d*w(u)]);return c.push([o+r*_(h),p+d*w(h)]),c.push([o,p]),this.patternFillPolygon(c,l)}getOffset(e,t,i){return i.roughness*(Math.random()*(t-e)+e)}doubleLine(e,t,i,s,n){const a=this._line(e,t,i,s,n,!0,!1),l=this._line(e,t,i,s,n,!0,!0);return a.concat(l)}_line(e,t,i,s,n,a,l){const o=g(e-i,2)+g(t-s,2);let p=n.maxRandomnessOffset||0;100*(p*p)>o&&(p=y(o)/10);const r=p/2,d=.2+.2*Math.random();let f=n.bowing*n.maxRandomnessOffset*(s-t)/200,h=n.bowing*n.maxRandomnessOffset*(e-i)/200;f=this.getOffset(-f,f,n),h=this.getOffset(-h,h,n);const c=[];return a&&(l?c.push({op:'move',data:[e+this.getOffset(-r,r,n),t+this.getOffset(-r,r,n)]}):c.push({op:'move',data:[e+this.getOffset(-p,p,n),t+this.getOffset(-p,p,n)]})),l?c.push({op:'bcurveTo',data:[f+e+(i-e)*d+this.getOffset(-r,r,n),h+t+(s-t)*d+this.getOffset(-r,r,n),f+e+2*(i-e)*d+this.getOffset(-r,r,n),h+t+2*(s-t)*d+this.getOffset(-r,r,n),i+this.getOffset(-r,r,n),s+this.getOffset(-r,r,n)]}):c.push({op:'bcurveTo',data:[f+e+(i-e)*d+this.getOffset(-p,p,n),h+t+(s-t)*d+this.getOffset(-p,p,n),f+e+2*(i-e)*d+this.getOffset(-p,p,n),h+t+2*(s-t)*d+this.getOffset(-p,p,n),i+this.getOffset(-p,p,n),s+this.getOffset(-p,p,n)]}),c}_curve(e,t,i){const n=e.length;let a=[];if(3f;f++)0===f?o.push({op:'move',data:[p.x,p.y]}):o.push({op:'move',data:[p.x+this.getOffset(-d[0],d[0],r),p.y+this.getOffset(-d[0],d[0],r)]}),h=[a+this.getOffset(-d[f],d[f],r),l+this.getOffset(-d[f],d[f],r)],o.push({op:'bcurveTo',data:[e+this.getOffset(-d[f],d[f],r),t+this.getOffset(-d[f],d[f],r),s+this.getOffset(-d[f],d[f],r),n+this.getOffset(-d[f],d[f],r),h[0],h[1]]});return p.setPosition(h[0],h[1]),o}_processSegment(e,t,i,s){let n=[];switch(t.key){case'M':case'm':{const i='m'===t.key;if(2<=t.data.length){let a=+t.data[0],l=+t.data[1];i&&(a+=e.x,l+=e.y);const o=1*(s.maxRandomnessOffset||0);a+=this.getOffset(-o,o,s),l+=this.getOffset(-o,o,s),e.setPosition(a,l),n.push({op:'move',data:[a,l]})}break}case'L':case'l':{const i='l'===t.key;if(2<=t.data.length){let a=+t.data[0],l=+t.data[1];i&&(a+=e.x,l+=e.y),n=n.concat(this.doubleLine(e.x,e.y,a,l,s)),e.setPosition(a,l)}break}case'H':case'h':{const i='h'===t.key;if(t.data.length){let a=+t.data[0];i&&(a+=e.x),n=n.concat(this.doubleLine(e.x,e.y,a,e.y,s)),e.setPosition(a,e.y)}break}case'V':case'v':{const i='v'===t.key;if(t.data.length){let a=+t.data[0];i&&(a+=e.y),n=n.concat(this.doubleLine(e.x,e.y,e.x,a,s)),e.setPosition(e.x,a)}break}case'Z':case'z':{e.first&&(n=n.concat(this.doubleLine(e.x,e.y,e.first[0],e.first[1],s)),e.setPosition(e.first[0],e.first[1]),e.first=null);break}case'C':case'c':{const i='c'===t.key;if(6<=t.data.length){let a=+t.data[0],l=+t.data[1],o=+t.data[2],p=+t.data[3],r=+t.data[4],d=+t.data[5];i&&(a+=e.x,o+=e.x,r+=e.x,l+=e.y,p+=e.y,d+=e.y);const f=this._bezierTo(a,l,o,p,r,d,e,s);n=n.concat(f),e.bezierReflectionPoint=[r+(r-o),d+(d-p)]}break}case'S':case's':{const a='s'===t.key;if(4<=t.data.length){let l=+t.data[0],o=+t.data[1],p=+t.data[2],r=+t.data[3];a&&(l+=e.x,p+=e.x,o+=e.y,r+=e.y);let d=l,f=o;const h=i?i.key:'';let g=null;('c'===h||'C'===h||'s'===h||'S'===h)&&(g=e.bezierReflectionPoint),g&&(d=g[0],f=g[1]);const c=this._bezierTo(d,f,l,o,p,r,e,s);n=n.concat(c),e.bezierReflectionPoint=[p+(p-l),r+(r-o)]}break}case'Q':case'q':{const i='q'===t.key;if(4<=t.data.length){let a=+t.data[0],l=+t.data[1],o=+t.data[2],p=+t.data[3];i&&(a+=e.x,o+=e.x,l+=e.y,p+=e.y);const r=1*(1+.2*s.roughness),d=1.5*(1+.22*s.roughness);n.push({op:'move',data:[e.x+this.getOffset(-r,r,s),e.y+this.getOffset(-r,r,s)]});let h=[o+this.getOffset(-r,r,s),p+this.getOffset(-r,r,s)];n.push({op:'qcurveTo',data:[a+this.getOffset(-r,r,s),l+this.getOffset(-r,r,s),h[0],h[1]]}),n.push({op:'move',data:[e.x+this.getOffset(-d,d,s),e.y+this.getOffset(-d,d,s)]}),h=[o+this.getOffset(-d,d,s),p+this.getOffset(-d,d,s)],n.push({op:'qcurveTo',data:[a+this.getOffset(-d,d,s),l+this.getOffset(-d,d,s),h[0],h[1]]}),e.setPosition(h[0],h[1]),e.quadReflectionPoint=[o+(o-a),p+(p-l)]}break}case'T':case't':{const a='t'===t.key;if(2<=t.data.length){let l=+t.data[0],o=+t.data[1];a&&(l+=e.x,o+=e.y);let p=l,r=o;const d=i?i.key:'';let h=null;('q'===d||'Q'===d||'t'===d||'T'===d)&&(h=e.quadReflectionPoint),h&&(p=h[0],r=h[1]);const g=1*(1+.2*s.roughness),c=1.5*(1+.22*s.roughness);n.push({op:'move',data:[e.x+this.getOffset(-g,g,s),e.y+this.getOffset(-g,g,s)]});let u=[l+this.getOffset(-g,g,s),o+this.getOffset(-g,g,s)];n.push({op:'qcurveTo',data:[p+this.getOffset(-g,g,s),r+this.getOffset(-g,g,s),u[0],u[1]]}),n.push({op:'move',data:[e.x+this.getOffset(-c,c,s),e.y+this.getOffset(-c,c,s)]}),u=[l+this.getOffset(-c,c,s),o+this.getOffset(-c,c,s)],n.push({op:'qcurveTo',data:[p+this.getOffset(-c,c,s),r+this.getOffset(-c,c,s),u[0],u[1]]}),e.setPosition(u[0],u[1]),e.quadReflectionPoint=[l+(l-p),o+(o-r)]}break}case'A':case'a':{const i='a'===t.key;if(7<=t.data.length){const a=+t.data[0],l=+t.data[1],o=+t.data[2],p=+t.data[3],r=+t.data[4];let d=+t.data[5],f=+t.data[6];if(i&&(d+=e.x,f+=e.y),d===e.x&&f===e.y)break;if(0==a||0==l)n=n.concat(this.doubleLine(e.x,e.y,d,f,s)),e.setPosition(d,f);else for(let t=0;1>t;t++){const t=new v([e.x,e.y],[d,f],[a,l],o,!!p,!!r);for(let i=t.getNextSegment();i;){const a=this._bezierTo(i.cp1[0],i.cp1[1],i.cp2[0],i.cp2[1],i.to[0],i.to[1],e,s);n=n.concat(a),i=t.getNextSegment()}}}break}default:}return n}}const L='undefined'!=typeof self,D=L&&self&&self.document&&self.document.currentScript&&self.document.currentScript.src,R='undefined'!=typeof self;class B{constructor(e,t){this.defaultOptions={maxRandomnessOffset:2,roughness:1,bowing:1,stroke:'#000',strokeWidth:1,curveTightness:0,curveStepCount:9,fillStyle:'hachure',fillWeight:-1,hachureAngle:-41,hachureGap:-1},this.config=e||{},this.surface=t,this.renderer=o(this.config),this.config.options&&(this.defaultOptions=this._options(this.config.options))}_options(e){return e?Object.assign({},this.defaultOptions,e):this.defaultOptions}_drawable(e,t,i){return{shape:e,sets:t||[],options:i||this.defaultOptions}}get lib(){return this.renderer}getCanvasSize(){const e=e=>e&&'object'==typeof e&&e.baseVal&&e.baseVal.value?e.baseVal.value:e||100;return this.surface?[e(this.surface.width),e(this.surface.height)]:[100,100]}computePolygonSize(e){if(e.length){let t=e[0][0],s=e[0][0],n=e[0][1],a=e[0][1];for(let l=1;li&&(i=t.strokeWidth/2),{d:this.opsToPath(e),stroke:t.fill||'none',strokeWidth:i,fill:'none'}}opsToPath(e){let t='';for(const i of e.ops){const e=i.data;switch(i.op){case'move':t+=`M${e[0]} ${e[1]} `;break;case'bcurveTo':t+=`C${e[0]} ${e[1]}, ${e[2]} ${e[3]}, ${e[4]} ${e[5]} `;break;case'qcurveTo':t+=`Q${e[0]} ${e[1]}, ${e[2]} ${e[3]} `;break;case'lineTo':t+=`L${e[0]} ${e[1]} `;}}return t.trim()}}class M extends B{constructor(e,t){super(e,t)}line(e,t,i,s,n){const a=this._options(n);return this._drawable('line',[this.lib.line(e,t,i,s,a)],a)}rectangle(e,t,i,s,n){const a=this._options(n),l=[];if(a.fill){const n=[[e,t],[e+i,t],[e+i,t+s],[e,t+s]];'solid'===a.fillStyle?l.push(this.lib.solidFillPolygon(n,a)):l.push(this.lib.patternFillPolygon(n,a))}return l.push(this.lib.rectangle(e,t,i,s,a)),this._drawable('rectangle',l,a)}ellipse(e,t,i,s,n){const a=this._options(n),l=[];if(a.fill)if('solid'===a.fillStyle){const n=this.lib.ellipse(e,t,i,s,a);n.type='fillPath',l.push(n)}else l.push(this.lib.patternFillEllipse(e,t,i,s,a));return l.push(this.lib.ellipse(e,t,i,s,a)),this._drawable('ellipse',l,a)}circle(e,t,i,s){const n=this.ellipse(e,t,i,i,s);return n.shape='circle',n}linearPath(e,t){const i=this._options(t);return this._drawable('linearPath',[this.lib.linearPath(e,!1,i)],i)}arc(e,t,i,s,n,a,l=!1,p){const r=this._options(p),o=[];if(l&&r.fill)if('solid'===r.fillStyle){const l=this.lib.arc(e,t,i,s,n,a,!0,!1,r);l.type='fillPath',o.push(l)}else o.push(this.lib.patternFillArc(e,t,i,s,n,a,r));return o.push(this.lib.arc(e,t,i,s,n,a,l,!0,r)),this._drawable('arc',o,r)}curve(e,t){const i=this._options(t);return this._drawable('curve',[this.lib.curve(e,i)],i)}polygon(e,t){const i=this._options(t),s=[];if(i.fill)if('solid'===i.fillStyle)s.push(this.lib.solidFillPolygon(e,i));else{const t=this.computePolygonSize(e),n=[[0,0],[t[0],0],[t[0],t[1]],[0,t[1]]],a=this.lib.patternFillPolygon(n,i);a.type='path2Dpattern',a.size=t,a.path=this.polygonPath(e),s.push(a)}return s.push(this.lib.linearPath(e,!0,i)),this._drawable('polygon',s,i)}path(e,t){const i=this._options(t),s=[];if(!e)return this._drawable('path',s,i);if(i.fill)if('solid'===i.fillStyle){s.push({type:'path2Dfill',path:e,ops:[]})}else{const t=this.computePathSize(e),n=[[0,0],[t[0],0],[t[0],t[1]],[0,t[1]]],a=this.lib.patternFillPolygon(n,i);a.type='path2Dpattern',a.size=t,a.path=e,s.push(a)}return s.push(this.lib.svgPath(e,i)),this._drawable('path',s,i)}}const q='undefined'!=typeof document;class F{constructor(e){this.canvas=e,this.ctx=this.canvas.getContext('2d')}static createRenderer(){return new E}draw(e){const t=e.sets||[],i=e.options||this.getDefaultOptions(),s=this.ctx;for(const n of t)switch(n.type){case'path':s.save(),s.strokeStyle=i.stroke,s.lineWidth=i.strokeWidth,this._drawToContext(s,n),s.restore();break;case'fillPath':s.save(),s.fillStyle=i.fill||'',this._drawToContext(s,n),s.restore();break;case'fillSketch':this.fillSketch(s,n,i);break;case'path2Dfill':{this.ctx.save(),this.ctx.fillStyle=i.fill||'';const e=new Path2D(n.path);this.ctx.fill(e),this.ctx.restore();break}case'path2Dpattern':{const e=this.canvas.ownerDocument||q&&document;if(e){const t=n.size,s=e.createElement('canvas'),a=s.getContext('2d'),l=this.computeBBox(n.path);l&&(l.width||l.height)?(s.width=this.canvas.width,s.height=this.canvas.height,a.translate(l.x||0,l.y||0)):(s.width=t[0],s.height=t[1]),this.fillSketch(a,n,i),this.ctx.save(),this.ctx.fillStyle=this.ctx.createPattern(s,'repeat');const o=new Path2D(n.path);this.ctx.fill(o),this.ctx.restore()}else console.error('Cannot render path2Dpattern. No defs/document defined.');break}}}computeBBox(e){if(q)try{const t=document.createElementNS('http://www.w3.org/2000/svg','svg');t.setAttribute('width','0'),t.setAttribute('height','0');const i=self.document.createElementNS('http://www.w3.org/2000/svg','path');i.setAttribute('d',e),t.appendChild(i),document.body.appendChild(t);const s=i.getBBox();return document.body.removeChild(t),s}catch(e){}return null}fillSketch(e,t,i){let s=i.fillWeight;0>s&&(s=i.strokeWidth/2),e.save(),e.strokeStyle=i.fill||'',e.lineWidth=s,this._drawToContext(e,t),e.restore()}_drawToContext(e,t){e.beginPath();for(const i of t.ops){const t=i.data;switch(i.op){case'move':e.moveTo(t[0],t[1]);break;case'bcurveTo':e.bezierCurveTo(t[0],t[1],t[2],t[3],t[4],t[5]);break;case'qcurveTo':e.quadraticCurveTo(t[0],t[1],t[2],t[3]);break;case'lineTo':e.lineTo(t[0],t[1]);}}'fillPath'===t.type?e.fill():e.stroke()}}class U extends F{constructor(e,t){super(e),this.gen=new M(t||null,this.canvas)}get generator(){return this.gen}getDefaultOptions(){return this.gen.defaultOptions}line(e,t,i,s,n){const a=this.gen.line(e,t,i,s,n);return this.draw(a),a}rectangle(e,t,i,s,n){const a=this.gen.rectangle(e,t,i,s,n);return this.draw(a),a}ellipse(e,t,i,s,n){const a=this.gen.ellipse(e,t,i,s,n);return this.draw(a),a}circle(e,t,i,s){const n=this.gen.circle(e,t,i,s);return this.draw(n),n}linearPath(e,t){const i=this.gen.linearPath(e,t);return this.draw(i),i}polygon(e,t){const i=this.gen.polygon(e,t);return this.draw(i),i}arc(e,t,i,s,n,a,l=!1,o){const p=this.gen.arc(e,t,i,s,n,a,l,o);return this.draw(p),p}curve(e,t){const i=this.gen.curve(e,t);return this.draw(i),i}path(e,t){const i=this.gen.path(e,t);return this.draw(i),i}}class X extends B{async line(e,t,i,s,n){const a=this._options(n);return this._drawable('line',[await this.lib.line(e,t,i,s,a)],a)}async rectangle(e,t,i,s,n){const a=this._options(n),l=[];if(a.fill){const n=[[e,t],[e+i,t],[e+i,t+s],[e,t+s]];'solid'===a.fillStyle?l.push((await this.lib.solidFillPolygon(n,a))):l.push((await this.lib.patternFillPolygon(n,a)))}return l.push((await this.lib.rectangle(e,t,i,s,a))),this._drawable('rectangle',l,a)}async ellipse(e,t,i,s,n){const a=this._options(n),l=[];if(a.fill)if('solid'===a.fillStyle){const n=await this.lib.ellipse(e,t,i,s,a);n.type='fillPath',l.push(n)}else l.push((await this.lib.patternFillEllipse(e,t,i,s,a)));return l.push((await this.lib.ellipse(e,t,i,s,a))),this._drawable('ellipse',l,a)}async circle(e,t,i,s){const n=await this.ellipse(e,t,i,i,s);return n.shape='circle',n}async linearPath(e,t){const i=this._options(t);return this._drawable('linearPath',[await this.lib.linearPath(e,!1,i)],i)}async arc(e,t,i,s,n,a,l=!1,p){const r=this._options(p),o=[];if(l&&r.fill)if('solid'===r.fillStyle){const l=await this.lib.arc(e,t,i,s,n,a,!0,!1,r);l.type='fillPath',o.push(l)}else o.push((await this.lib.patternFillArc(e,t,i,s,n,a,r)));return o.push((await this.lib.arc(e,t,i,s,n,a,l,!0,r))),this._drawable('arc',o,r)}async curve(e,t){const i=this._options(t);return this._drawable('curve',[await this.lib.curve(e,i)],i)}async polygon(e,t){const i=this._options(t),s=[];if(i.fill)if('solid'===i.fillStyle)s.push((await this.lib.solidFillPolygon(e,i)));else{const t=this.computePolygonSize(e),n=[[0,0],[t[0],0],[t[0],t[1]],[0,t[1]]],a=await this.lib.patternFillPolygon(n,i);a.type='path2Dpattern',a.size=t,a.path=this.polygonPath(e),s.push(a)}return s.push((await this.lib.linearPath(e,!0,i))),this._drawable('polygon',s,i)}async path(e,t){const i=this._options(t),s=[];if(!e)return this._drawable('path',s,i);if(i.fill)if('solid'===i.fillStyle){s.push({type:'path2Dfill',path:e,ops:[]})}else{const t=this.computePathSize(e),n=[[0,0],[t[0],0],[t[0],t[1]],[0,t[1]]],a=await this.lib.patternFillPolygon(n,i);a.type='path2Dpattern',a.size=t,a.path=e,s.push(a)}return s.push((await this.lib.svgPath(e,i))),this._drawable('path',s,i)}}class G extends F{constructor(e,t){super(e),this.genAsync=new X(t||null,this.canvas)}get generator(){return this.genAsync}getDefaultOptions(){return this.genAsync.defaultOptions}async line(e,t,i,s,n){const a=await this.genAsync.line(e,t,i,s,n);return this.draw(a),a}async rectangle(e,t,i,s,n){const a=await this.genAsync.rectangle(e,t,i,s,n);return this.draw(a),a}async ellipse(e,t,i,s,n){const a=await this.genAsync.ellipse(e,t,i,s,n);return this.draw(a),a}async circle(e,t,i,s){const n=await this.genAsync.circle(e,t,i,s);return this.draw(n),n}async linearPath(e,t){const i=await this.genAsync.linearPath(e,t);return this.draw(i),i}async polygon(e,t){const i=await this.genAsync.polygon(e,t);return this.draw(i),i}async arc(e,t,i,s,n,a,l=!1,o){const p=await this.genAsync.arc(e,t,i,s,n,a,l,o);return this.draw(p),p}async curve(e,t){const i=await this.genAsync.curve(e,t);return this.draw(i),i}async path(e,t){const i=await this.genAsync.path(e,t);return this.draw(i),i}}const V='undefined'!=typeof document;class j{constructor(e){this.svg=e}static createRenderer(){return new E}get defs(){const e=this.svg.ownerDocument||V&&document;if(e&&!this._defs){const t=e.createElementNS('http://www.w3.org/2000/svg','defs');this.svg.firstChild?this.svg.insertBefore(t,this.svg.firstChild):this.svg.appendChild(t),this._defs=t}return this._defs||null}draw(e){const t=e.sets||[],i=e.options||this.getDefaultOptions(),s=this.svg.ownerDocument||V&&document,n=s.createElementNS('http://www.w3.org/2000/svg','g');for(const a of t){let e=null;switch(a.type){case'path':{e=s.createElementNS('http://www.w3.org/2000/svg','path'),e.setAttribute('d',this.opsToPath(a)),e.style.stroke=i.stroke,e.style.strokeWidth=i.strokeWidth+'',e.style.fill='none';break}case'fillPath':{e=s.createElementNS('http://www.w3.org/2000/svg','path'),e.setAttribute('d',this.opsToPath(a)),e.style.stroke='none',e.style.strokeWidth='0',e.style.fill=i.fill||null;break}case'fillSketch':{e=this.fillSketch(s,a,i);break}case'path2Dfill':{e=s.createElementNS('http://www.w3.org/2000/svg','path'),e.setAttribute('d',a.path||''),e.style.stroke='none',e.style.strokeWidth='0',e.style.fill=i.fill||null;break}case'path2Dpattern':{if(!this.defs)console.error('Cannot render path2Dpattern. No defs/document defined.');else{const t=a.size,n=s.createElementNS('http://www.w3.org/2000/svg','pattern'),l=`rough-${c(Math.random()*(Number.MAX_SAFE_INTEGER||999999))}`;n.setAttribute('id',l),n.setAttribute('x','0'),n.setAttribute('y','0'),n.setAttribute('width','1'),n.setAttribute('height','1'),n.setAttribute('height','1'),n.setAttribute('viewBox',`0 0 ${p(t[0])} ${p(t[1])}`),n.setAttribute('patternUnits','objectBoundingBox');const o=this.fillSketch(s,a,i);n.appendChild(o),this.defs.appendChild(n),e=s.createElementNS('http://www.w3.org/2000/svg','path'),e.setAttribute('d',a.path||''),e.style.stroke='none',e.style.strokeWidth='0',e.style.fill=`url(#${l})`}break}}e&&n.appendChild(e)}return n}fillSketch(e,t,i){let s=i.fillWeight;0>s&&(s=i.strokeWidth/2);const n=e.createElementNS('http://www.w3.org/2000/svg','path');return n.setAttribute('d',this.opsToPath(t)),n.style.stroke=i.fill||null,n.style.strokeWidth=s+'',n.style.fill='none',n}}class I extends j{constructor(e,t){super(e),this.gen=new M(t||null,this.svg)}get generator(){return this.gen}getDefaultOptions(){return this.gen.defaultOptions}opsToPath(e){return this.gen.opsToPath(e)}line(e,t,i,s,n){const a=this.gen.line(e,t,i,s,n);return this.draw(a)}rectangle(e,t,i,s,n){const a=this.gen.rectangle(e,t,i,s,n);return this.draw(a)}ellipse(e,t,i,s,n){const a=this.gen.ellipse(e,t,i,s,n);return this.draw(a)}circle(e,t,i,s){const n=this.gen.circle(e,t,i,s);return this.draw(n)}linearPath(e,t){const i=this.gen.linearPath(e,t);return this.draw(i)}polygon(e,t){const i=this.gen.polygon(e,t);return this.draw(i)}arc(e,t,i,s,n,a,l=!1,o){const p=this.gen.arc(e,t,i,s,n,a,l,o);return this.draw(p)}curve(e,t){const i=this.gen.curve(e,t);return this.draw(i)}path(e,t){const i=this.gen.path(e,t);return this.draw(i)}}class $ extends j{constructor(e,t){super(e),this.genAsync=new X(t||null,this.svg)}get generator(){return this.genAsync}getDefaultOptions(){return this.genAsync.defaultOptions}opsToPath(e){return this.genAsync.opsToPath(e)}async line(e,t,i,s,n){const a=await this.genAsync.line(e,t,i,s,n);return this.draw(a)}async rectangle(e,t,i,s,n){const a=await this.genAsync.rectangle(e,t,i,s,n);return this.draw(a)}async ellipse(e,t,i,s,n){const a=await this.genAsync.ellipse(e,t,i,s,n);return this.draw(a)}async circle(e,t,i,s){const n=await this.genAsync.circle(e,t,i,s);return this.draw(n)}async linearPath(e,t){const i=await this.genAsync.linearPath(e,t);return this.draw(i)}async polygon(e,t){const i=await this.genAsync.polygon(e,t);return this.draw(i)}async arc(e,t,i,s,n,a,l=!1,o){const p=await this.genAsync.arc(e,t,i,s,n,a,l,o);return this.draw(p)}async curve(e,t){const i=await this.genAsync.curve(e,t);return this.draw(i)}async path(e,t){const i=await this.genAsync.path(e,t);return this.draw(i)}}var Q={canvas(e,t){return t&&t.async?new G(e,t):new U(e,t)},svg(e,t){return t&&t.async?new $(e,t):new I(e,t)},createRenderer(){return U.createRenderer()},generator(e,t){return e&&e.async?new X(e,t):new M(e,t)}};return Q}(); diff --git a/dist/rough.umd.es5.js b/dist/rough.umd.es5.js index bde0832..b22bd5e 100644 --- a/dist/rough.umd.es5.js +++ b/dist/rough.umd.es5.js @@ -1708,9 +1708,9 @@ } var hasSelf$1 = typeof self !== 'undefined'; - var RoughGenerator = function () { - function RoughGenerator(config, surface) { - classCallCheck(this, RoughGenerator); + var RoughGeneratorBase = function () { + function RoughGeneratorBase(config, surface) { + classCallCheck(this, RoughGeneratorBase); this.defaultOptions = { maxRandomnessOffset: 2, @@ -1733,7 +1733,7 @@ } } - createClass(RoughGenerator, [{ + createClass(RoughGeneratorBase, [{ key: '_options', value: function _options(options) { return options ? Object.assign({}, this.defaultOptions, options) : this.defaultOptions; @@ -1817,130 +1817,6 @@ } return size; } - }, { - key: 'line', - value: function line(x1, y1, x2, y2, options) { - var o = this._options(options); - return this._drawable('line', [this.lib.line(x1, y1, x2, y2, o)], o); - } - }, { - key: 'rectangle', - value: function rectangle(x, y, width, height, options) { - var o = this._options(options); - var paths = []; - if (o.fill) { - var points = [[x, y], [x + width, y], [x + width, y + height], [x, y + height]]; - if (o.fillStyle === 'solid') { - paths.push(this.lib.solidFillPolygon(points, o)); - } else { - paths.push(this.lib.patternFillPolygon(points, o)); - } - } - paths.push(this.lib.rectangle(x, y, width, height, o)); - return this._drawable('rectangle', paths, o); - } - }, { - key: 'ellipse', - value: function ellipse(x, y, width, height, options) { - var o = this._options(options); - var paths = []; - if (o.fill) { - if (o.fillStyle === 'solid') { - var shape = this.lib.ellipse(x, y, width, height, o); - shape.type = 'fillPath'; - paths.push(shape); - } else { - paths.push(this.lib.patternFillEllipse(x, y, width, height, o)); - } - } - paths.push(this.lib.ellipse(x, y, width, height, o)); - return this._drawable('ellipse', paths, o); - } - }, { - key: 'circle', - value: function circle(x, y, diameter, options) { - var ret = this.ellipse(x, y, diameter, diameter, options); - ret.shape = 'circle'; - return ret; - } - }, { - key: 'linearPath', - value: function linearPath(points, options) { - var o = this._options(options); - return this._drawable('linearPath', [this.lib.linearPath(points, false, o)], o); - } - }, { - key: 'arc', - value: function arc(x, y, width, height, start, stop) { - var closed = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false; - var options = arguments[7]; - - var o = this._options(options); - var paths = []; - if (closed && o.fill) { - if (o.fillStyle === 'solid') { - var shape = this.lib.arc(x, y, width, height, start, stop, true, false, o); - shape.type = 'fillPath'; - paths.push(shape); - } else { - paths.push(this.lib.patternFillArc(x, y, width, height, start, stop, o)); - } - } - paths.push(this.lib.arc(x, y, width, height, start, stop, closed, true, o)); - return this._drawable('arc', paths, o); - } - }, { - key: 'curve', - value: function curve(points, options) { - var o = this._options(options); - return this._drawable('curve', [this.lib.curve(points, o)], o); - } - }, { - key: 'polygon', - value: function polygon(points, options) { - var o = this._options(options); - var paths = []; - if (o.fill) { - if (o.fillStyle === 'solid') { - paths.push(this.lib.solidFillPolygon(points, o)); - } else { - var size = this.computePolygonSize(points); - var fillPoints = [[0, 0], [size[0], 0], [size[0], size[1]], [0, size[1]]]; - var shape = this.lib.patternFillPolygon(fillPoints, o); - shape.type = 'path2Dpattern'; - shape.size = size; - shape.path = this.polygonPath(points); - paths.push(shape); - } - } - paths.push(this.lib.linearPath(points, true, o)); - return this._drawable('polygon', paths, o); - } - }, { - key: 'path', - value: function path(d, options) { - var o = this._options(options); - var paths = []; - if (!d) { - return this._drawable('path', paths, o); - } - if (o.fill) { - if (o.fillStyle === 'solid') { - var shape = { type: 'path2Dfill', path: d, ops: [] }; - paths.push(shape); - } else { - var size = this.computePathSize(d); - var points = [[0, 0], [size[0], 0], [size[0], size[1]], [0, size[1]]]; - var _shape = this.lib.patternFillPolygon(points, o); - _shape.type = 'path2Dpattern'; - _shape.size = size; - _shape.path = d; - paths.push(_shape); - } - } - paths.push(this.lib.svgPath(d, o)); - return this._drawable('path', paths, o); - } }, { key: 'toPaths', value: function toPaths(drawable) { @@ -2088,60 +1964,68 @@ return this.renderer; } }]); - return RoughGenerator; + return RoughGeneratorBase; }(); - var hasDocument = typeof document !== 'undefined'; - var RoughCanvas = function () { - function RoughCanvas(canvas, config) { - classCallCheck(this, RoughCanvas); + var RoughGenerator = function (_RoughGeneratorBase) { + inherits(RoughGenerator, _RoughGeneratorBase); - this.canvas = canvas; - this.ctx = this.canvas.getContext('2d'); - this.gen = new RoughGenerator(config || null, this.canvas); + function RoughGenerator(config, surface) { + classCallCheck(this, RoughGenerator); + return possibleConstructorReturn(this, (RoughGenerator.__proto__ || Object.getPrototypeOf(RoughGenerator)).call(this, config, surface)); } - createClass(RoughCanvas, [{ + createClass(RoughGenerator, [{ key: 'line', value: function line(x1, y1, x2, y2, options) { - var d = this.gen.line(x1, y1, x2, y2, options); - this.draw(d); - return d; + var o = this._options(options); + return this._drawable('line', [this.lib.line(x1, y1, x2, y2, o)], o); } }, { key: 'rectangle', value: function rectangle(x, y, width, height, options) { - var d = this.gen.rectangle(x, y, width, height, options); - this.draw(d); - return d; + var o = this._options(options); + var paths = []; + if (o.fill) { + var points = [[x, y], [x + width, y], [x + width, y + height], [x, y + height]]; + if (o.fillStyle === 'solid') { + paths.push(this.lib.solidFillPolygon(points, o)); + } else { + paths.push(this.lib.patternFillPolygon(points, o)); + } + } + paths.push(this.lib.rectangle(x, y, width, height, o)); + return this._drawable('rectangle', paths, o); } }, { key: 'ellipse', value: function ellipse(x, y, width, height, options) { - var d = this.gen.ellipse(x, y, width, height, options); - this.draw(d); - return d; + var o = this._options(options); + var paths = []; + if (o.fill) { + if (o.fillStyle === 'solid') { + var shape = this.lib.ellipse(x, y, width, height, o); + shape.type = 'fillPath'; + paths.push(shape); + } else { + paths.push(this.lib.patternFillEllipse(x, y, width, height, o)); + } + } + paths.push(this.lib.ellipse(x, y, width, height, o)); + return this._drawable('ellipse', paths, o); } }, { key: 'circle', value: function circle(x, y, diameter, options) { - var d = this.gen.circle(x, y, diameter, options); - this.draw(d); - return d; + var ret = this.ellipse(x, y, diameter, diameter, options); + ret.shape = 'circle'; + return ret; } }, { key: 'linearPath', value: function linearPath(points, options) { - var d = this.gen.linearPath(points, options); - this.draw(d); - return d; - } - }, { - key: 'polygon', - value: function polygon(points, options) { - var d = this.gen.polygon(points, options); - this.draw(d); - return d; + var o = this._options(options); + return this._drawable('linearPath', [this.lib.linearPath(points, false, o)], o); } }, { key: 'arc', @@ -2149,29 +2033,90 @@ var closed = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false; var options = arguments[7]; - var d = this.gen.arc(x, y, width, height, start, stop, closed, options); - this.draw(d); - return d; + var o = this._options(options); + var paths = []; + if (closed && o.fill) { + if (o.fillStyle === 'solid') { + var shape = this.lib.arc(x, y, width, height, start, stop, true, false, o); + shape.type = 'fillPath'; + paths.push(shape); + } else { + paths.push(this.lib.patternFillArc(x, y, width, height, start, stop, o)); + } + } + paths.push(this.lib.arc(x, y, width, height, start, stop, closed, true, o)); + return this._drawable('arc', paths, o); } }, { key: 'curve', value: function curve(points, options) { - var d = this.gen.curve(points, options); - this.draw(d); - return d; + var o = this._options(options); + return this._drawable('curve', [this.lib.curve(points, o)], o); + } + }, { + key: 'polygon', + value: function polygon(points, options) { + var o = this._options(options); + var paths = []; + if (o.fill) { + if (o.fillStyle === 'solid') { + paths.push(this.lib.solidFillPolygon(points, o)); + } else { + var size = this.computePolygonSize(points); + var fillPoints = [[0, 0], [size[0], 0], [size[0], size[1]], [0, size[1]]]; + var shape = this.lib.patternFillPolygon(fillPoints, o); + shape.type = 'path2Dpattern'; + shape.size = size; + shape.path = this.polygonPath(points); + paths.push(shape); + } + } + paths.push(this.lib.linearPath(points, true, o)); + return this._drawable('polygon', paths, o); } }, { key: 'path', value: function path(d, options) { - var drawing = this.gen.path(d, options); - this.draw(drawing); - return drawing; + var o = this._options(options); + var paths = []; + if (!d) { + return this._drawable('path', paths, o); + } + if (o.fill) { + if (o.fillStyle === 'solid') { + var shape = { type: 'path2Dfill', path: d, ops: [] }; + paths.push(shape); + } else { + var size = this.computePathSize(d); + var points = [[0, 0], [size[0], 0], [size[0], size[1]], [0, size[1]]]; + var _shape = this.lib.patternFillPolygon(points, o); + _shape.type = 'path2Dpattern'; + _shape.size = size; + _shape.path = d; + paths.push(_shape); + } + } + paths.push(this.lib.svgPath(d, o)); + return this._drawable('path', paths, o); } - }, { + }]); + return RoughGenerator; + }(RoughGeneratorBase); + + var hasDocument = typeof document !== 'undefined'; + var RoughCanvasBase = function () { + function RoughCanvasBase(canvas) { + classCallCheck(this, RoughCanvasBase); + + this.canvas = canvas; + this.ctx = this.canvas.getContext('2d'); + } + + createClass(RoughCanvasBase, [{ key: 'draw', value: function draw(drawable) { var sets = drawable.sets || []; - var o = drawable.options || this.gen.defaultOptions; + var o = drawable.options || this.getDefaultOptions(); var ctx = this.ctx; var _iteratorNormalCompletion = true; var _didIteratorError = false; @@ -2285,70 +2230,157 @@ ctx.restore(); } }, { - key: '_drawToContext', - value: function _drawToContext(ctx, drawing) { - ctx.beginPath(); - var _iteratorNormalCompletion2 = true; - var _didIteratorError2 = false; - var _iteratorError2 = undefined; - - try { - for (var _iterator2 = drawing.ops[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { - var item = _step2.value; - - var data = item.data; - switch (item.op) { - case 'move': - ctx.moveTo(data[0], data[1]); - break; - case 'bcurveTo': - ctx.bezierCurveTo(data[0], data[1], data[2], data[3], data[4], data[5]); - break; - case 'qcurveTo': - ctx.quadraticCurveTo(data[0], data[1], data[2], data[3]); - break; - case 'lineTo': - ctx.lineTo(data[0], data[1]); - break; - } - } - } catch (err) { - _didIteratorError2 = true; - _iteratorError2 = err; - } finally { - try { - if (!_iteratorNormalCompletion2 && _iterator2.return) { - _iterator2.return(); - } - } finally { - if (_didIteratorError2) { - throw _iteratorError2; - } - } - } - - if (drawing.type === 'fillPath') { - ctx.fill(); - } else { - ctx.stroke(); - } + key: '_drawToContext', + value: function _drawToContext(ctx, drawing) { + ctx.beginPath(); + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = drawing.ops[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var item = _step2.value; + + var data = item.data; + switch (item.op) { + case 'move': + ctx.moveTo(data[0], data[1]); + break; + case 'bcurveTo': + ctx.bezierCurveTo(data[0], data[1], data[2], data[3], data[4], data[5]); + break; + case 'qcurveTo': + ctx.quadraticCurveTo(data[0], data[1], data[2], data[3]); + break; + case 'lineTo': + ctx.lineTo(data[0], data[1]); + break; + } + } + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2.return) { + _iterator2.return(); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } + + if (drawing.type === 'fillPath') { + ctx.fill(); + } else { + ctx.stroke(); + } + } + }], [{ + key: 'createRenderer', + value: function createRenderer() { + return new RoughRenderer(); + } + }]); + return RoughCanvasBase; + }(); + + var RoughCanvas = function (_RoughCanvasBase) { + inherits(RoughCanvas, _RoughCanvasBase); + + function RoughCanvas(canvas, config) { + classCallCheck(this, RoughCanvas); + + var _this = possibleConstructorReturn(this, (RoughCanvas.__proto__ || Object.getPrototypeOf(RoughCanvas)).call(this, canvas)); + + _this.gen = new RoughGenerator(config || null, _this.canvas); + return _this; + } + + createClass(RoughCanvas, [{ + key: 'getDefaultOptions', + value: function getDefaultOptions() { + return this.gen.defaultOptions; + } + }, { + key: 'line', + value: function line(x1, y1, x2, y2, options) { + var d = this.gen.line(x1, y1, x2, y2, options); + this.draw(d); + return d; + } + }, { + key: 'rectangle', + value: function rectangle(x, y, width, height, options) { + var d = this.gen.rectangle(x, y, width, height, options); + this.draw(d); + return d; + } + }, { + key: 'ellipse', + value: function ellipse(x, y, width, height, options) { + var d = this.gen.ellipse(x, y, width, height, options); + this.draw(d); + return d; + } + }, { + key: 'circle', + value: function circle(x, y, diameter, options) { + var d = this.gen.circle(x, y, diameter, options); + this.draw(d); + return d; + } + }, { + key: 'linearPath', + value: function linearPath(points, options) { + var d = this.gen.linearPath(points, options); + this.draw(d); + return d; + } + }, { + key: 'polygon', + value: function polygon(points, options) { + var d = this.gen.polygon(points, options); + this.draw(d); + return d; + } + }, { + key: 'arc', + value: function arc(x, y, width, height, start, stop) { + var closed = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false; + var options = arguments[7]; + + var d = this.gen.arc(x, y, width, height, start, stop, closed, options); + this.draw(d); + return d; + } + }, { + key: 'curve', + value: function curve(points, options) { + var d = this.gen.curve(points, options); + this.draw(d); + return d; + } + }, { + key: 'path', + value: function path(d, options) { + var drawing = this.gen.path(d, options); + this.draw(drawing); + return drawing; } }, { key: 'generator', get: function get$$1() { return this.gen; } - }], [{ - key: 'createRenderer', - value: function createRenderer() { - return new RoughRenderer(); - } }]); return RoughCanvas; - }(); + }(RoughCanvasBase); - var RoughGeneratorAsync = function (_RoughGenerator) { - inherits(RoughGeneratorAsync, _RoughGenerator); + var RoughGeneratorAsync = function (_RoughGeneratorBase) { + inherits(RoughGeneratorAsync, _RoughGeneratorBase); function RoughGeneratorAsync() { classCallCheck(this, RoughGeneratorAsync); @@ -2357,14 +2389,10 @@ createClass(RoughGeneratorAsync, [{ key: 'line', - - // @ts-ignore value: async function line(x1, y1, x2, y2, options) { var o = this._options(options); return this._drawable('line', [await this.lib.line(x1, y1, x2, y2, o)], o); } - // @ts-ignore - }, { key: 'rectangle', value: async function rectangle(x, y, width, height, options) { @@ -2381,8 +2409,6 @@ paths.push((await this.lib.rectangle(x, y, width, height, o))); return this._drawable('rectangle', paths, o); } - // @ts-ignore - }, { key: 'ellipse', value: async function ellipse(x, y, width, height, options) { @@ -2400,8 +2426,6 @@ paths.push((await this.lib.ellipse(x, y, width, height, o))); return this._drawable('ellipse', paths, o); } - // @ts-ignore - }, { key: 'circle', value: async function circle(x, y, diameter, options) { @@ -2409,16 +2433,12 @@ ret.shape = 'circle'; return ret; } - // @ts-ignore - }, { key: 'linearPath', value: async function linearPath(points, options) { var o = this._options(options); return this._drawable('linearPath', [await this.lib.linearPath(points, false, o)], o); } - // @ts-ignore - }, { key: 'arc', value: async function arc(x, y, width, height, start, stop) { @@ -2439,16 +2459,12 @@ paths.push((await this.lib.arc(x, y, width, height, start, stop, closed, true, o))); return this._drawable('arc', paths, o); } - // @ts-ignore - }, { key: 'curve', value: async function curve(points, options) { var o = this._options(options); return this._drawable('curve', [await this.lib.curve(points, o)], o); } - // @ts-ignore - }, { key: 'polygon', value: async function polygon(points, options) { @@ -2470,8 +2486,6 @@ paths.push((await this.lib.linearPath(points, true, o))); return this._drawable('polygon', paths, o); } - // @ts-ignore - }, { key: 'path', value: async function path(d, options) { @@ -2499,33 +2513,32 @@ } }]); return RoughGeneratorAsync; - }(RoughGenerator); + }(RoughGeneratorBase); - var RoughCanvasAsync = function (_RoughCanvas) { - inherits(RoughCanvasAsync, _RoughCanvas); + var RoughCanvasAsync = function (_RoughCanvasBase) { + inherits(RoughCanvasAsync, _RoughCanvasBase); function RoughCanvasAsync(canvas, config) { classCallCheck(this, RoughCanvasAsync); - var _this = possibleConstructorReturn(this, (RoughCanvasAsync.__proto__ || Object.getPrototypeOf(RoughCanvasAsync)).call(this, canvas, config)); + var _this = possibleConstructorReturn(this, (RoughCanvasAsync.__proto__ || Object.getPrototypeOf(RoughCanvasAsync)).call(this, canvas)); _this.genAsync = new RoughGeneratorAsync(config || null, _this.canvas); return _this; } - // @ts-ignore - createClass(RoughCanvasAsync, [{ + key: 'getDefaultOptions', + value: function getDefaultOptions() { + return this.genAsync.defaultOptions; + } + }, { key: 'line', - - // @ts-ignore value: async function line(x1, y1, x2, y2, options) { var d = await this.genAsync.line(x1, y1, x2, y2, options); this.draw(d); return d; } - // @ts-ignore - }, { key: 'rectangle', value: async function rectangle(x, y, width, height, options) { @@ -2533,8 +2546,6 @@ this.draw(d); return d; } - // @ts-ignore - }, { key: 'ellipse', value: async function ellipse(x, y, width, height, options) { @@ -2542,8 +2553,6 @@ this.draw(d); return d; } - // @ts-ignore - }, { key: 'circle', value: async function circle(x, y, diameter, options) { @@ -2551,8 +2560,6 @@ this.draw(d); return d; } - // @ts-ignore - }, { key: 'linearPath', value: async function linearPath(points, options) { @@ -2560,8 +2567,6 @@ this.draw(d); return d; } - // @ts-ignore - }, { key: 'polygon', value: async function polygon(points, options) { @@ -2569,8 +2574,6 @@ this.draw(d); return d; } - // @ts-ignore - }, { key: 'arc', value: async function arc(x, y, width, height, start, stop) { @@ -2581,8 +2584,6 @@ this.draw(d); return d; } - // @ts-ignore - }, { key: 'curve', value: async function curve(points, options) { @@ -2590,8 +2591,6 @@ this.draw(d); return d; } - // @ts-ignore - }, { key: 'path', value: async function path(d, options) { @@ -2606,79 +2605,21 @@ } }]); return RoughCanvasAsync; - }(RoughCanvas); + }(RoughCanvasBase); var hasDocument$1 = typeof document !== 'undefined'; - var RoughSVG = function () { - function RoughSVG(svg, config) { - classCallCheck(this, RoughSVG); + var RoughSVGBase = function () { + function RoughSVGBase(svg) { + classCallCheck(this, RoughSVGBase); this.svg = svg; - this.gen = new RoughGenerator(config || null, this.svg); } - createClass(RoughSVG, [{ - key: 'line', - value: function line(x1, y1, x2, y2, options) { - var d = this.gen.line(x1, y1, x2, y2, options); - return this.draw(d); - } - }, { - key: 'rectangle', - value: function rectangle(x, y, width, height, options) { - var d = this.gen.rectangle(x, y, width, height, options); - return this.draw(d); - } - }, { - key: 'ellipse', - value: function ellipse(x, y, width, height, options) { - var d = this.gen.ellipse(x, y, width, height, options); - return this.draw(d); - } - }, { - key: 'circle', - value: function circle(x, y, diameter, options) { - var d = this.gen.circle(x, y, diameter, options); - return this.draw(d); - } - }, { - key: 'linearPath', - value: function linearPath(points, options) { - var d = this.gen.linearPath(points, options); - return this.draw(d); - } - }, { - key: 'polygon', - value: function polygon(points, options) { - var d = this.gen.polygon(points, options); - return this.draw(d); - } - }, { - key: 'arc', - value: function arc(x, y, width, height, start, stop) { - var closed = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false; - var options = arguments[7]; - - var d = this.gen.arc(x, y, width, height, start, stop, closed, options); - return this.draw(d); - } - }, { - key: 'curve', - value: function curve(points, options) { - var d = this.gen.curve(points, options); - return this.draw(d); - } - }, { - key: 'path', - value: function path(d, options) { - var drawing = this.gen.path(d, options); - return this.draw(drawing); - } - }, { + createClass(RoughSVGBase, [{ key: 'draw', value: function draw(drawable) { var sets = drawable.sets || []; - var o = drawable.options || this.gen.defaultOptions; + var o = drawable.options || this.getDefaultOptions(); var doc = this.svg.ownerDocument || hasDocument$1 && document; var g = doc.createElementNS('http://www.w3.org/2000/svg', 'g'); var _iteratorNormalCompletion = true; @@ -2772,11 +2713,6 @@ return g; } - }, { - key: 'opsToPath', - value: function opsToPath(drawing) { - return this.gen.opsToPath(drawing); - } }, { key: 'fillSketch', value: function fillSketch(doc, drawing, o) { @@ -2791,11 +2727,6 @@ path.style.fill = 'none'; return path; } - }, { - key: 'generator', - get: function get$$1() { - return this.gen; - } }, { key: 'defs', get: function get$$1() { @@ -2819,73 +2750,155 @@ return new RoughRenderer(); } }]); - return RoughSVG; + return RoughSVGBase; }(); - var RoughSVGAsync = function (_RoughSVG) { - inherits(RoughSVGAsync, _RoughSVG); + var RoughSVG = function (_RoughSVGBase) { + inherits(RoughSVG, _RoughSVGBase); + + function RoughSVG(svg, config) { + classCallCheck(this, RoughSVG); + + var _this = possibleConstructorReturn(this, (RoughSVG.__proto__ || Object.getPrototypeOf(RoughSVG)).call(this, svg)); + + _this.gen = new RoughGenerator(config || null, _this.svg); + return _this; + } + + createClass(RoughSVG, [{ + key: 'getDefaultOptions', + value: function getDefaultOptions() { + return this.gen.defaultOptions; + } + }, { + key: 'opsToPath', + value: function opsToPath(drawing) { + return this.gen.opsToPath(drawing); + } + }, { + key: 'line', + value: function line(x1, y1, x2, y2, options) { + var d = this.gen.line(x1, y1, x2, y2, options); + return this.draw(d); + } + }, { + key: 'rectangle', + value: function rectangle(x, y, width, height, options) { + var d = this.gen.rectangle(x, y, width, height, options); + return this.draw(d); + } + }, { + key: 'ellipse', + value: function ellipse(x, y, width, height, options) { + var d = this.gen.ellipse(x, y, width, height, options); + return this.draw(d); + } + }, { + key: 'circle', + value: function circle(x, y, diameter, options) { + var d = this.gen.circle(x, y, diameter, options); + return this.draw(d); + } + }, { + key: 'linearPath', + value: function linearPath(points, options) { + var d = this.gen.linearPath(points, options); + return this.draw(d); + } + }, { + key: 'polygon', + value: function polygon(points, options) { + var d = this.gen.polygon(points, options); + return this.draw(d); + } + }, { + key: 'arc', + value: function arc(x, y, width, height, start, stop) { + var closed = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false; + var options = arguments[7]; + + var d = this.gen.arc(x, y, width, height, start, stop, closed, options); + return this.draw(d); + } + }, { + key: 'curve', + value: function curve(points, options) { + var d = this.gen.curve(points, options); + return this.draw(d); + } + }, { + key: 'path', + value: function path(d, options) { + var drawing = this.gen.path(d, options); + return this.draw(drawing); + } + }, { + key: 'generator', + get: function get$$1() { + return this.gen; + } + }]); + return RoughSVG; + }(RoughSVGBase); + + var RoughSVGAsync = function (_RoughSVGBase) { + inherits(RoughSVGAsync, _RoughSVGBase); function RoughSVGAsync(svg, config) { classCallCheck(this, RoughSVGAsync); - var _this = possibleConstructorReturn(this, (RoughSVGAsync.__proto__ || Object.getPrototypeOf(RoughSVGAsync)).call(this, svg, config)); + var _this = possibleConstructorReturn(this, (RoughSVGAsync.__proto__ || Object.getPrototypeOf(RoughSVGAsync)).call(this, svg)); _this.genAsync = new RoughGeneratorAsync(config || null, _this.svg); return _this; } - // @ts-ignore - createClass(RoughSVGAsync, [{ + key: 'getDefaultOptions', + value: function getDefaultOptions() { + return this.genAsync.defaultOptions; + } + }, { + key: 'opsToPath', + value: function opsToPath(drawing) { + return this.genAsync.opsToPath(drawing); + } + }, { key: 'line', - - // @ts-ignore value: async function line(x1, y1, x2, y2, options) { var d = await this.genAsync.line(x1, y1, x2, y2, options); return this.draw(d); } - // @ts-ignore - }, { key: 'rectangle', value: async function rectangle(x, y, width, height, options) { var d = await this.genAsync.rectangle(x, y, width, height, options); return this.draw(d); } - // @ts-ignore - }, { key: 'ellipse', value: async function ellipse(x, y, width, height, options) { var d = await this.genAsync.ellipse(x, y, width, height, options); return this.draw(d); } - // @ts-ignore - }, { key: 'circle', value: async function circle(x, y, diameter, options) { var d = await this.genAsync.circle(x, y, diameter, options); return this.draw(d); } - // @ts-ignore - }, { key: 'linearPath', value: async function linearPath(points, options) { var d = await this.genAsync.linearPath(points, options); return this.draw(d); } - // @ts-ignore - }, { key: 'polygon', value: async function polygon(points, options) { var d = await this.genAsync.polygon(points, options); return this.draw(d); } - // @ts-ignore - }, { key: 'arc', value: async function arc(x, y, width, height, start, stop) { @@ -2895,16 +2908,12 @@ var d = await this.genAsync.arc(x, y, width, height, start, stop, closed, options); return this.draw(d); } - // @ts-ignore - }, { key: 'curve', value: async function curve(points, options) { var d = await this.genAsync.curve(points, options); return this.draw(d); } - // @ts-ignore - }, { key: 'path', value: async function path(d, options) { @@ -2918,7 +2927,7 @@ } }]); return RoughSVGAsync; - }(RoughSVG); + }(RoughSVGBase); var rough = { canvas: function canvas(_canvas, config) { diff --git a/dist/rough.umd.es5.min.js b/dist/rough.umd.es5.min.js index efe5ebf..6fd4b87 100644 --- a/dist/rough.umd.es5.min.js +++ b/dist/rough.umd.es5.min.js @@ -1 +1 @@ -(function(e,t){'object'==typeof exports&&'undefined'!=typeof module?module.exports=t():'function'==typeof define&&define.amd?define(t):e.rough=t()})(this,function(){'use strict';function e(e,t){return e.type===t}function t(e){var t=e[0],l=e[1];return y(f(t[0]-l[0],2)+f(t[1]-l[1],2))}function l(e,t){for(var l,a=[],n=new z([e[0],e[1]],[e[2],e[3]]),s=0;sg&&(g=4*t.strokeWidth),g=d(g,.1);for(var y=h%180*(c/180),k=v(y),x=_(y),b=p(y),m=new E(o-1,r+1,n-1,s+1,g,x,k,b),w=void 0;null!=(w=m.nextLine());)for(var P=l(w,e),O=0;O=f&&(f=4*i.strokeWidth);var h=i.fillWeight;0>h&&(h=i.strokeWidth/2);for(var g=p(u%180*(c/180)),v=d/r,_=y(v*g*v*g+1),x=v*g/_,b=1/_,m=f/(r*d/y(d*b*(d*b)+r*x*(r*x))/r),w=y(r*r-(e-r+m)*(e-r+m)),P=e-r+m;Pf){var h=y(1-f/(this._rx*this._rx*this._ry*this._ry));this._rx*=h,this._ry*=h,u=0}else u=(i===o?-1:1)*y(f/(this._rx*this._rx*d*d+this._ry*this._ry*p*p));var s=u*this._rx*d/this._ry,x=-u*this._ry*p/this._rx;this._C=[0,0],this._C[0]=this._cosPhi*s-this._sinPhi*x+(t[0]+l[0])/2,this._C[1]=this._sinPhi*s+this._cosPhi*x+(t[1]+l[1])/2,this._theta=this.calculateVectorAngle(1,0,(p-s)/this._rx,(d-x)/this._ry);var m=this.calculateVectorAngle((p-s)/this._rx,(d-x)/this._ry,(-p-s)/this._rx,(-d-x)/this._ry);!o&&0m&&(m+=2*c),this._numSegs=g(k(m/(c/2))),this._delta=m/this._numSegs,this._T=8/3*_(this._delta/4)*_(this._delta/4)/_(this._delta/2)}}return m(e,[{key:'getNextSegment',value:function(){if(this._segIndex===this._numSegs)return null;var e=v(this._theta),t=_(this._theta),l=this._theta+this._delta,a=v(l),n=_(l),i=[this._cosPhi*this._rx*a-this._sinPhi*this._ry*n+this._C[0],this._sinPhi*this._rx*a+this._cosPhi*this._ry*n+this._C[1]],s=[this._from[0]+this._T*(-this._cosPhi*this._rx*t-this._sinPhi*this._ry*e),this._from[1]+this._T*(-this._sinPhi*this._rx*t+this._cosPhi*this._ry*e)],o=[i[0]+this._T*(this._cosPhi*this._rx*n+this._sinPhi*this._ry*a),i[1]+this._T*(this._sinPhi*this._rx*n-this._cosPhi*this._ry*a)];return this._theta=l,this._from=[i[0],i[1]],this._segIndex++,{cp1:s,cp2:o,to:i}}},{key:'calculateVectorAngle',value:function(e,t,l,a){var n=Math.atan2,i=n(t,e),s=n(a,l);return s>=i?s-i:2*c-(i-s)}}]),e}(),C=function(){function e(t,l){b(this,e),this.sets=t,this.closed=l}return m(e,[{key:'fit',value:function(e){var t=[],l=!0,a=!1,n=void 0;try{for(var s,o=this.sets[Symbol.iterator]();!(l=(s=o.next()).done);l=!0){var r=s.value,p=r.length,u=h(e*p);if(5>u){if(5>=p)continue;u=5}t.push(this.reduce(r,u))}}catch(e){a=!0,n=e}finally{try{!l&&o.return&&o.return()}finally{if(a)throw n}}var f='',g=!0,y=!1,c=void 0;try{for(var v,_,k=t[Symbol.iterator]();!(g=(v=k.next()).done);g=!0){_=v.value;for(var x,b=0;b<_.length;b++)x=_[b],f+=0===b?'M'+x[0]+','+x[1]:'L'+x[0]+','+x[1];this.closed&&(f+='z ')}}catch(e){y=!0,c=e}finally{try{!g&&k.return&&k.return()}finally{if(y)throw c}}return f}},{key:'distance',value:function(e,t){return y(f(e[0]-t[0],2)+f(e[1]-t[1],2))}},{key:'reduce',value:function(e,t){if(e.length<=t)return e;for(var l=e.slice(0);l.length>t;){for(var n=-1,o=-1,r=1;rn||s=u(e.py1,e.py2)&&this.py1<=d(e.py1,e.py2)?(this.xi=this.px1,this.yi=this.py1,!0):!!(this.py2>=u(e.py1,e.py2)&&this.py2<=d(e.py1,e.py2))&&(this.xi=this.px2,this.yi=this.py2,!0)):(this.xi=this.px1,this.yi=n*this.xi+s,!(-1e-5>(this.py1-this.yi)*(this.yi-this.py2)||-1e-5>(e.py1-this.yi)*(this.yi-e.py2))&&(!(1e-5>k(e.a))||!(-1e-5>(e.px1-this.xi)*(this.xi-e.px2)))):n===t?(this.xi=e.px1,this.yi=l*this.xi+i,!(-1e-5>(e.py1-this.yi)*(this.yi-e.py2)||-1e-5>(this.py1-this.yi)*(this.yi-this.py2))&&(!(1e-5>k(o))||!(-1e-5>(this.px1-this.xi)*(this.xi-this.px2)))):l===n?i==s&&(this.px1>=u(e.px1,e.px2)&&this.px1<=d(e.py1,e.py2)?(this.xi=this.px1,this.yi=this.py1,!0):!!(this.px2>=u(e.px1,e.px2)&&this.px2<=d(e.px1,e.px2))&&(this.xi=this.px2,this.yi=this.py2,!0)):(this.xi=(s-i)/(l-n),this.yi=l*this.xi+i,!(-1e-5>(this.px1-this.xi)*(this.xi-this.px2)||-1e-5>(e.px1-this.xi)*(this.xi-e.px2)))}}]),e}(),E=function(){function e(t,l,a,n,i,s,o,r){b(this,e),this.deltaX=0,this.hGap=0,this.top=t,this.bottom=l,this.left=a,this.right=n,this.gap=i,this.sinAngle=s,this.tanAngle=r,1e-4>k(s)?this.pos=a+i:.9999k(this.sinAngle)){if(this.posthis.right&&l>this.right;)if(this.pos+=this.hGap,t=this.pos-this.deltaX/2,l=this.pos+this.deltaX/2,this.pos>this.right+this.deltaX)return null;var i=new z([t,a],[l,n]);this.sLeft&&i.intersects(this.sLeft)&&(t=i.xi,a=i.yi),this.sRight&&i.intersects(this.sRight)&&(l=i.xi,n=i.yi),0s&&(s=4*a.strokeWidth),s=d(s,.1);var o=a.fillWeight;0>o&&(o=a.strokeWidth/2);var r=!0,p=!1,u=void 0;try{for(var f,h=e[Symbol.iterator]();!(r=(f=h.next()).done);r=!0)for(var y=f.value,k=t(y),x=k/s,b=g(x)-1,m=Math.atan((y[1][1]-y[0][1])/(y[1][0]-y[0][0])),w=0;wg;)g+=2*c,y+=2*c;y-g>2*c&&(g=0,y=2*c);var x=2*c/p.curveStepCount,b=u(x/2,(y-g)/2),m=this._arc(b,o,d,f,h,g,y,1,p),w=this._arc(b,o,d,f,h,g,y,1.5,p),P=m.concat(w);return s&&(r?(P=P.concat(this.doubleLine(o,d,o+f*v(g),d+h*_(g),p)),P=P.concat(this.doubleLine(o,d,o+f*v(y),d+h*_(y),p))):(P.push({op:'lineTo',data:[o,d]}),P.push({op:'lineTo',data:[o+f*v(g),d+h*_(g)]}))),{type:'path',ops:P}}},{key:'svgPath',value:function(e,t){e=(e||'').replace(/\n/g,' ').replace(/(-\s)/g,'-').replace('/(ss)/g',' ');var l=new A(e);if(t.simplification){var a=new C(l.linearPoints,l.closed),n=a.fit(t.simplification);l=new A(n)}for(var o=[],r=l.segments||[],d=0;du;)u+=2*c,f+=2*c;f-u>2*c&&(u=0,f=2*c);for(var h=(f-u)/s.curveStepCount,g=[],y=u;y<=f;y+=h)g.push([o+p*v(y),r+d*_(y)]);return g.push([o+p*v(f),r+d*_(f)]),g.push([o,r]),this.patternFillPolygon(g,s)}},{key:'getOffset',value:function(e,t,l){return l.roughness*(Math.random()*(t-e)+e)}},{key:'doubleLine',value:function(e,t,l,a,n){var i=this._line(e,t,l,a,n,!0,!1),s=this._line(e,t,l,a,n,!0,!0);return i.concat(s)}},{key:'_line',value:function(e,t,l,a,n,i,s){var o=f(e-l,2)+f(t-a,2),r=n.maxRandomnessOffset||0;100*(r*r)>o&&(r=y(o)/10);var p=r/2,d=.2+.2*Math.random(),u=n.bowing*n.maxRandomnessOffset*(a-t)/200,h=n.bowing*n.maxRandomnessOffset*(e-l)/200;u=this.getOffset(-u,u,n),h=this.getOffset(-h,h,n);var g=[];return i&&(s?g.push({op:'move',data:[e+this.getOffset(-p,p,n),t+this.getOffset(-p,p,n)]}):g.push({op:'move',data:[e+this.getOffset(-r,r,n),t+this.getOffset(-r,r,n)]})),s?g.push({op:'bcurveTo',data:[u+e+(l-e)*d+this.getOffset(-p,p,n),h+t+(a-t)*d+this.getOffset(-p,p,n),u+e+2*(l-e)*d+this.getOffset(-p,p,n),h+t+2*(a-t)*d+this.getOffset(-p,p,n),l+this.getOffset(-p,p,n),a+this.getOffset(-p,p,n)]}):g.push({op:'bcurveTo',data:[u+e+(l-e)*d+this.getOffset(-r,r,n),h+t+(a-t)*d+this.getOffset(-r,r,n),u+e+2*(l-e)*d+this.getOffset(-r,r,n),h+t+2*(a-t)*d+this.getOffset(-r,r,n),l+this.getOffset(-r,r,n),a+this.getOffset(-r,r,n)]}),g}},{key:'_curve',value:function(e,t,l){var a=e.length,n=[];if(3h;h++)0===h?o.push({op:'move',data:[r.x,r.y]}):o.push({op:'move',data:[r.x+this.getOffset(-d[0],d[0],p),r.y+this.getOffset(-d[0],d[0],p)]}),u=[n+this.getOffset(-d[h],d[h],p),s+this.getOffset(-d[h],d[h],p)],o.push({op:'bcurveTo',data:[e+this.getOffset(-d[h],d[h],p),t+this.getOffset(-d[h],d[h],p),l+this.getOffset(-d[h],d[h],p),a+this.getOffset(-d[h],d[h],p),u[0],u[1]]});return r.setPosition(u[0],u[1]),o}},{key:'_processSegment',value:function(e,t,l,a){var n=[];switch(t.key){case'M':case'm':{var s='m'===t.key;if(2<=t.data.length){var o=+t.data[0],r=+t.data[1];s&&(o+=e.x,r+=e.y);var p=1*(a.maxRandomnessOffset||0);o+=this.getOffset(-p,p,a),r+=this.getOffset(-p,p,a),e.setPosition(o,r),n.push({op:'move',data:[o,r]})}break}case'L':case'l':{var d='l'===t.key;if(2<=t.data.length){var u=+t.data[0],h=+t.data[1];d&&(u+=e.x,h+=e.y),n=n.concat(this.doubleLine(e.x,e.y,u,h,a)),e.setPosition(u,h)}break}case'H':case'h':{var g='h'===t.key;if(t.data.length){var c=+t.data[0];g&&(c+=e.x),n=n.concat(this.doubleLine(e.x,e.y,c,e.y,a)),e.setPosition(c,e.y)}break}case'V':case'v':{var v='v'===t.key;if(t.data.length){var _=+t.data[0];v&&(_+=e.y),n=n.concat(this.doubleLine(e.x,e.y,e.x,_,a)),e.setPosition(e.x,_)}break}case'Z':case'z':{e.first&&(n=n.concat(this.doubleLine(e.x,e.y,e.first[0],e.first[1],a)),e.setPosition(e.first[0],e.first[1]),e.first=null);break}case'C':case'c':{var k='c'===t.key;if(6<=t.data.length){var b=+t.data[0],m=+t.data[1],w=+t.data[2],P=+t.data[3],O=+t.data[4],S=+t.data[5];k&&(b+=e.x,w+=e.x,O+=e.x,m+=e.y,P+=e.y,S+=e.y);var A=this._bezierTo(b,m,w,P,O,S,e,a);n=n.concat(A),e.bezierReflectionPoint=[O+(O-w),S+(S-P)]}break}case'S':case's':{var C='s'===t.key;if(4<=t.data.length){var z=+t.data[0],E=+t.data[1],L=+t.data[2],W=+t.data[3];C&&(z+=e.x,L+=e.x,E+=e.y,W+=e.y);var N=z,R=E,D=l?l.key:'',B=null;('c'===D||'C'===D||'s'===D||'S'===D)&&(B=e.bezierReflectionPoint),B&&(N=B[0],R=B[1]);var F=this._bezierTo(N,R,z,E,L,W,e,a);n=n.concat(F),e.bezierReflectionPoint=[L+(L-z),W+(W-E)]}break}case'Q':case'q':{var M='q'===t.key;if(4<=t.data.length){var q=+t.data[0],U=+t.data[1],X=+t.data[2],V=+t.data[3];M&&(q+=e.x,X+=e.x,U+=e.y,V+=e.y);var G=1*(1+.2*a.roughness),j=1.5*(1+.22*a.roughness);n.push({op:'move',data:[e.x+this.getOffset(-G,G,a),e.y+this.getOffset(-G,G,a)]});var I=[X+this.getOffset(-G,G,a),V+this.getOffset(-G,G,a)];n.push({op:'qcurveTo',data:[q+this.getOffset(-G,G,a),U+this.getOffset(-G,G,a),I[0],I[1]]}),n.push({op:'move',data:[e.x+this.getOffset(-j,j,a),e.y+this.getOffset(-j,j,a)]}),I=[X+this.getOffset(-j,j,a),V+this.getOffset(-j,j,a)],n.push({op:'qcurveTo',data:[q+this.getOffset(-j,j,a),U+this.getOffset(-j,j,a),I[0],I[1]]}),e.setPosition(I[0],I[1]),e.quadReflectionPoint=[X+(X-q),V+(V-U)]}break}case'T':case't':{var Q='t'===t.key;if(2<=t.data.length){var $=+t.data[0],Z=+t.data[1];Q&&($+=e.x,Z+=e.y);var H=$,J=Z,Y=l?l.key:'',K=null;('q'===Y||'Q'===Y||'t'===Y||'T'===Y)&&(K=e.quadReflectionPoint),K&&(H=K[0],J=K[1]);var ee=1*(1+.2*a.roughness),te=1.5*(1+.22*a.roughness);n.push({op:'move',data:[e.x+this.getOffset(-ee,ee,a),e.y+this.getOffset(-ee,ee,a)]});var le=[$+this.getOffset(-ee,ee,a),Z+this.getOffset(-ee,ee,a)];n.push({op:'qcurveTo',data:[H+this.getOffset(-ee,ee,a),J+this.getOffset(-ee,ee,a),le[0],le[1]]}),n.push({op:'move',data:[e.x+this.getOffset(-te,te,a),e.y+this.getOffset(-te,te,a)]}),le=[$+this.getOffset(-te,te,a),Z+this.getOffset(-te,te,a)],n.push({op:'qcurveTo',data:[H+this.getOffset(-te,te,a),J+this.getOffset(-te,te,a),le[0],le[1]]}),e.setPosition(le[0],le[1]),e.quadReflectionPoint=[$+($-H),Z+(Z-J)]}break}case'A':case'a':{var ae='a'===t.key;if(7<=t.data.length){var ne=+t.data[0],ie=+t.data[1],se=+t.data[2],oe=+t.data[3],re=+t.data[4],pe=+t.data[5],de=+t.data[6];if(ae&&(pe+=e.x,de+=e.y),pe===e.x&&de===e.y)break;if(0==ne||0==ie)n=n.concat(this.doubleLine(e.x,e.y,pe,de,a)),e.setPosition(pe,de);else for(var ue=0;1>ue;ue++)for(var fe,he=new T([e.x,e.y],[pe,de],[ne,ie],se,!!oe,!!re),ge=he.getNextSegment();ge;)fe=this._bezierTo(ge.cp1[0],ge.cp1[1],ge.cp2[0],ge.cp2[1],ge.to[0],ge.to[1],e,a),n=n.concat(fe),ge=he.getNextSegment()}break}default:}return n}}]),e}(),F='undefined'!=typeof self,M=F&&self&&self.document&&self.document.currentScript&&self.document.currentScript.src,q='undefined'!=typeof self,U=function(){function e(t,l){b(this,e),this.defaultOptions={maxRandomnessOffset:2,roughness:1,bowing:1,stroke:'#000',strokeWidth:1,curveTightness:0,curveStepCount:9,fillStyle:'hachure',fillWeight:-1,hachureAngle:-41,hachureGap:-1},this.config=t||{},this.surface=l,this.renderer=o(this.config),this.config.options&&(this.defaultOptions=this._options(this.config.options))}return m(e,[{key:'_options',value:function(e){return e?Object.assign({},this.defaultOptions,e):this.defaultOptions}},{key:'_drawable',value:function(e,t,l){return{shape:e,sets:t||[],options:l||this.defaultOptions}}},{key:'getCanvasSize',value:function(){var e=function(e){return e&&'object'===('undefined'==typeof e?'undefined':x(e))&&e.baseVal&&e.baseVal.value?e.baseVal.value:e||100};return this.surface?[e(this.surface.width),e(this.surface.height)]:[100,100]}},{key:'computePolygonSize',value:function(e){if(e.length){for(var t=e[0][0],l=e[0][0],a=e[0][1],n=e[0][1],s=1;sl&&(l=t.strokeWidth/2),{d:this.opsToPath(e),stroke:t.fill||'none',strokeWidth:l,fill:'none'}}},{key:'opsToPath',value:function(e){var t='',l=!0,a=!1,n=void 0;try{for(var i,s=e.ops[Symbol.iterator]();!(l=(i=s.next()).done);l=!0){var o=i.value,r=o.data;switch(o.op){case'move':t+='M'+r[0]+' '+r[1]+' ';break;case'bcurveTo':t+='C'+r[0]+' '+r[1]+', '+r[2]+' '+r[3]+', '+r[4]+' '+r[5]+' ';break;case'qcurveTo':t+='Q'+r[0]+' '+r[1]+', '+r[2]+' '+r[3]+' ';break;case'lineTo':t+='L'+r[0]+' '+r[1]+' ';}}}catch(e){a=!0,n=e}finally{try{!l&&s.return&&s.return()}finally{if(a)throw n}}return t.trim()}},{key:'lib',get:function(){return this.renderer}}]),e}(),X='undefined'!=typeof document,V=function(){function e(t,l){b(this,e),this.canvas=t,this.ctx=this.canvas.getContext('2d'),this.gen=new U(l||null,this.canvas)}return m(e,[{key:'line',value:function(e,t,l,a,n){var i=this.gen.line(e,t,l,a,n);return this.draw(i),i}},{key:'rectangle',value:function(e,t,l,a,n){var i=this.gen.rectangle(e,t,l,a,n);return this.draw(i),i}},{key:'ellipse',value:function(e,t,l,a,n){var i=this.gen.ellipse(e,t,l,a,n);return this.draw(i),i}},{key:'circle',value:function(e,t,l,a){var n=this.gen.circle(e,t,l,a);return this.draw(n),n}},{key:'linearPath',value:function(e,t){var l=this.gen.linearPath(e,t);return this.draw(l),l}},{key:'polygon',value:function(e,t){var l=this.gen.polygon(e,t);return this.draw(l),l}},{key:'arc',value:function(e,t,l,a,n,i){var s=!!(6a&&(a=l.strokeWidth/2),e.save(),e.strokeStyle=l.fill||'',e.lineWidth=a,this._drawToContext(e,t),e.restore()}},{key:'_drawToContext',value:function(e,t){e.beginPath();var l=!0,a=!1,n=void 0;try{for(var i,s=t.ops[Symbol.iterator]();!(l=(i=s.next()).done);l=!0){var o=i.value,r=o.data;switch(o.op){case'move':e.moveTo(r[0],r[1]);break;case'bcurveTo':e.bezierCurveTo(r[0],r[1],r[2],r[3],r[4],r[5]);break;case'qcurveTo':e.quadraticCurveTo(r[0],r[1],r[2],r[3]);break;case'lineTo':e.lineTo(r[0],r[1]);}}}catch(e){a=!0,n=e}finally{try{!l&&s.return&&s.return()}finally{if(a)throw n}}'fillPath'===t.type?e.fill():e.stroke()}},{key:'generator',get:function(){return this.gen}}],[{key:'createRenderer',value:function(){return new B}}]),e}(),G=function(e){function t(){return b(this,t),P(this,(t.__proto__||Object.getPrototypeOf(t)).apply(this,arguments))}return w(t,e),m(t,[{key:'line',value:async function(e,t,l,a,n){var i=this._options(n);return this._drawable('line',[await this.lib.line(e,t,l,a,i)],i)}},{key:'rectangle',value:async function(e,t,l,a,n){var i=this._options(n),s=[];if(i.fill){var o=[[e,t],[e+l,t],[e+l,t+a],[e,t+a]];'solid'===i.fillStyle?s.push((await this.lib.solidFillPolygon(o,i))):s.push((await this.lib.patternFillPolygon(o,i)))}return s.push((await this.lib.rectangle(e,t,l,a,i))),this._drawable('rectangle',s,i)}},{key:'ellipse',value:async function(e,t,l,a,n){var i=this._options(n),s=[];if(i.fill)if('solid'===i.fillStyle){var o=await this.lib.ellipse(e,t,l,a,i);o.type='fillPath',s.push(o)}else s.push((await this.lib.patternFillEllipse(e,t,l,a,i)));return s.push((await this.lib.ellipse(e,t,l,a,i))),this._drawable('ellipse',s,i)}},{key:'circle',value:async function(e,t,l,a){var n=await this.ellipse(e,t,l,l,a);return n.shape='circle',n}},{key:'linearPath',value:async function(e,t){var l=this._options(t);return this._drawable('linearPath',[await this.lib.linearPath(e,!1,l)],l)}},{key:'arc',value:async function(e,t,l,a,n,i){var s=!!(6a&&(a=l.strokeWidth/2);var n=e.createElementNS('http://www.w3.org/2000/svg','path');return n.setAttribute('d',this.opsToPath(t)),n.style.stroke=l.fill||null,n.style.strokeWidth=a+'',n.style.fill='none',n}},{key:'generator',get:function(){return this.gen}},{key:'defs',get:function(){var e=this.svg.ownerDocument||I&&document;if(e&&!this._defs){var t=e.createElementNS('http://www.w3.org/2000/svg','defs');this.svg.firstChild?this.svg.insertBefore(t,this.svg.firstChild):this.svg.appendChild(t),this._defs=t}return this._defs||null}}],[{key:'createRenderer',value:function(){return new B}}]),e}(),$=function(e){function t(e,l){b(this,t);var a=P(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,l));return a.genAsync=new G(l||null,a.svg),a}return w(t,e),m(t,[{key:'line',value:async function(e,t,l,a,n){var i=await this.genAsync.line(e,t,l,a,n);return this.draw(i)}},{key:'rectangle',value:async function(e,t,l,a,n){var i=await this.genAsync.rectangle(e,t,l,a,n);return this.draw(i)}},{key:'ellipse',value:async function(e,t,l,a,n){var i=await this.genAsync.ellipse(e,t,l,a,n);return this.draw(i)}},{key:'circle',value:async function(e,t,l,a){var n=await this.genAsync.circle(e,t,l,a);return this.draw(n)}},{key:'linearPath',value:async function(e,t){var l=await this.genAsync.linearPath(e,t);return this.draw(l)}},{key:'polygon',value:async function(e,t){var l=await this.genAsync.polygon(e,t);return this.draw(l)}},{key:'arc',value:async function(e,t,l,a,n,i){var s=!!(6g&&(g=4*t.strokeWidth),g=d(g,.1);for(var y=h%180*(c/180),k=v(y),x=_(y),b=p(y),m=new E(o-1,r+1,n-1,s+1,g,x,k,b),O=void 0;null!=(O=m.nextLine());)for(var P=l(O,e),w=0;w=f&&(f=4*i.strokeWidth);var h=i.fillWeight;0>h&&(h=i.strokeWidth/2);for(var g=p(u%180*(c/180)),v=d/r,_=y(v*g*v*g+1),x=v*g/_,b=1/_,m=f/(r*d/y(d*b*(d*b)+r*x*(r*x))/r),O=y(r*r-(e-r+m)*(e-r+m)),P=e-r+m;Pf){var h=y(1-f/(this._rx*this._rx*this._ry*this._ry));this._rx*=h,this._ry*=h,u=0}else u=(i===o?-1:1)*y(f/(this._rx*this._rx*d*d+this._ry*this._ry*p*p));var s=u*this._rx*d/this._ry,x=-u*this._ry*p/this._rx;this._C=[0,0],this._C[0]=this._cosPhi*s-this._sinPhi*x+(t[0]+l[0])/2,this._C[1]=this._sinPhi*s+this._cosPhi*x+(t[1]+l[1])/2,this._theta=this.calculateVectorAngle(1,0,(p-s)/this._rx,(d-x)/this._ry);var m=this.calculateVectorAngle((p-s)/this._rx,(d-x)/this._ry,(-p-s)/this._rx,(-d-x)/this._ry);!o&&0m&&(m+=2*c),this._numSegs=g(k(m/(c/2))),this._delta=m/this._numSegs,this._T=8/3*_(this._delta/4)*_(this._delta/4)/_(this._delta/2)}}return m(e,[{key:'getNextSegment',value:function(){if(this._segIndex===this._numSegs)return null;var e=v(this._theta),t=_(this._theta),l=this._theta+this._delta,a=v(l),n=_(l),i=[this._cosPhi*this._rx*a-this._sinPhi*this._ry*n+this._C[0],this._sinPhi*this._rx*a+this._cosPhi*this._ry*n+this._C[1]],s=[this._from[0]+this._T*(-this._cosPhi*this._rx*t-this._sinPhi*this._ry*e),this._from[1]+this._T*(-this._sinPhi*this._rx*t+this._cosPhi*this._ry*e)],o=[i[0]+this._T*(this._cosPhi*this._rx*n+this._sinPhi*this._ry*a),i[1]+this._T*(this._sinPhi*this._rx*n-this._cosPhi*this._ry*a)];return this._theta=l,this._from=[i[0],i[1]],this._segIndex++,{cp1:s,cp2:o,to:i}}},{key:'calculateVectorAngle',value:function(e,t,l,a){var n=Math.atan2,i=n(t,e),s=n(a,l);return s>=i?s-i:2*c-(i-s)}}]),e}(),C=function(){function e(t,l){b(this,e),this.sets=t,this.closed=l}return m(e,[{key:'fit',value:function(e){var t=[],l=!0,a=!1,n=void 0;try{for(var s,o=this.sets[Symbol.iterator]();!(l=(s=o.next()).done);l=!0){var r=s.value,p=r.length,u=h(e*p);if(5>u){if(5>=p)continue;u=5}t.push(this.reduce(r,u))}}catch(e){a=!0,n=e}finally{try{!l&&o.return&&o.return()}finally{if(a)throw n}}var f='',g=!0,y=!1,c=void 0;try{for(var v,_,k=t[Symbol.iterator]();!(g=(v=k.next()).done);g=!0){_=v.value;for(var x,b=0;b<_.length;b++)x=_[b],f+=0===b?'M'+x[0]+','+x[1]:'L'+x[0]+','+x[1];this.closed&&(f+='z ')}}catch(e){y=!0,c=e}finally{try{!g&&k.return&&k.return()}finally{if(y)throw c}}return f}},{key:'distance',value:function(e,t){return y(f(e[0]-t[0],2)+f(e[1]-t[1],2))}},{key:'reduce',value:function(e,t){if(e.length<=t)return e;for(var l=e.slice(0);l.length>t;){for(var n=-1,o=-1,r=1;rn||s=u(e.py1,e.py2)&&this.py1<=d(e.py1,e.py2)?(this.xi=this.px1,this.yi=this.py1,!0):!!(this.py2>=u(e.py1,e.py2)&&this.py2<=d(e.py1,e.py2))&&(this.xi=this.px2,this.yi=this.py2,!0)):(this.xi=this.px1,this.yi=n*this.xi+s,!(-1e-5>(this.py1-this.yi)*(this.yi-this.py2)||-1e-5>(e.py1-this.yi)*(this.yi-e.py2))&&(!(1e-5>k(e.a))||!(-1e-5>(e.px1-this.xi)*(this.xi-e.px2)))):n===t?(this.xi=e.px1,this.yi=l*this.xi+i,!(-1e-5>(e.py1-this.yi)*(this.yi-e.py2)||-1e-5>(this.py1-this.yi)*(this.yi-this.py2))&&(!(1e-5>k(o))||!(-1e-5>(this.px1-this.xi)*(this.xi-this.px2)))):l===n?i==s&&(this.px1>=u(e.px1,e.px2)&&this.px1<=d(e.py1,e.py2)?(this.xi=this.px1,this.yi=this.py1,!0):!!(this.px2>=u(e.px1,e.px2)&&this.px2<=d(e.px1,e.px2))&&(this.xi=this.px2,this.yi=this.py2,!0)):(this.xi=(s-i)/(l-n),this.yi=l*this.xi+i,!(-1e-5>(this.px1-this.xi)*(this.xi-this.px2)||-1e-5>(e.px1-this.xi)*(this.xi-e.px2)))}}]),e}(),E=function(){function e(t,l,a,n,i,s,o,r){b(this,e),this.deltaX=0,this.hGap=0,this.top=t,this.bottom=l,this.left=a,this.right=n,this.gap=i,this.sinAngle=s,this.tanAngle=r,1e-4>k(s)?this.pos=a+i:.9999k(this.sinAngle)){if(this.posthis.right&&l>this.right;)if(this.pos+=this.hGap,t=this.pos-this.deltaX/2,l=this.pos+this.deltaX/2,this.pos>this.right+this.deltaX)return null;var i=new z([t,a],[l,n]);this.sLeft&&i.intersects(this.sLeft)&&(t=i.xi,a=i.yi),this.sRight&&i.intersects(this.sRight)&&(l=i.xi,n=i.yi),0s&&(s=4*a.strokeWidth),s=d(s,.1);var o=a.fillWeight;0>o&&(o=a.strokeWidth/2);var r=!0,p=!1,u=void 0;try{for(var f,h=e[Symbol.iterator]();!(r=(f=h.next()).done);r=!0)for(var y=f.value,k=t(y),x=k/s,b=g(x)-1,m=Math.atan((y[1][1]-y[0][1])/(y[1][0]-y[0][0])),O=0;Og;)g+=2*c,y+=2*c;y-g>2*c&&(g=0,y=2*c);var x=2*c/p.curveStepCount,b=u(x/2,(y-g)/2),m=this._arc(b,o,d,f,h,g,y,1,p),O=this._arc(b,o,d,f,h,g,y,1.5,p),P=m.concat(O);return s&&(r?(P=P.concat(this.doubleLine(o,d,o+f*v(g),d+h*_(g),p)),P=P.concat(this.doubleLine(o,d,o+f*v(y),d+h*_(y),p))):(P.push({op:'lineTo',data:[o,d]}),P.push({op:'lineTo',data:[o+f*v(g),d+h*_(g)]}))),{type:'path',ops:P}}},{key:'svgPath',value:function(e,t){e=(e||'').replace(/\n/g,' ').replace(/(-\s)/g,'-').replace('/(ss)/g',' ');var l=new A(e);if(t.simplification){var a=new C(l.linearPoints,l.closed),n=a.fit(t.simplification);l=new A(n)}for(var o=[],r=l.segments||[],d=0;du;)u+=2*c,f+=2*c;f-u>2*c&&(u=0,f=2*c);for(var h=(f-u)/s.curveStepCount,g=[],y=u;y<=f;y+=h)g.push([o+p*v(y),r+d*_(y)]);return g.push([o+p*v(f),r+d*_(f)]),g.push([o,r]),this.patternFillPolygon(g,s)}},{key:'getOffset',value:function(e,t,l){return l.roughness*(Math.random()*(t-e)+e)}},{key:'doubleLine',value:function(e,t,l,a,n){var i=this._line(e,t,l,a,n,!0,!1),s=this._line(e,t,l,a,n,!0,!0);return i.concat(s)}},{key:'_line',value:function(e,t,l,a,n,i,s){var o=f(e-l,2)+f(t-a,2),r=n.maxRandomnessOffset||0;100*(r*r)>o&&(r=y(o)/10);var p=r/2,d=.2+.2*Math.random(),u=n.bowing*n.maxRandomnessOffset*(a-t)/200,h=n.bowing*n.maxRandomnessOffset*(e-l)/200;u=this.getOffset(-u,u,n),h=this.getOffset(-h,h,n);var g=[];return i&&(s?g.push({op:'move',data:[e+this.getOffset(-p,p,n),t+this.getOffset(-p,p,n)]}):g.push({op:'move',data:[e+this.getOffset(-r,r,n),t+this.getOffset(-r,r,n)]})),s?g.push({op:'bcurveTo',data:[u+e+(l-e)*d+this.getOffset(-p,p,n),h+t+(a-t)*d+this.getOffset(-p,p,n),u+e+2*(l-e)*d+this.getOffset(-p,p,n),h+t+2*(a-t)*d+this.getOffset(-p,p,n),l+this.getOffset(-p,p,n),a+this.getOffset(-p,p,n)]}):g.push({op:'bcurveTo',data:[u+e+(l-e)*d+this.getOffset(-r,r,n),h+t+(a-t)*d+this.getOffset(-r,r,n),u+e+2*(l-e)*d+this.getOffset(-r,r,n),h+t+2*(a-t)*d+this.getOffset(-r,r,n),l+this.getOffset(-r,r,n),a+this.getOffset(-r,r,n)]}),g}},{key:'_curve',value:function(e,t,l){var a=e.length,n=[];if(3h;h++)0===h?o.push({op:'move',data:[r.x,r.y]}):o.push({op:'move',data:[r.x+this.getOffset(-d[0],d[0],p),r.y+this.getOffset(-d[0],d[0],p)]}),u=[n+this.getOffset(-d[h],d[h],p),s+this.getOffset(-d[h],d[h],p)],o.push({op:'bcurveTo',data:[e+this.getOffset(-d[h],d[h],p),t+this.getOffset(-d[h],d[h],p),l+this.getOffset(-d[h],d[h],p),a+this.getOffset(-d[h],d[h],p),u[0],u[1]]});return r.setPosition(u[0],u[1]),o}},{key:'_processSegment',value:function(e,t,l,a){var n=[];switch(t.key){case'M':case'm':{var s='m'===t.key;if(2<=t.data.length){var o=+t.data[0],r=+t.data[1];s&&(o+=e.x,r+=e.y);var p=1*(a.maxRandomnessOffset||0);o+=this.getOffset(-p,p,a),r+=this.getOffset(-p,p,a),e.setPosition(o,r),n.push({op:'move',data:[o,r]})}break}case'L':case'l':{var d='l'===t.key;if(2<=t.data.length){var u=+t.data[0],h=+t.data[1];d&&(u+=e.x,h+=e.y),n=n.concat(this.doubleLine(e.x,e.y,u,h,a)),e.setPosition(u,h)}break}case'H':case'h':{var g='h'===t.key;if(t.data.length){var c=+t.data[0];g&&(c+=e.x),n=n.concat(this.doubleLine(e.x,e.y,c,e.y,a)),e.setPosition(c,e.y)}break}case'V':case'v':{var v='v'===t.key;if(t.data.length){var _=+t.data[0];v&&(_+=e.y),n=n.concat(this.doubleLine(e.x,e.y,e.x,_,a)),e.setPosition(e.x,_)}break}case'Z':case'z':{e.first&&(n=n.concat(this.doubleLine(e.x,e.y,e.first[0],e.first[1],a)),e.setPosition(e.first[0],e.first[1]),e.first=null);break}case'C':case'c':{var k='c'===t.key;if(6<=t.data.length){var b=+t.data[0],m=+t.data[1],O=+t.data[2],P=+t.data[3],w=+t.data[4],S=+t.data[5];k&&(b+=e.x,O+=e.x,w+=e.x,m+=e.y,P+=e.y,S+=e.y);var A=this._bezierTo(b,m,O,P,w,S,e,a);n=n.concat(A),e.bezierReflectionPoint=[w+(w-O),S+(S-P)]}break}case'S':case's':{var C='s'===t.key;if(4<=t.data.length){var z=+t.data[0],E=+t.data[1],L=+t.data[2],W=+t.data[3];C&&(z+=e.x,L+=e.x,E+=e.y,W+=e.y);var N=z,D=E,R=l?l.key:'',B=null;('c'===R||'C'===R||'s'===R||'S'===R)&&(B=e.bezierReflectionPoint),B&&(N=B[0],D=B[1]);var F=this._bezierTo(N,D,z,E,L,W,e,a);n=n.concat(F),e.bezierReflectionPoint=[L+(L-z),W+(W-E)]}break}case'Q':case'q':{var M='q'===t.key;if(4<=t.data.length){var q=+t.data[0],U=+t.data[1],X=+t.data[2],V=+t.data[3];M&&(q+=e.x,X+=e.x,U+=e.y,V+=e.y);var G=1*(1+.2*a.roughness),j=1.5*(1+.22*a.roughness);n.push({op:'move',data:[e.x+this.getOffset(-G,G,a),e.y+this.getOffset(-G,G,a)]});var I=[X+this.getOffset(-G,G,a),V+this.getOffset(-G,G,a)];n.push({op:'qcurveTo',data:[q+this.getOffset(-G,G,a),U+this.getOffset(-G,G,a),I[0],I[1]]}),n.push({op:'move',data:[e.x+this.getOffset(-j,j,a),e.y+this.getOffset(-j,j,a)]}),I=[X+this.getOffset(-j,j,a),V+this.getOffset(-j,j,a)],n.push({op:'qcurveTo',data:[q+this.getOffset(-j,j,a),U+this.getOffset(-j,j,a),I[0],I[1]]}),e.setPosition(I[0],I[1]),e.quadReflectionPoint=[X+(X-q),V+(V-U)]}break}case'T':case't':{var Q='t'===t.key;if(2<=t.data.length){var $=+t.data[0],Z=+t.data[1];Q&&($+=e.x,Z+=e.y);var H=$,J=Z,Y=l?l.key:'',K=null;('q'===Y||'Q'===Y||'t'===Y||'T'===Y)&&(K=e.quadReflectionPoint),K&&(H=K[0],J=K[1]);var ee=1*(1+.2*a.roughness),te=1.5*(1+.22*a.roughness);n.push({op:'move',data:[e.x+this.getOffset(-ee,ee,a),e.y+this.getOffset(-ee,ee,a)]});var le=[$+this.getOffset(-ee,ee,a),Z+this.getOffset(-ee,ee,a)];n.push({op:'qcurveTo',data:[H+this.getOffset(-ee,ee,a),J+this.getOffset(-ee,ee,a),le[0],le[1]]}),n.push({op:'move',data:[e.x+this.getOffset(-te,te,a),e.y+this.getOffset(-te,te,a)]}),le=[$+this.getOffset(-te,te,a),Z+this.getOffset(-te,te,a)],n.push({op:'qcurveTo',data:[H+this.getOffset(-te,te,a),J+this.getOffset(-te,te,a),le[0],le[1]]}),e.setPosition(le[0],le[1]),e.quadReflectionPoint=[$+($-H),Z+(Z-J)]}break}case'A':case'a':{var ae='a'===t.key;if(7<=t.data.length){var ne=+t.data[0],ie=+t.data[1],se=+t.data[2],oe=+t.data[3],re=+t.data[4],pe=+t.data[5],de=+t.data[6];if(ae&&(pe+=e.x,de+=e.y),pe===e.x&&de===e.y)break;if(0==ne||0==ie)n=n.concat(this.doubleLine(e.x,e.y,pe,de,a)),e.setPosition(pe,de);else for(var ue=0;1>ue;ue++)for(var fe,he=new T([e.x,e.y],[pe,de],[ne,ie],se,!!oe,!!re),ge=he.getNextSegment();ge;)fe=this._bezierTo(ge.cp1[0],ge.cp1[1],ge.cp2[0],ge.cp2[1],ge.to[0],ge.to[1],e,a),n=n.concat(fe),ge=he.getNextSegment()}break}default:}return n}}]),e}(),F='undefined'!=typeof self,M=F&&self&&self.document&&self.document.currentScript&&self.document.currentScript.src,q='undefined'!=typeof self,U=function(){function e(t,l){b(this,e),this.defaultOptions={maxRandomnessOffset:2,roughness:1,bowing:1,stroke:'#000',strokeWidth:1,curveTightness:0,curveStepCount:9,fillStyle:'hachure',fillWeight:-1,hachureAngle:-41,hachureGap:-1},this.config=t||{},this.surface=l,this.renderer=o(this.config),this.config.options&&(this.defaultOptions=this._options(this.config.options))}return m(e,[{key:'_options',value:function(e){return e?Object.assign({},this.defaultOptions,e):this.defaultOptions}},{key:'_drawable',value:function(e,t,l){return{shape:e,sets:t||[],options:l||this.defaultOptions}}},{key:'getCanvasSize',value:function(){var e=function(e){return e&&'object'===('undefined'==typeof e?'undefined':x(e))&&e.baseVal&&e.baseVal.value?e.baseVal.value:e||100};return this.surface?[e(this.surface.width),e(this.surface.height)]:[100,100]}},{key:'computePolygonSize',value:function(e){if(e.length){for(var t=e[0][0],l=e[0][0],a=e[0][1],n=e[0][1],s=1;sl&&(l=t.strokeWidth/2),{d:this.opsToPath(e),stroke:t.fill||'none',strokeWidth:l,fill:'none'}}},{key:'opsToPath',value:function(e){var t='',l=!0,a=!1,n=void 0;try{for(var i,s=e.ops[Symbol.iterator]();!(l=(i=s.next()).done);l=!0){var o=i.value,r=o.data;switch(o.op){case'move':t+='M'+r[0]+' '+r[1]+' ';break;case'bcurveTo':t+='C'+r[0]+' '+r[1]+', '+r[2]+' '+r[3]+', '+r[4]+' '+r[5]+' ';break;case'qcurveTo':t+='Q'+r[0]+' '+r[1]+', '+r[2]+' '+r[3]+' ';break;case'lineTo':t+='L'+r[0]+' '+r[1]+' ';}}}catch(e){a=!0,n=e}finally{try{!l&&s.return&&s.return()}finally{if(a)throw n}}return t.trim()}},{key:'lib',get:function(){return this.renderer}}]),e}(),X=function(e){function t(e,l){return b(this,t),P(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,l))}return O(t,e),m(t,[{key:'line',value:function(e,t,l,a,n){var i=this._options(n);return this._drawable('line',[this.lib.line(e,t,l,a,i)],i)}},{key:'rectangle',value:function(e,t,l,a,n){var i=this._options(n),s=[];if(i.fill){var o=[[e,t],[e+l,t],[e+l,t+a],[e,t+a]];'solid'===i.fillStyle?s.push(this.lib.solidFillPolygon(o,i)):s.push(this.lib.patternFillPolygon(o,i))}return s.push(this.lib.rectangle(e,t,l,a,i)),this._drawable('rectangle',s,i)}},{key:'ellipse',value:function(e,t,l,a,n){var i=this._options(n),s=[];if(i.fill)if('solid'===i.fillStyle){var o=this.lib.ellipse(e,t,l,a,i);o.type='fillPath',s.push(o)}else s.push(this.lib.patternFillEllipse(e,t,l,a,i));return s.push(this.lib.ellipse(e,t,l,a,i)),this._drawable('ellipse',s,i)}},{key:'circle',value:function(e,t,l,a){var n=this.ellipse(e,t,l,l,a);return n.shape='circle',n}},{key:'linearPath',value:function(e,t){var l=this._options(t);return this._drawable('linearPath',[this.lib.linearPath(e,!1,l)],l)}},{key:'arc',value:function(e,t,l,a,n,i){var s=!!(6a&&(a=l.strokeWidth/2),e.save(),e.strokeStyle=l.fill||'',e.lineWidth=a,this._drawToContext(e,t),e.restore()}},{key:'_drawToContext',value:function(e,t){e.beginPath();var l=!0,a=!1,n=void 0;try{for(var i,s=t.ops[Symbol.iterator]();!(l=(i=s.next()).done);l=!0){var o=i.value,r=o.data;switch(o.op){case'move':e.moveTo(r[0],r[1]);break;case'bcurveTo':e.bezierCurveTo(r[0],r[1],r[2],r[3],r[4],r[5]);break;case'qcurveTo':e.quadraticCurveTo(r[0],r[1],r[2],r[3]);break;case'lineTo':e.lineTo(r[0],r[1]);}}}catch(e){a=!0,n=e}finally{try{!l&&s.return&&s.return()}finally{if(a)throw n}}'fillPath'===t.type?e.fill():e.stroke()}}],[{key:'createRenderer',value:function(){return new B}}]),e}(),j=function(e){function t(e,l){b(this,t);var a=P(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e));return a.gen=new X(l||null,a.canvas),a}return O(t,e),m(t,[{key:'getDefaultOptions',value:function(){return this.gen.defaultOptions}},{key:'line',value:function(e,t,l,a,n){var i=this.gen.line(e,t,l,a,n);return this.draw(i),i}},{key:'rectangle',value:function(e,t,l,a,n){var i=this.gen.rectangle(e,t,l,a,n);return this.draw(i),i}},{key:'ellipse',value:function(e,t,l,a,n){var i=this.gen.ellipse(e,t,l,a,n);return this.draw(i),i}},{key:'circle',value:function(e,t,l,a){var n=this.gen.circle(e,t,l,a);return this.draw(n),n}},{key:'linearPath',value:function(e,t){var l=this.gen.linearPath(e,t);return this.draw(l),l}},{key:'polygon',value:function(e,t){var l=this.gen.polygon(e,t);return this.draw(l),l}},{key:'arc',value:function(e,t,l,a,n,i){var s=!!(6a&&(a=l.strokeWidth/2);var n=e.createElementNS('http://www.w3.org/2000/svg','path');return n.setAttribute('d',this.opsToPath(t)),n.style.stroke=l.fill||null,n.style.strokeWidth=a+'',n.style.fill='none',n}},{key:'defs',get:function(){var e=this.svg.ownerDocument||$&&document;if(e&&!this._defs){var t=e.createElementNS('http://www.w3.org/2000/svg','defs');this.svg.firstChild?this.svg.insertBefore(t,this.svg.firstChild):this.svg.appendChild(t),this._defs=t}return this._defs||null}}],[{key:'createRenderer',value:function(){return new B}}]),e}(),H=function(e){function t(e,l){b(this,t);var a=P(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e));return a.gen=new X(l||null,a.svg),a}return O(t,e),m(t,[{key:'getDefaultOptions',value:function(){return this.gen.defaultOptions}},{key:'opsToPath',value:function(e){return this.gen.opsToPath(e)}},{key:'line',value:function(e,t,l,a,n){var i=this.gen.line(e,t,l,a,n);return this.draw(i)}},{key:'rectangle',value:function(e,t,l,a,n){var i=this.gen.rectangle(e,t,l,a,n);return this.draw(i)}},{key:'ellipse',value:function(e,t,l,a,n){var i=this.gen.ellipse(e,t,l,a,n);return this.draw(i)}},{key:'circle',value:function(e,t,l,a){var n=this.gen.circle(e,t,l,a);return this.draw(n)}},{key:'linearPath',value:function(e,t){var l=this.gen.linearPath(e,t);return this.draw(l)}},{key:'polygon',value:function(e,t){var l=this.gen.polygon(e,t);return this.draw(l)}},{key:'arc',value:function(e,t,l,a,n,i){var s=!!(6h&&(h=4*t.strokeWidth),h=d(h,.1);const g=r%180*(b/180),c=_(g),u=m(g),y=p(g),x=new S(l-1,o+1,n-1,a+1,h,u,c,y);for(let t;null!=(t=x.nextLine());){const n=i(t,e);for(let e=0;e=h&&(h=4*a.strokeWidth);let g=a.fillWeight;0>g&&(g=a.strokeWidth/2);const c=p(f%180*(b/180)),u=d/r,_=y(u*c*u*c+1),x=u*c/_,m=1/_,O=h/(r*d/y(d*m*(d*m)+r*x*(r*x))/r);let P=y(r*r-(e-r+O)*(e-r+O));for(let p=e-r+O;pd){const e=y(1-d/(this._rx*this._rx*this._ry*this._ry));this._rx*=e,this._ry*=e,p=0}else p=(n===a?-1:1)*y(d/(this._rx*this._rx*r*r+this._ry*this._ry*o*o));const f=p*this._rx*r/this._ry,h=-p*this._ry*o/this._rx;this._C=[0,0],this._C[0]=this._cosPhi*f-this._sinPhi*h+(e[0]+t[0])/2,this._C[1]=this._sinPhi*f+this._cosPhi*h+(e[1]+t[1])/2,this._theta=this.calculateVectorAngle(1,0,(o-f)/this._rx,(r-h)/this._ry);let g=this.calculateVectorAngle((o-f)/this._rx,(r-h)/this._ry,(-o-f)/this._rx,(-r-h)/this._ry);!a&&0g&&(g+=2*b),this._numSegs=u(w(g/(b/2))),this._delta=g/this._numSegs,this._T=8/3*m(this._delta/4)*m(this._delta/4)/m(this._delta/2)}getNextSegment(){if(this._segIndex===this._numSegs)return null;const e=_(this._theta),t=m(this._theta),i=this._theta+this._delta,s=_(i),n=m(i),a=[this._cosPhi*this._rx*s-this._sinPhi*this._ry*n+this._C[0],this._sinPhi*this._rx*s+this._cosPhi*this._ry*n+this._C[1]],l=[this._from[0]+this._T*(-this._cosPhi*this._rx*t-this._sinPhi*this._ry*e),this._from[1]+this._T*(-this._sinPhi*this._rx*t+this._cosPhi*this._ry*e)],o=[a[0]+this._T*(this._cosPhi*this._rx*n+this._sinPhi*this._ry*s),a[1]+this._T*(this._sinPhi*this._rx*n-this._cosPhi*this._ry*s)];return this._theta=i,this._from=[a[0],a[1]],this._segIndex++,{cp1:l,cp2:o,to:a}}calculateVectorAngle(e,t,i,s){var n=Math.atan2;const a=n(t,e),l=n(s,i);return l>=a?l-a:2*b-(a-l)}}class k{constructor(e,t){this.sets=e,this.closed=t}fit(e){const t=[];for(const i of this.sets){const s=i.length;let n=c(e*s);if(5>n){if(5>=s)continue;n=5}t.push(this.reduce(i,n))}let s='';for(const n of t){for(let e=0;et;){let e=-1,t=-1;for(let l=1;le||s=f(e.py1,e.py2)&&this.py1<=d(e.py1,e.py2)?(this.xi=this.px1,this.yi=this.py1,!0):!!(this.py2>=f(e.py1,e.py2)&&this.py2<=d(e.py1,e.py2))&&(this.xi=this.px2,this.yi=this.py2,!0)):(this.xi=this.px1,this.yi=i*this.xi+n,!(-1e-5>(this.py1-this.yi)*(this.yi-this.py2)||-1e-5>(e.py1-this.yi)*(this.yi-e.py2))&&(!(1e-5>w(e.a))||!(-1e-5>(e.px1-this.xi)*(this.xi-e.px2)))):i===h?(this.xi=e.px1,this.yi=t*this.xi+s,!(-1e-5>(e.py1-this.yi)*(this.yi-e.py2)||-1e-5>(this.py1-this.yi)*(this.yi-this.py2))&&(!(1e-5>w(l))||!(-1e-5>(this.px1-this.xi)*(this.xi-this.px2)))):t===i?s==n&&(this.px1>=f(e.px1,e.px2)&&this.px1<=d(e.py1,e.py2)?(this.xi=this.px1,this.yi=this.py1,!0):!!(this.px2>=f(e.px1,e.px2)&&this.px2<=d(e.px1,e.px2))&&(this.xi=this.px2,this.yi=this.py2,!0)):(this.xi=(n-s)/(t-i),this.yi=t*this.xi+s,!(-1e-5>(this.px1-this.xi)*(this.xi-this.px2)||-1e-5>(e.px1-this.xi)*(this.xi-e.px2)))}}class S{constructor(e,t,i,s,n,a,l,o){this.deltaX=0,this.hGap=0,this.top=e,this.bottom=t,this.left=i,this.right=s,this.gap=n,this.sinAngle=a,this.tanAngle=o,1e-4>w(a)?this.pos=i+n:.9999w(this.sinAngle)){if(this.posthis.right&&t>this.right;)if(this.pos+=this.hGap,e=this.pos-this.deltaX/2,t=this.pos+this.deltaX/2,this.pos>this.right+this.deltaX)return null;const a=new A([e,i],[t,n]);this.sLeft&&a.intersects(this.sLeft)&&(e=a.xi,i=a.yi),this.sRight&&a.intersects(this.sRight)&&(t=a.xi,n=a.yi),0a&&(a=4*s.strokeWidth),a=d(a,.1);let o=s.fillWeight;0>o&&(o=s.strokeWidth/2);for(const r of e){const e=t(r),i=e/a,l=u(i)-1,p=Math.atan((r[1][1]-r[0][1])/(r[1][0]-r[0][0]));for(let e=0;ec;)c+=2*b,u+=2*b;u-c>2*b&&(c=0,u=2*b);const y=2*b/p.curveStepCount,x=f(y/2,(u-c)/2),O=this._arc(x,o,d,h,g,c,u,1,p),P=this._arc(x,o,d,h,g,c,u,1.5,p);let v=O.concat(P);return l&&(r?(v=v.concat(this.doubleLine(o,d,o+h*_(c),d+g*m(c),p)),v=v.concat(this.doubleLine(o,d,o+h*_(u),d+g*m(u),p))):(v.push({op:'lineTo',data:[o,d]}),v.push({op:'lineTo',data:[o+h*_(c),d+g*m(c)]}))),{type:'path',ops:v}}svgPath(e,t){e=(e||'').replace(/\n/g,' ').replace(/(-\s)/g,'-').replace('/(ss)/g',' ');let n=new P(e);if(t.simplification){const e=new k(n.linearPoints,n.closed),i=e.fit(t.simplification);n=new P(i)}let a=[];const l=n.segments||[];for(let o=0;of;)f+=2*b,h+=2*b;h-f>2*b&&(f=0,h=2*b);const g=(h-f)/l.curveStepCount,c=[];for(let u=f;u<=h;u+=g)c.push([o+p*_(u),r+d*m(u)]);return c.push([o+p*_(h),r+d*m(h)]),c.push([o,r]),this.patternFillPolygon(c,l)}getOffset(e,t,i){return i.roughness*(Math.random()*(t-e)+e)}doubleLine(e,t,i,s,n){const a=this._line(e,t,i,s,n,!0,!1),l=this._line(e,t,i,s,n,!0,!0);return a.concat(l)}_line(e,t,i,s,n,a,l){const o=g(e-i,2)+g(t-s,2);let r=n.maxRandomnessOffset||0;100*(r*r)>o&&(r=y(o)/10);const p=r/2,d=.2+.2*Math.random();let f=n.bowing*n.maxRandomnessOffset*(s-t)/200,h=n.bowing*n.maxRandomnessOffset*(e-i)/200;f=this.getOffset(-f,f,n),h=this.getOffset(-h,h,n);const c=[];return a&&(l?c.push({op:'move',data:[e+this.getOffset(-p,p,n),t+this.getOffset(-p,p,n)]}):c.push({op:'move',data:[e+this.getOffset(-r,r,n),t+this.getOffset(-r,r,n)]})),l?c.push({op:'bcurveTo',data:[f+e+(i-e)*d+this.getOffset(-p,p,n),h+t+(s-t)*d+this.getOffset(-p,p,n),f+e+2*(i-e)*d+this.getOffset(-p,p,n),h+t+2*(s-t)*d+this.getOffset(-p,p,n),i+this.getOffset(-p,p,n),s+this.getOffset(-p,p,n)]}):c.push({op:'bcurveTo',data:[f+e+(i-e)*d+this.getOffset(-r,r,n),h+t+(s-t)*d+this.getOffset(-r,r,n),f+e+2*(i-e)*d+this.getOffset(-r,r,n),h+t+2*(s-t)*d+this.getOffset(-r,r,n),i+this.getOffset(-r,r,n),s+this.getOffset(-r,r,n)]}),c}_curve(e,t,i){const n=e.length;let a=[];if(3f;f++)0===f?o.push({op:'move',data:[r.x,r.y]}):o.push({op:'move',data:[r.x+this.getOffset(-d[0],d[0],p),r.y+this.getOffset(-d[0],d[0],p)]}),h=[a+this.getOffset(-d[f],d[f],p),l+this.getOffset(-d[f],d[f],p)],o.push({op:'bcurveTo',data:[e+this.getOffset(-d[f],d[f],p),t+this.getOffset(-d[f],d[f],p),s+this.getOffset(-d[f],d[f],p),n+this.getOffset(-d[f],d[f],p),h[0],h[1]]});return r.setPosition(h[0],h[1]),o}_processSegment(e,t,i,s){let n=[];switch(t.key){case'M':case'm':{const i='m'===t.key;if(2<=t.data.length){let a=+t.data[0],l=+t.data[1];i&&(a+=e.x,l+=e.y);const o=1*(s.maxRandomnessOffset||0);a+=this.getOffset(-o,o,s),l+=this.getOffset(-o,o,s),e.setPosition(a,l),n.push({op:'move',data:[a,l]})}break}case'L':case'l':{const i='l'===t.key;if(2<=t.data.length){let a=+t.data[0],l=+t.data[1];i&&(a+=e.x,l+=e.y),n=n.concat(this.doubleLine(e.x,e.y,a,l,s)),e.setPosition(a,l)}break}case'H':case'h':{const i='h'===t.key;if(t.data.length){let a=+t.data[0];i&&(a+=e.x),n=n.concat(this.doubleLine(e.x,e.y,a,e.y,s)),e.setPosition(a,e.y)}break}case'V':case'v':{const i='v'===t.key;if(t.data.length){let a=+t.data[0];i&&(a+=e.y),n=n.concat(this.doubleLine(e.x,e.y,e.x,a,s)),e.setPosition(e.x,a)}break}case'Z':case'z':{e.first&&(n=n.concat(this.doubleLine(e.x,e.y,e.first[0],e.first[1],s)),e.setPosition(e.first[0],e.first[1]),e.first=null);break}case'C':case'c':{const i='c'===t.key;if(6<=t.data.length){let a=+t.data[0],l=+t.data[1],o=+t.data[2],r=+t.data[3],p=+t.data[4],d=+t.data[5];i&&(a+=e.x,o+=e.x,p+=e.x,l+=e.y,r+=e.y,d+=e.y);const f=this._bezierTo(a,l,o,r,p,d,e,s);n=n.concat(f),e.bezierReflectionPoint=[p+(p-o),d+(d-r)]}break}case'S':case's':{const a='s'===t.key;if(4<=t.data.length){let l=+t.data[0],o=+t.data[1],r=+t.data[2],p=+t.data[3];a&&(l+=e.x,r+=e.x,o+=e.y,p+=e.y);let d=l,f=o;const h=i?i.key:'';let g=null;('c'===h||'C'===h||'s'===h||'S'===h)&&(g=e.bezierReflectionPoint),g&&(d=g[0],f=g[1]);const c=this._bezierTo(d,f,l,o,r,p,e,s);n=n.concat(c),e.bezierReflectionPoint=[r+(r-l),p+(p-o)]}break}case'Q':case'q':{const i='q'===t.key;if(4<=t.data.length){let a=+t.data[0],l=+t.data[1],o=+t.data[2],r=+t.data[3];i&&(a+=e.x,o+=e.x,l+=e.y,r+=e.y);const p=1*(1+.2*s.roughness),d=1.5*(1+.22*s.roughness);n.push({op:'move',data:[e.x+this.getOffset(-p,p,s),e.y+this.getOffset(-p,p,s)]});let h=[o+this.getOffset(-p,p,s),r+this.getOffset(-p,p,s)];n.push({op:'qcurveTo',data:[a+this.getOffset(-p,p,s),l+this.getOffset(-p,p,s),h[0],h[1]]}),n.push({op:'move',data:[e.x+this.getOffset(-d,d,s),e.y+this.getOffset(-d,d,s)]}),h=[o+this.getOffset(-d,d,s),r+this.getOffset(-d,d,s)],n.push({op:'qcurveTo',data:[a+this.getOffset(-d,d,s),l+this.getOffset(-d,d,s),h[0],h[1]]}),e.setPosition(h[0],h[1]),e.quadReflectionPoint=[o+(o-a),r+(r-l)]}break}case'T':case't':{const a='t'===t.key;if(2<=t.data.length){let l=+t.data[0],o=+t.data[1];a&&(l+=e.x,o+=e.y);let r=l,p=o;const d=i?i.key:'';let h=null;('q'===d||'Q'===d||'t'===d||'T'===d)&&(h=e.quadReflectionPoint),h&&(r=h[0],p=h[1]);const g=1*(1+.2*s.roughness),c=1.5*(1+.22*s.roughness);n.push({op:'move',data:[e.x+this.getOffset(-g,g,s),e.y+this.getOffset(-g,g,s)]});let u=[l+this.getOffset(-g,g,s),o+this.getOffset(-g,g,s)];n.push({op:'qcurveTo',data:[r+this.getOffset(-g,g,s),p+this.getOffset(-g,g,s),u[0],u[1]]}),n.push({op:'move',data:[e.x+this.getOffset(-c,c,s),e.y+this.getOffset(-c,c,s)]}),u=[l+this.getOffset(-c,c,s),o+this.getOffset(-c,c,s)],n.push({op:'qcurveTo',data:[r+this.getOffset(-c,c,s),p+this.getOffset(-c,c,s),u[0],u[1]]}),e.setPosition(u[0],u[1]),e.quadReflectionPoint=[l+(l-r),o+(o-p)]}break}case'A':case'a':{const i='a'===t.key;if(7<=t.data.length){const a=+t.data[0],l=+t.data[1],o=+t.data[2],r=+t.data[3],p=+t.data[4];let d=+t.data[5],f=+t.data[6];if(i&&(d+=e.x,f+=e.y),d===e.x&&f===e.y)break;if(0==a||0==l)n=n.concat(this.doubleLine(e.x,e.y,d,f,s)),e.setPosition(d,f);else for(let t=0;1>t;t++){const t=new v([e.x,e.y],[d,f],[a,l],o,!!r,!!p);for(let i=t.getNextSegment();i;){const a=this._bezierTo(i.cp1[0],i.cp1[1],i.cp2[0],i.cp2[1],i.to[0],i.to[1],e,s);n=n.concat(a),i=t.getNextSegment()}}}break}default:}return n}}const L='undefined'!=typeof self,R=L&&self&&self.document&&self.document.currentScript&&self.document.currentScript.src,D='undefined'!=typeof self;class B{constructor(e,t){this.defaultOptions={maxRandomnessOffset:2,roughness:1,bowing:1,stroke:'#000',strokeWidth:1,curveTightness:0,curveStepCount:9,fillStyle:'hachure',fillWeight:-1,hachureAngle:-41,hachureGap:-1},this.config=e||{},this.surface=t,this.renderer=o(this.config),this.config.options&&(this.defaultOptions=this._options(this.config.options))}_options(e){return e?Object.assign({},this.defaultOptions,e):this.defaultOptions}_drawable(e,t,i){return{shape:e,sets:t||[],options:i||this.defaultOptions}}get lib(){return this.renderer}getCanvasSize(){const e=e=>e&&'object'==typeof e&&e.baseVal&&e.baseVal.value?e.baseVal.value:e||100;return this.surface?[e(this.surface.width),e(this.surface.height)]:[100,100]}computePolygonSize(e){if(e.length){let t=e[0][0],s=e[0][0],n=e[0][1],a=e[0][1];for(let l=1;li&&(i=t.strokeWidth/2),{d:this.opsToPath(e),stroke:t.fill||'none',strokeWidth:i,fill:'none'}}opsToPath(e){let t='';for(const i of e.ops){const e=i.data;switch(i.op){case'move':t+=`M${e[0]} ${e[1]} `;break;case'bcurveTo':t+=`C${e[0]} ${e[1]}, ${e[2]} ${e[3]}, ${e[4]} ${e[5]} `;break;case'qcurveTo':t+=`Q${e[0]} ${e[1]}, ${e[2]} ${e[3]} `;break;case'lineTo':t+=`L${e[0]} ${e[1]} `;}}return t.trim()}}const M='undefined'!=typeof document;class q{constructor(e,t){this.canvas=e,this.ctx=this.canvas.getContext('2d'),this.gen=new B(t||null,this.canvas)}get generator(){return this.gen}static createRenderer(){return new E}line(e,t,i,s,n){const a=this.gen.line(e,t,i,s,n);return this.draw(a),a}rectangle(e,t,i,s,n){const a=this.gen.rectangle(e,t,i,s,n);return this.draw(a),a}ellipse(e,t,i,s,n){const a=this.gen.ellipse(e,t,i,s,n);return this.draw(a),a}circle(e,t,i,s){const n=this.gen.circle(e,t,i,s);return this.draw(n),n}linearPath(e,t){const i=this.gen.linearPath(e,t);return this.draw(i),i}polygon(e,t){const i=this.gen.polygon(e,t);return this.draw(i),i}arc(e,t,i,s,n,a,l=!1,o){const r=this.gen.arc(e,t,i,s,n,a,l,o);return this.draw(r),r}curve(e,t){const i=this.gen.curve(e,t);return this.draw(i),i}path(e,t){const i=this.gen.path(e,t);return this.draw(i),i}draw(e){const t=e.sets||[],i=e.options||this.gen.defaultOptions,s=this.ctx;for(const n of t)switch(n.type){case'path':s.save(),s.strokeStyle=i.stroke,s.lineWidth=i.strokeWidth,this._drawToContext(s,n),s.restore();break;case'fillPath':s.save(),s.fillStyle=i.fill||'',this._drawToContext(s,n),s.restore();break;case'fillSketch':this.fillSketch(s,n,i);break;case'path2Dfill':{this.ctx.save(),this.ctx.fillStyle=i.fill||'';const e=new Path2D(n.path);this.ctx.fill(e),this.ctx.restore();break}case'path2Dpattern':{const e=this.canvas.ownerDocument||M&&document;if(e){const t=n.size,s=e.createElement('canvas'),a=s.getContext('2d'),l=this.computeBBox(n.path);l&&(l.width||l.height)?(s.width=this.canvas.width,s.height=this.canvas.height,a.translate(l.x||0,l.y||0)):(s.width=t[0],s.height=t[1]),this.fillSketch(a,n,i),this.ctx.save(),this.ctx.fillStyle=this.ctx.createPattern(s,'repeat');const o=new Path2D(n.path);this.ctx.fill(o),this.ctx.restore()}else console.error('Cannot render path2Dpattern. No defs/document defined.');break}}}computeBBox(e){if(M)try{const t=document.createElementNS('http://www.w3.org/2000/svg','svg');t.setAttribute('width','0'),t.setAttribute('height','0');const i=self.document.createElementNS('http://www.w3.org/2000/svg','path');i.setAttribute('d',e),t.appendChild(i),document.body.appendChild(t);const s=i.getBBox();return document.body.removeChild(t),s}catch(e){}return null}fillSketch(e,t,i){let s=i.fillWeight;0>s&&(s=i.strokeWidth/2),e.save(),e.strokeStyle=i.fill||'',e.lineWidth=s,this._drawToContext(e,t),e.restore()}_drawToContext(e,t){e.beginPath();for(const i of t.ops){const t=i.data;switch(i.op){case'move':e.moveTo(t[0],t[1]);break;case'bcurveTo':e.bezierCurveTo(t[0],t[1],t[2],t[3],t[4],t[5]);break;case'qcurveTo':e.quadraticCurveTo(t[0],t[1],t[2],t[3]);break;case'lineTo':e.lineTo(t[0],t[1]);}}'fillPath'===t.type?e.fill():e.stroke()}}class F extends B{async line(e,t,i,s,n){const a=this._options(n);return this._drawable('line',[await this.lib.line(e,t,i,s,a)],a)}async rectangle(e,t,i,s,n){const a=this._options(n),l=[];if(a.fill){const n=[[e,t],[e+i,t],[e+i,t+s],[e,t+s]];'solid'===a.fillStyle?l.push((await this.lib.solidFillPolygon(n,a))):l.push((await this.lib.patternFillPolygon(n,a)))}return l.push((await this.lib.rectangle(e,t,i,s,a))),this._drawable('rectangle',l,a)}async ellipse(e,t,i,s,n){const a=this._options(n),l=[];if(a.fill)if('solid'===a.fillStyle){const n=await this.lib.ellipse(e,t,i,s,a);n.type='fillPath',l.push(n)}else l.push((await this.lib.patternFillEllipse(e,t,i,s,a)));return l.push((await this.lib.ellipse(e,t,i,s,a))),this._drawable('ellipse',l,a)}async circle(e,t,i,s){const n=await this.ellipse(e,t,i,i,s);return n.shape='circle',n}async linearPath(e,t){const i=this._options(t);return this._drawable('linearPath',[await this.lib.linearPath(e,!1,i)],i)}async arc(e,t,i,s,n,a,l=!1,r){const p=this._options(r),o=[];if(l&&p.fill)if('solid'===p.fillStyle){const l=await this.lib.arc(e,t,i,s,n,a,!0,!1,p);l.type='fillPath',o.push(l)}else o.push((await this.lib.patternFillArc(e,t,i,s,n,a,p)));return o.push((await this.lib.arc(e,t,i,s,n,a,l,!0,p))),this._drawable('arc',o,p)}async curve(e,t){const i=this._options(t);return this._drawable('curve',[await this.lib.curve(e,i)],i)}async polygon(e,t){const i=this._options(t),s=[];if(i.fill)if('solid'===i.fillStyle)s.push((await this.lib.solidFillPolygon(e,i)));else{const t=this.computePolygonSize(e),n=[[0,0],[t[0],0],[t[0],t[1]],[0,t[1]]],a=await this.lib.patternFillPolygon(n,i);a.type='path2Dpattern',a.size=t,a.path=this.polygonPath(e),s.push(a)}return s.push((await this.lib.linearPath(e,!0,i))),this._drawable('polygon',s,i)}async path(e,t){const i=this._options(t),s=[];if(!e)return this._drawable('path',s,i);if(i.fill)if('solid'===i.fillStyle){s.push({type:'path2Dfill',path:e,ops:[]})}else{const t=this.computePathSize(e),n=[[0,0],[t[0],0],[t[0],t[1]],[0,t[1]]],a=await this.lib.patternFillPolygon(n,i);a.type='path2Dpattern',a.size=t,a.path=e,s.push(a)}return s.push((await this.lib.svgPath(e,i))),this._drawable('path',s,i)}}class U extends q{constructor(e,t){super(e,t),this.genAsync=new F(t||null,this.canvas)}get generator(){return this.genAsync}async line(e,t,i,s,n){const a=await this.genAsync.line(e,t,i,s,n);return this.draw(a),a}async rectangle(e,t,i,s,n){const a=await this.genAsync.rectangle(e,t,i,s,n);return this.draw(a),a}async ellipse(e,t,i,s,n){const a=await this.genAsync.ellipse(e,t,i,s,n);return this.draw(a),a}async circle(e,t,i,s){const n=await this.genAsync.circle(e,t,i,s);return this.draw(n),n}async linearPath(e,t){const i=await this.genAsync.linearPath(e,t);return this.draw(i),i}async polygon(e,t){const i=await this.genAsync.polygon(e,t);return this.draw(i),i}async arc(e,t,i,s,n,a,l=!1,o){const r=await this.genAsync.arc(e,t,i,s,n,a,l,o);return this.draw(r),r}async curve(e,t){const i=await this.genAsync.curve(e,t);return this.draw(i),i}async path(e,t){const i=await this.genAsync.path(e,t);return this.draw(i),i}}const X='undefined'!=typeof document;class G{constructor(e,t){this.svg=e,this.gen=new B(t||null,this.svg)}get generator(){return this.gen}static createRenderer(){return new E}get defs(){const e=this.svg.ownerDocument||X&&document;if(e&&!this._defs){const t=e.createElementNS('http://www.w3.org/2000/svg','defs');this.svg.firstChild?this.svg.insertBefore(t,this.svg.firstChild):this.svg.appendChild(t),this._defs=t}return this._defs||null}line(e,t,i,s,n){const a=this.gen.line(e,t,i,s,n);return this.draw(a)}rectangle(e,t,i,s,n){const a=this.gen.rectangle(e,t,i,s,n);return this.draw(a)}ellipse(e,t,i,s,n){const a=this.gen.ellipse(e,t,i,s,n);return this.draw(a)}circle(e,t,i,s){const n=this.gen.circle(e,t,i,s);return this.draw(n)}linearPath(e,t){const i=this.gen.linearPath(e,t);return this.draw(i)}polygon(e,t){const i=this.gen.polygon(e,t);return this.draw(i)}arc(e,t,i,s,n,a,l=!1,o){const r=this.gen.arc(e,t,i,s,n,a,l,o);return this.draw(r)}curve(e,t){const i=this.gen.curve(e,t);return this.draw(i)}path(e,t){const i=this.gen.path(e,t);return this.draw(i)}draw(e){const t=e.sets||[],i=e.options||this.gen.defaultOptions,s=this.svg.ownerDocument||X&&document,n=s.createElementNS('http://www.w3.org/2000/svg','g');for(const a of t){let e=null;switch(a.type){case'path':{e=s.createElementNS('http://www.w3.org/2000/svg','path'),e.setAttribute('d',this.opsToPath(a)),e.style.stroke=i.stroke,e.style.strokeWidth=i.strokeWidth+'',e.style.fill='none';break}case'fillPath':{e=s.createElementNS('http://www.w3.org/2000/svg','path'),e.setAttribute('d',this.opsToPath(a)),e.style.stroke='none',e.style.strokeWidth='0',e.style.fill=i.fill||null;break}case'fillSketch':{e=this.fillSketch(s,a,i);break}case'path2Dfill':{e=s.createElementNS('http://www.w3.org/2000/svg','path'),e.setAttribute('d',a.path||''),e.style.stroke='none',e.style.strokeWidth='0',e.style.fill=i.fill||null;break}case'path2Dpattern':{if(!this.defs)console.error('Cannot render path2Dpattern. No defs/document defined.');else{const t=a.size,n=s.createElementNS('http://www.w3.org/2000/svg','pattern'),l=`rough-${c(Math.random()*(Number.MAX_SAFE_INTEGER||999999))}`;n.setAttribute('id',l),n.setAttribute('x','0'),n.setAttribute('y','0'),n.setAttribute('width','1'),n.setAttribute('height','1'),n.setAttribute('height','1'),n.setAttribute('viewBox',`0 0 ${r(t[0])} ${r(t[1])}`),n.setAttribute('patternUnits','objectBoundingBox');const o=this.fillSketch(s,a,i);n.appendChild(o),this.defs.appendChild(n),e=s.createElementNS('http://www.w3.org/2000/svg','path'),e.setAttribute('d',a.path||''),e.style.stroke='none',e.style.strokeWidth='0',e.style.fill=`url(#${l})`}break}}e&&n.appendChild(e)}return n}opsToPath(e){return this.gen.opsToPath(e)}fillSketch(e,t,i){let s=i.fillWeight;0>s&&(s=i.strokeWidth/2);const n=e.createElementNS('http://www.w3.org/2000/svg','path');return n.setAttribute('d',this.opsToPath(t)),n.style.stroke=i.fill||null,n.style.strokeWidth=s+'',n.style.fill='none',n}}class V extends G{constructor(e,t){super(e,t),this.genAsync=new F(t||null,this.svg)}get generator(){return this.genAsync}async line(e,t,i,s,n){const a=await this.genAsync.line(e,t,i,s,n);return this.draw(a)}async rectangle(e,t,i,s,n){const a=await this.genAsync.rectangle(e,t,i,s,n);return this.draw(a)}async ellipse(e,t,i,s,n){const a=await this.genAsync.ellipse(e,t,i,s,n);return this.draw(a)}async circle(e,t,i,s){const n=await this.genAsync.circle(e,t,i,s);return this.draw(n)}async linearPath(e,t){const i=await this.genAsync.linearPath(e,t);return this.draw(i)}async polygon(e,t){const i=await this.genAsync.polygon(e,t);return this.draw(i)}async arc(e,t,i,s,n,a,l=!1,o){const r=await this.genAsync.arc(e,t,i,s,n,a,l,o);return this.draw(r)}async curve(e,t){const i=await this.genAsync.curve(e,t);return this.draw(i)}async path(e,t){const i=await this.genAsync.path(e,t);return this.draw(i)}}var j={canvas(e,t){return t&&t.async?new U(e,t):new q(e,t)},svg(e,t){return t&&t.async?new V(e,t):new G(e,t)},createRenderer(){return q.createRenderer()},generator(e,t){return e&&e.async?new F(e,t):new B(e,t)}};return j}); +(function(e,t){'object'==typeof exports&&'undefined'!=typeof module?module.exports=t():'function'==typeof define&&define.amd?define(t):e.rough=t()})(this,function(){'use strict';function e(e,t){return e.type===t}function t(e){const t=e[0],i=e[1];return y(g(t[0]-i[0],2)+g(t[1]-i[1],2))}function i(e,t){const n=[],s=new A([e[0],e[1]],[e[2],e[3]]);for(let a=0;ah&&(h=4*t.strokeWidth),h=d(h,.1);const g=r%180*(b/180),c=_(g),u=m(g),y=p(g),x=new S(l-1,o+1,s-1,a+1,h,u,c,y);for(let t;null!=(t=x.nextLine());){const s=i(t,e);for(let e=0;e=h&&(h=4*a.strokeWidth);let g=a.fillWeight;0>g&&(g=a.strokeWidth/2);const c=p(f%180*(b/180)),u=d/r,_=y(u*c*u*c+1),x=u*c/_,m=1/_,O=h/(r*d/y(d*m*(d*m)+r*x*(r*x))/r);let P=y(r*r-(e-r+O)*(e-r+O));for(let p=e-r+O;pd){const e=y(1-d/(this._rx*this._rx*this._ry*this._ry));this._rx*=e,this._ry*=e,p=0}else p=(s===a?-1:1)*y(d/(this._rx*this._rx*r*r+this._ry*this._ry*o*o));const f=p*this._rx*r/this._ry,h=-p*this._ry*o/this._rx;this._C=[0,0],this._C[0]=this._cosPhi*f-this._sinPhi*h+(e[0]+t[0])/2,this._C[1]=this._sinPhi*f+this._cosPhi*h+(e[1]+t[1])/2,this._theta=this.calculateVectorAngle(1,0,(o-f)/this._rx,(r-h)/this._ry);let g=this.calculateVectorAngle((o-f)/this._rx,(r-h)/this._ry,(-o-f)/this._rx,(-r-h)/this._ry);!a&&0g&&(g+=2*b),this._numSegs=u(w(g/(b/2))),this._delta=g/this._numSegs,this._T=8/3*m(this._delta/4)*m(this._delta/4)/m(this._delta/2)}getNextSegment(){if(this._segIndex===this._numSegs)return null;const e=_(this._theta),t=m(this._theta),i=this._theta+this._delta,n=_(i),s=m(i),a=[this._cosPhi*this._rx*n-this._sinPhi*this._ry*s+this._C[0],this._sinPhi*this._rx*n+this._cosPhi*this._ry*s+this._C[1]],l=[this._from[0]+this._T*(-this._cosPhi*this._rx*t-this._sinPhi*this._ry*e),this._from[1]+this._T*(-this._sinPhi*this._rx*t+this._cosPhi*this._ry*e)],o=[a[0]+this._T*(this._cosPhi*this._rx*s+this._sinPhi*this._ry*n),a[1]+this._T*(this._sinPhi*this._rx*s-this._cosPhi*this._ry*n)];return this._theta=i,this._from=[a[0],a[1]],this._segIndex++,{cp1:l,cp2:o,to:a}}calculateVectorAngle(e,t,i,n){var s=Math.atan2;const a=s(t,e),l=s(n,i);return l>=a?l-a:2*b-(a-l)}}class k{constructor(e,t){this.sets=e,this.closed=t}fit(e){const t=[];for(const i of this.sets){const n=i.length;let s=c(e*n);if(5>s){if(5>=n)continue;s=5}t.push(this.reduce(i,s))}let n='';for(const s of t){for(let e=0;et;){let e=-1,t=-1;for(let l=1;le||s=f(e.py1,e.py2)&&this.py1<=d(e.py1,e.py2)?(this.xi=this.px1,this.yi=this.py1,!0):!!(this.py2>=f(e.py1,e.py2)&&this.py2<=d(e.py1,e.py2))&&(this.xi=this.px2,this.yi=this.py2,!0)):(this.xi=this.px1,this.yi=i*this.xi+s,!(-1e-5>(this.py1-this.yi)*(this.yi-this.py2)||-1e-5>(e.py1-this.yi)*(this.yi-e.py2))&&(!(1e-5>w(e.a))||!(-1e-5>(e.px1-this.xi)*(this.xi-e.px2)))):i===h?(this.xi=e.px1,this.yi=t*this.xi+n,!(-1e-5>(e.py1-this.yi)*(this.yi-e.py2)||-1e-5>(this.py1-this.yi)*(this.yi-this.py2))&&(!(1e-5>w(l))||!(-1e-5>(this.px1-this.xi)*(this.xi-this.px2)))):t===i?n==s&&(this.px1>=f(e.px1,e.px2)&&this.px1<=d(e.py1,e.py2)?(this.xi=this.px1,this.yi=this.py1,!0):!!(this.px2>=f(e.px1,e.px2)&&this.px2<=d(e.px1,e.px2))&&(this.xi=this.px2,this.yi=this.py2,!0)):(this.xi=(s-n)/(t-i),this.yi=t*this.xi+n,!(-1e-5>(this.px1-this.xi)*(this.xi-this.px2)||-1e-5>(e.px1-this.xi)*(this.xi-e.px2)))}}class S{constructor(e,t,i,n,s,a,l,o){this.deltaX=0,this.hGap=0,this.top=e,this.bottom=t,this.left=i,this.right=n,this.gap=s,this.sinAngle=a,this.tanAngle=o,1e-4>w(a)?this.pos=i+s:.9999w(this.sinAngle)){if(this.posthis.right&&t>this.right;)if(this.pos+=this.hGap,e=this.pos-this.deltaX/2,t=this.pos+this.deltaX/2,this.pos>this.right+this.deltaX)return null;const a=new A([e,i],[t,n]);this.sLeft&&a.intersects(this.sLeft)&&(e=a.xi,i=a.yi),this.sRight&&a.intersects(this.sRight)&&(t=a.xi,n=a.yi),0a&&(a=4*n.strokeWidth),a=d(a,.1);let o=n.fillWeight;0>o&&(o=n.strokeWidth/2);for(const r of e){const e=t(r),i=e/a,l=u(i)-1,p=Math.atan((r[1][1]-r[0][1])/(r[1][0]-r[0][0]));for(let e=0;ec;)c+=2*b,u+=2*b;u-c>2*b&&(c=0,u=2*b);const y=2*b/p.curveStepCount,x=f(y/2,(u-c)/2),O=this._arc(x,o,d,h,g,c,u,1,p),P=this._arc(x,o,d,h,g,c,u,1.5,p);let v=O.concat(P);return l&&(r?(v=v.concat(this.doubleLine(o,d,o+h*_(c),d+g*m(c),p)),v=v.concat(this.doubleLine(o,d,o+h*_(u),d+g*m(u),p))):(v.push({op:'lineTo',data:[o,d]}),v.push({op:'lineTo',data:[o+h*_(c),d+g*m(c)]}))),{type:'path',ops:v}}svgPath(e,t){e=(e||'').replace(/\n/g,' ').replace(/(-\s)/g,'-').replace('/(ss)/g',' ');let n=new P(e);if(t.simplification){const e=new k(n.linearPoints,n.closed),i=e.fit(t.simplification);n=new P(i)}let a=[];const l=n.segments||[];for(let o=0;of;)f+=2*b,h+=2*b;h-f>2*b&&(f=0,h=2*b);const g=(h-f)/l.curveStepCount,c=[];for(let u=f;u<=h;u+=g)c.push([o+p*_(u),r+d*m(u)]);return c.push([o+p*_(h),r+d*m(h)]),c.push([o,r]),this.patternFillPolygon(c,l)}getOffset(e,t,i){return i.roughness*(Math.random()*(t-e)+e)}doubleLine(e,t,i,n,s){const a=this._line(e,t,i,n,s,!0,!1),l=this._line(e,t,i,n,s,!0,!0);return a.concat(l)}_line(e,t,i,n,s,a,l){const o=g(e-i,2)+g(t-n,2);let r=s.maxRandomnessOffset||0;100*(r*r)>o&&(r=y(o)/10);const p=r/2,d=.2+.2*Math.random();let f=s.bowing*s.maxRandomnessOffset*(n-t)/200,h=s.bowing*s.maxRandomnessOffset*(e-i)/200;f=this.getOffset(-f,f,s),h=this.getOffset(-h,h,s);const c=[];return a&&(l?c.push({op:'move',data:[e+this.getOffset(-p,p,s),t+this.getOffset(-p,p,s)]}):c.push({op:'move',data:[e+this.getOffset(-r,r,s),t+this.getOffset(-r,r,s)]})),l?c.push({op:'bcurveTo',data:[f+e+(i-e)*d+this.getOffset(-p,p,s),h+t+(n-t)*d+this.getOffset(-p,p,s),f+e+2*(i-e)*d+this.getOffset(-p,p,s),h+t+2*(n-t)*d+this.getOffset(-p,p,s),i+this.getOffset(-p,p,s),n+this.getOffset(-p,p,s)]}):c.push({op:'bcurveTo',data:[f+e+(i-e)*d+this.getOffset(-r,r,s),h+t+(n-t)*d+this.getOffset(-r,r,s),f+e+2*(i-e)*d+this.getOffset(-r,r,s),h+t+2*(n-t)*d+this.getOffset(-r,r,s),i+this.getOffset(-r,r,s),n+this.getOffset(-r,r,s)]}),c}_curve(e,t,i){const n=e.length;let a=[];if(3f;f++)0===f?o.push({op:'move',data:[r.x,r.y]}):o.push({op:'move',data:[r.x+this.getOffset(-d[0],d[0],p),r.y+this.getOffset(-d[0],d[0],p)]}),h=[a+this.getOffset(-d[f],d[f],p),l+this.getOffset(-d[f],d[f],p)],o.push({op:'bcurveTo',data:[e+this.getOffset(-d[f],d[f],p),t+this.getOffset(-d[f],d[f],p),n+this.getOffset(-d[f],d[f],p),s+this.getOffset(-d[f],d[f],p),h[0],h[1]]});return r.setPosition(h[0],h[1]),o}_processSegment(e,t,i,n){let s=[];switch(t.key){case'M':case'm':{const i='m'===t.key;if(2<=t.data.length){let a=+t.data[0],l=+t.data[1];i&&(a+=e.x,l+=e.y);const o=1*(n.maxRandomnessOffset||0);a+=this.getOffset(-o,o,n),l+=this.getOffset(-o,o,n),e.setPosition(a,l),s.push({op:'move',data:[a,l]})}break}case'L':case'l':{const i='l'===t.key;if(2<=t.data.length){let a=+t.data[0],l=+t.data[1];i&&(a+=e.x,l+=e.y),s=s.concat(this.doubleLine(e.x,e.y,a,l,n)),e.setPosition(a,l)}break}case'H':case'h':{const i='h'===t.key;if(t.data.length){let a=+t.data[0];i&&(a+=e.x),s=s.concat(this.doubleLine(e.x,e.y,a,e.y,n)),e.setPosition(a,e.y)}break}case'V':case'v':{const i='v'===t.key;if(t.data.length){let a=+t.data[0];i&&(a+=e.y),s=s.concat(this.doubleLine(e.x,e.y,e.x,a,n)),e.setPosition(e.x,a)}break}case'Z':case'z':{e.first&&(s=s.concat(this.doubleLine(e.x,e.y,e.first[0],e.first[1],n)),e.setPosition(e.first[0],e.first[1]),e.first=null);break}case'C':case'c':{const i='c'===t.key;if(6<=t.data.length){let a=+t.data[0],l=+t.data[1],o=+t.data[2],r=+t.data[3],p=+t.data[4],d=+t.data[5];i&&(a+=e.x,o+=e.x,p+=e.x,l+=e.y,r+=e.y,d+=e.y);const f=this._bezierTo(a,l,o,r,p,d,e,n);s=s.concat(f),e.bezierReflectionPoint=[p+(p-o),d+(d-r)]}break}case'S':case's':{const a='s'===t.key;if(4<=t.data.length){let l=+t.data[0],o=+t.data[1],r=+t.data[2],p=+t.data[3];a&&(l+=e.x,r+=e.x,o+=e.y,p+=e.y);let d=l,f=o;const h=i?i.key:'';let g=null;('c'===h||'C'===h||'s'===h||'S'===h)&&(g=e.bezierReflectionPoint),g&&(d=g[0],f=g[1]);const c=this._bezierTo(d,f,l,o,r,p,e,n);s=s.concat(c),e.bezierReflectionPoint=[r+(r-l),p+(p-o)]}break}case'Q':case'q':{const i='q'===t.key;if(4<=t.data.length){let a=+t.data[0],l=+t.data[1],o=+t.data[2],r=+t.data[3];i&&(a+=e.x,o+=e.x,l+=e.y,r+=e.y);const p=1*(1+.2*n.roughness),d=1.5*(1+.22*n.roughness);s.push({op:'move',data:[e.x+this.getOffset(-p,p,n),e.y+this.getOffset(-p,p,n)]});let h=[o+this.getOffset(-p,p,n),r+this.getOffset(-p,p,n)];s.push({op:'qcurveTo',data:[a+this.getOffset(-p,p,n),l+this.getOffset(-p,p,n),h[0],h[1]]}),s.push({op:'move',data:[e.x+this.getOffset(-d,d,n),e.y+this.getOffset(-d,d,n)]}),h=[o+this.getOffset(-d,d,n),r+this.getOffset(-d,d,n)],s.push({op:'qcurveTo',data:[a+this.getOffset(-d,d,n),l+this.getOffset(-d,d,n),h[0],h[1]]}),e.setPosition(h[0],h[1]),e.quadReflectionPoint=[o+(o-a),r+(r-l)]}break}case'T':case't':{const a='t'===t.key;if(2<=t.data.length){let l=+t.data[0],o=+t.data[1];a&&(l+=e.x,o+=e.y);let r=l,p=o;const d=i?i.key:'';let h=null;('q'===d||'Q'===d||'t'===d||'T'===d)&&(h=e.quadReflectionPoint),h&&(r=h[0],p=h[1]);const g=1*(1+.2*n.roughness),c=1.5*(1+.22*n.roughness);s.push({op:'move',data:[e.x+this.getOffset(-g,g,n),e.y+this.getOffset(-g,g,n)]});let u=[l+this.getOffset(-g,g,n),o+this.getOffset(-g,g,n)];s.push({op:'qcurveTo',data:[r+this.getOffset(-g,g,n),p+this.getOffset(-g,g,n),u[0],u[1]]}),s.push({op:'move',data:[e.x+this.getOffset(-c,c,n),e.y+this.getOffset(-c,c,n)]}),u=[l+this.getOffset(-c,c,n),o+this.getOffset(-c,c,n)],s.push({op:'qcurveTo',data:[r+this.getOffset(-c,c,n),p+this.getOffset(-c,c,n),u[0],u[1]]}),e.setPosition(u[0],u[1]),e.quadReflectionPoint=[l+(l-r),o+(o-p)]}break}case'A':case'a':{const i='a'===t.key;if(7<=t.data.length){const a=+t.data[0],l=+t.data[1],o=+t.data[2],r=+t.data[3],p=+t.data[4];let d=+t.data[5],f=+t.data[6];if(i&&(d+=e.x,f+=e.y),d===e.x&&f===e.y)break;if(0==a||0==l)s=s.concat(this.doubleLine(e.x,e.y,d,f,n)),e.setPosition(d,f);else for(let t=0;1>t;t++){const t=new v([e.x,e.y],[d,f],[a,l],o,!!r,!!p);for(let i=t.getNextSegment();i;){const a=this._bezierTo(i.cp1[0],i.cp1[1],i.cp2[0],i.cp2[1],i.to[0],i.to[1],e,n);s=s.concat(a),i=t.getNextSegment()}}}break}default:}return s}}const L='undefined'!=typeof self,D=L&&self&&self.document&&self.document.currentScript&&self.document.currentScript.src,R='undefined'!=typeof self;class B{constructor(e,t){this.defaultOptions={maxRandomnessOffset:2,roughness:1,bowing:1,stroke:'#000',strokeWidth:1,curveTightness:0,curveStepCount:9,fillStyle:'hachure',fillWeight:-1,hachureAngle:-41,hachureGap:-1},this.config=e||{},this.surface=t,this.renderer=o(this.config),this.config.options&&(this.defaultOptions=this._options(this.config.options))}_options(e){return e?Object.assign({},this.defaultOptions,e):this.defaultOptions}_drawable(e,t,i){return{shape:e,sets:t||[],options:i||this.defaultOptions}}get lib(){return this.renderer}getCanvasSize(){const e=e=>e&&'object'==typeof e&&e.baseVal&&e.baseVal.value?e.baseVal.value:e||100;return this.surface?[e(this.surface.width),e(this.surface.height)]:[100,100]}computePolygonSize(e){if(e.length){let t=e[0][0],n=e[0][0],s=e[0][1],a=e[0][1];for(let l=1;li&&(i=t.strokeWidth/2),{d:this.opsToPath(e),stroke:t.fill||'none',strokeWidth:i,fill:'none'}}opsToPath(e){let t='';for(const i of e.ops){const e=i.data;switch(i.op){case'move':t+=`M${e[0]} ${e[1]} `;break;case'bcurveTo':t+=`C${e[0]} ${e[1]}, ${e[2]} ${e[3]}, ${e[4]} ${e[5]} `;break;case'qcurveTo':t+=`Q${e[0]} ${e[1]}, ${e[2]} ${e[3]} `;break;case'lineTo':t+=`L${e[0]} ${e[1]} `;}}return t.trim()}}class M extends B{constructor(e,t){super(e,t)}line(e,t,i,n,s){const a=this._options(s);return this._drawable('line',[this.lib.line(e,t,i,n,a)],a)}rectangle(e,t,i,n,s){const a=this._options(s),l=[];if(a.fill){const s=[[e,t],[e+i,t],[e+i,t+n],[e,t+n]];'solid'===a.fillStyle?l.push(this.lib.solidFillPolygon(s,a)):l.push(this.lib.patternFillPolygon(s,a))}return l.push(this.lib.rectangle(e,t,i,n,a)),this._drawable('rectangle',l,a)}ellipse(e,t,i,n,s){const a=this._options(s),l=[];if(a.fill)if('solid'===a.fillStyle){const s=this.lib.ellipse(e,t,i,n,a);s.type='fillPath',l.push(s)}else l.push(this.lib.patternFillEllipse(e,t,i,n,a));return l.push(this.lib.ellipse(e,t,i,n,a)),this._drawable('ellipse',l,a)}circle(e,t,i,n){const s=this.ellipse(e,t,i,i,n);return s.shape='circle',s}linearPath(e,t){const i=this._options(t);return this._drawable('linearPath',[this.lib.linearPath(e,!1,i)],i)}arc(e,t,i,n,s,a,l=!1,r){const p=this._options(r),o=[];if(l&&p.fill)if('solid'===p.fillStyle){const l=this.lib.arc(e,t,i,n,s,a,!0,!1,p);l.type='fillPath',o.push(l)}else o.push(this.lib.patternFillArc(e,t,i,n,s,a,p));return o.push(this.lib.arc(e,t,i,n,s,a,l,!0,p)),this._drawable('arc',o,p)}curve(e,t){const i=this._options(t);return this._drawable('curve',[this.lib.curve(e,i)],i)}polygon(e,t){const i=this._options(t),n=[];if(i.fill)if('solid'===i.fillStyle)n.push(this.lib.solidFillPolygon(e,i));else{const t=this.computePolygonSize(e),s=[[0,0],[t[0],0],[t[0],t[1]],[0,t[1]]],a=this.lib.patternFillPolygon(s,i);a.type='path2Dpattern',a.size=t,a.path=this.polygonPath(e),n.push(a)}return n.push(this.lib.linearPath(e,!0,i)),this._drawable('polygon',n,i)}path(e,t){const i=this._options(t),n=[];if(!e)return this._drawable('path',n,i);if(i.fill)if('solid'===i.fillStyle){n.push({type:'path2Dfill',path:e,ops:[]})}else{const t=this.computePathSize(e),s=[[0,0],[t[0],0],[t[0],t[1]],[0,t[1]]],a=this.lib.patternFillPolygon(s,i);a.type='path2Dpattern',a.size=t,a.path=e,n.push(a)}return n.push(this.lib.svgPath(e,i)),this._drawable('path',n,i)}}const q='undefined'!=typeof document;class F{constructor(e){this.canvas=e,this.ctx=this.canvas.getContext('2d')}static createRenderer(){return new E}draw(e){const t=e.sets||[],i=e.options||this.getDefaultOptions(),n=this.ctx;for(const s of t)switch(s.type){case'path':n.save(),n.strokeStyle=i.stroke,n.lineWidth=i.strokeWidth,this._drawToContext(n,s),n.restore();break;case'fillPath':n.save(),n.fillStyle=i.fill||'',this._drawToContext(n,s),n.restore();break;case'fillSketch':this.fillSketch(n,s,i);break;case'path2Dfill':{this.ctx.save(),this.ctx.fillStyle=i.fill||'';const e=new Path2D(s.path);this.ctx.fill(e),this.ctx.restore();break}case'path2Dpattern':{const e=this.canvas.ownerDocument||q&&document;if(e){const t=s.size,n=e.createElement('canvas'),a=n.getContext('2d'),l=this.computeBBox(s.path);l&&(l.width||l.height)?(n.width=this.canvas.width,n.height=this.canvas.height,a.translate(l.x||0,l.y||0)):(n.width=t[0],n.height=t[1]),this.fillSketch(a,s,i),this.ctx.save(),this.ctx.fillStyle=this.ctx.createPattern(n,'repeat');const o=new Path2D(s.path);this.ctx.fill(o),this.ctx.restore()}else console.error('Cannot render path2Dpattern. No defs/document defined.');break}}}computeBBox(e){if(q)try{const t=document.createElementNS('http://www.w3.org/2000/svg','svg');t.setAttribute('width','0'),t.setAttribute('height','0');const i=self.document.createElementNS('http://www.w3.org/2000/svg','path');i.setAttribute('d',e),t.appendChild(i),document.body.appendChild(t);const n=i.getBBox();return document.body.removeChild(t),n}catch(e){}return null}fillSketch(e,t,i){let n=i.fillWeight;0>n&&(n=i.strokeWidth/2),e.save(),e.strokeStyle=i.fill||'',e.lineWidth=n,this._drawToContext(e,t),e.restore()}_drawToContext(e,t){e.beginPath();for(const i of t.ops){const t=i.data;switch(i.op){case'move':e.moveTo(t[0],t[1]);break;case'bcurveTo':e.bezierCurveTo(t[0],t[1],t[2],t[3],t[4],t[5]);break;case'qcurveTo':e.quadraticCurveTo(t[0],t[1],t[2],t[3]);break;case'lineTo':e.lineTo(t[0],t[1]);}}'fillPath'===t.type?e.fill():e.stroke()}}class U extends F{constructor(e,t){super(e),this.gen=new M(t||null,this.canvas)}get generator(){return this.gen}getDefaultOptions(){return this.gen.defaultOptions}line(e,t,i,n,s){const a=this.gen.line(e,t,i,n,s);return this.draw(a),a}rectangle(e,t,i,n,s){const a=this.gen.rectangle(e,t,i,n,s);return this.draw(a),a}ellipse(e,t,i,n,s){const a=this.gen.ellipse(e,t,i,n,s);return this.draw(a),a}circle(e,t,i,n){const s=this.gen.circle(e,t,i,n);return this.draw(s),s}linearPath(e,t){const i=this.gen.linearPath(e,t);return this.draw(i),i}polygon(e,t){const i=this.gen.polygon(e,t);return this.draw(i),i}arc(e,t,i,n,s,a,l=!1,o){const r=this.gen.arc(e,t,i,n,s,a,l,o);return this.draw(r),r}curve(e,t){const i=this.gen.curve(e,t);return this.draw(i),i}path(e,t){const i=this.gen.path(e,t);return this.draw(i),i}}class X extends B{async line(e,t,i,n,s){const a=this._options(s);return this._drawable('line',[await this.lib.line(e,t,i,n,a)],a)}async rectangle(e,t,i,n,s){const a=this._options(s),l=[];if(a.fill){const s=[[e,t],[e+i,t],[e+i,t+n],[e,t+n]];'solid'===a.fillStyle?l.push((await this.lib.solidFillPolygon(s,a))):l.push((await this.lib.patternFillPolygon(s,a)))}return l.push((await this.lib.rectangle(e,t,i,n,a))),this._drawable('rectangle',l,a)}async ellipse(e,t,i,n,s){const a=this._options(s),l=[];if(a.fill)if('solid'===a.fillStyle){const s=await this.lib.ellipse(e,t,i,n,a);s.type='fillPath',l.push(s)}else l.push((await this.lib.patternFillEllipse(e,t,i,n,a)));return l.push((await this.lib.ellipse(e,t,i,n,a))),this._drawable('ellipse',l,a)}async circle(e,t,i,n){const s=await this.ellipse(e,t,i,i,n);return s.shape='circle',s}async linearPath(e,t){const i=this._options(t);return this._drawable('linearPath',[await this.lib.linearPath(e,!1,i)],i)}async arc(e,t,i,n,s,a,l=!1,r){const p=this._options(r),o=[];if(l&&p.fill)if('solid'===p.fillStyle){const l=await this.lib.arc(e,t,i,n,s,a,!0,!1,p);l.type='fillPath',o.push(l)}else o.push((await this.lib.patternFillArc(e,t,i,n,s,a,p)));return o.push((await this.lib.arc(e,t,i,n,s,a,l,!0,p))),this._drawable('arc',o,p)}async curve(e,t){const i=this._options(t);return this._drawable('curve',[await this.lib.curve(e,i)],i)}async polygon(e,t){const i=this._options(t),n=[];if(i.fill)if('solid'===i.fillStyle)n.push((await this.lib.solidFillPolygon(e,i)));else{const t=this.computePolygonSize(e),s=[[0,0],[t[0],0],[t[0],t[1]],[0,t[1]]],a=await this.lib.patternFillPolygon(s,i);a.type='path2Dpattern',a.size=t,a.path=this.polygonPath(e),n.push(a)}return n.push((await this.lib.linearPath(e,!0,i))),this._drawable('polygon',n,i)}async path(e,t){const i=this._options(t),n=[];if(!e)return this._drawable('path',n,i);if(i.fill)if('solid'===i.fillStyle){n.push({type:'path2Dfill',path:e,ops:[]})}else{const t=this.computePathSize(e),s=[[0,0],[t[0],0],[t[0],t[1]],[0,t[1]]],a=await this.lib.patternFillPolygon(s,i);a.type='path2Dpattern',a.size=t,a.path=e,n.push(a)}return n.push((await this.lib.svgPath(e,i))),this._drawable('path',n,i)}}class G extends F{constructor(e,t){super(e),this.genAsync=new X(t||null,this.canvas)}get generator(){return this.genAsync}getDefaultOptions(){return this.genAsync.defaultOptions}async line(e,t,i,n,s){const a=await this.genAsync.line(e,t,i,n,s);return this.draw(a),a}async rectangle(e,t,i,n,s){const a=await this.genAsync.rectangle(e,t,i,n,s);return this.draw(a),a}async ellipse(e,t,i,n,s){const a=await this.genAsync.ellipse(e,t,i,n,s);return this.draw(a),a}async circle(e,t,i,n){const s=await this.genAsync.circle(e,t,i,n);return this.draw(s),s}async linearPath(e,t){const i=await this.genAsync.linearPath(e,t);return this.draw(i),i}async polygon(e,t){const i=await this.genAsync.polygon(e,t);return this.draw(i),i}async arc(e,t,i,n,s,a,l=!1,o){const r=await this.genAsync.arc(e,t,i,n,s,a,l,o);return this.draw(r),r}async curve(e,t){const i=await this.genAsync.curve(e,t);return this.draw(i),i}async path(e,t){const i=await this.genAsync.path(e,t);return this.draw(i),i}}const V='undefined'!=typeof document;class j{constructor(e){this.svg=e}static createRenderer(){return new E}get defs(){const e=this.svg.ownerDocument||V&&document;if(e&&!this._defs){const t=e.createElementNS('http://www.w3.org/2000/svg','defs');this.svg.firstChild?this.svg.insertBefore(t,this.svg.firstChild):this.svg.appendChild(t),this._defs=t}return this._defs||null}draw(e){const t=e.sets||[],i=e.options||this.getDefaultOptions(),n=this.svg.ownerDocument||V&&document,s=n.createElementNS('http://www.w3.org/2000/svg','g');for(const a of t){let e=null;switch(a.type){case'path':{e=n.createElementNS('http://www.w3.org/2000/svg','path'),e.setAttribute('d',this.opsToPath(a)),e.style.stroke=i.stroke,e.style.strokeWidth=i.strokeWidth+'',e.style.fill='none';break}case'fillPath':{e=n.createElementNS('http://www.w3.org/2000/svg','path'),e.setAttribute('d',this.opsToPath(a)),e.style.stroke='none',e.style.strokeWidth='0',e.style.fill=i.fill||null;break}case'fillSketch':{e=this.fillSketch(n,a,i);break}case'path2Dfill':{e=n.createElementNS('http://www.w3.org/2000/svg','path'),e.setAttribute('d',a.path||''),e.style.stroke='none',e.style.strokeWidth='0',e.style.fill=i.fill||null;break}case'path2Dpattern':{if(!this.defs)console.error('Cannot render path2Dpattern. No defs/document defined.');else{const t=a.size,s=n.createElementNS('http://www.w3.org/2000/svg','pattern'),l=`rough-${c(Math.random()*(Number.MAX_SAFE_INTEGER||999999))}`;s.setAttribute('id',l),s.setAttribute('x','0'),s.setAttribute('y','0'),s.setAttribute('width','1'),s.setAttribute('height','1'),s.setAttribute('height','1'),s.setAttribute('viewBox',`0 0 ${r(t[0])} ${r(t[1])}`),s.setAttribute('patternUnits','objectBoundingBox');const o=this.fillSketch(n,a,i);s.appendChild(o),this.defs.appendChild(s),e=n.createElementNS('http://www.w3.org/2000/svg','path'),e.setAttribute('d',a.path||''),e.style.stroke='none',e.style.strokeWidth='0',e.style.fill=`url(#${l})`}break}}e&&s.appendChild(e)}return s}fillSketch(e,t,i){let n=i.fillWeight;0>n&&(n=i.strokeWidth/2);const s=e.createElementNS('http://www.w3.org/2000/svg','path');return s.setAttribute('d',this.opsToPath(t)),s.style.stroke=i.fill||null,s.style.strokeWidth=n+'',s.style.fill='none',s}}class I extends j{constructor(e,t){super(e),this.gen=new M(t||null,this.svg)}get generator(){return this.gen}getDefaultOptions(){return this.gen.defaultOptions}opsToPath(e){return this.gen.opsToPath(e)}line(e,t,i,n,s){const a=this.gen.line(e,t,i,n,s);return this.draw(a)}rectangle(e,t,i,n,s){const a=this.gen.rectangle(e,t,i,n,s);return this.draw(a)}ellipse(e,t,i,n,s){const a=this.gen.ellipse(e,t,i,n,s);return this.draw(a)}circle(e,t,i,n){const s=this.gen.circle(e,t,i,n);return this.draw(s)}linearPath(e,t){const i=this.gen.linearPath(e,t);return this.draw(i)}polygon(e,t){const i=this.gen.polygon(e,t);return this.draw(i)}arc(e,t,i,n,s,a,l=!1,o){const r=this.gen.arc(e,t,i,n,s,a,l,o);return this.draw(r)}curve(e,t){const i=this.gen.curve(e,t);return this.draw(i)}path(e,t){const i=this.gen.path(e,t);return this.draw(i)}}class $ extends j{constructor(e,t){super(e),this.genAsync=new X(t||null,this.svg)}get generator(){return this.genAsync}getDefaultOptions(){return this.genAsync.defaultOptions}opsToPath(e){return this.genAsync.opsToPath(e)}async line(e,t,i,n,s){const a=await this.genAsync.line(e,t,i,n,s);return this.draw(a)}async rectangle(e,t,i,n,s){const a=await this.genAsync.rectangle(e,t,i,n,s);return this.draw(a)}async ellipse(e,t,i,n,s){const a=await this.genAsync.ellipse(e,t,i,n,s);return this.draw(a)}async circle(e,t,i,n){const s=await this.genAsync.circle(e,t,i,n);return this.draw(s)}async linearPath(e,t){const i=await this.genAsync.linearPath(e,t);return this.draw(i)}async polygon(e,t){const i=await this.genAsync.polygon(e,t);return this.draw(i)}async arc(e,t,i,n,s,a,l=!1,o){const r=await this.genAsync.arc(e,t,i,n,s,a,l,o);return this.draw(r)}async curve(e,t){const i=await this.genAsync.curve(e,t);return this.draw(i)}async path(e,t){const i=await this.genAsync.path(e,t);return this.draw(i)}}var Q={canvas(e,t){return t&&t.async?new G(e,t):new U(e,t)},svg(e,t){return t&&t.async?new $(e,t):new I(e,t)},createRenderer(){return U.createRenderer()},generator(e,t){return e&&e.async?new X(e,t):new M(e,t)}};return Q}); diff --git a/package.json b/package.json index 2f84854..8d086ad 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "roughjs", - "version": "2.2.4", + "version": "2.2.5", "description": "Create graphics using HTML Canvas or SVG with a hand-drawn, sketchy, appearance.", "main": "dist/rough.umd.js", "module": "bin/rough.js", diff --git a/src/canvas-async.ts b/src/canvas-async.ts index bc77097..18cc7a3 100644 --- a/src/canvas-async.ts +++ b/src/canvas-async.ts @@ -1,78 +1,72 @@ -import { RoughCanvas } from './canvas'; -import { Config, Options, Drawable } from './core'; +import { Config, Options, ResolvedOptions, Drawable } from './core'; import { RoughGeneratorAsync } from './generator-async'; import { Point } from './geometry'; +import { RoughCanvasBase } from './canvas-base'; -export class RoughCanvasAsync extends RoughCanvas { +export class RoughCanvasAsync extends RoughCanvasBase { private genAsync: RoughGeneratorAsync; constructor(canvas: HTMLCanvasElement, config?: Config) { - super(canvas, config); + super(canvas); this.genAsync = new RoughGeneratorAsync(config || null, this.canvas); } - // @ts-ignore get generator(): RoughGeneratorAsync { return this.genAsync; } - // @ts-ignore + getDefaultOptions(): ResolvedOptions { + return this.genAsync.defaultOptions; + } + async line(x1: number, y1: number, x2: number, y2: number, options?: Options): Promise { const d = await this.genAsync.line(x1, y1, x2, y2, options); this.draw(d); return d; } - // @ts-ignore async rectangle(x: number, y: number, width: number, height: number, options?: Options): Promise { const d = await this.genAsync.rectangle(x, y, width, height, options); this.draw(d); return d; } - // @ts-ignore async ellipse(x: number, y: number, width: number, height: number, options?: Options): Promise { const d = await this.genAsync.ellipse(x, y, width, height, options); this.draw(d); return d; } - // @ts-ignore async circle(x: number, y: number, diameter: number, options?: Options): Promise { const d = await this.genAsync.circle(x, y, diameter, options); this.draw(d); return d; } - // @ts-ignore async linearPath(points: Point[], options?: Options): Promise { const d = await this.genAsync.linearPath(points, options); this.draw(d); return d; } - // @ts-ignore async polygon(points: Point[], options?: Options): Promise { const d = await this.genAsync.polygon(points, options); this.draw(d); return d; } - // @ts-ignore async arc(x: number, y: number, width: number, height: number, start: number, stop: number, closed: boolean = false, options?: Options): Promise { const d = await this.genAsync.arc(x, y, width, height, start, stop, closed, options); this.draw(d); return d; } - // @ts-ignore async curve(points: Point[], options?: Options): Promise { const d = await this.genAsync.curve(points, options); this.draw(d); return d; } - // @ts-ignore async path(d: string, options?: Options): Promise { const drawing = await this.genAsync.path(d, options); this.draw(drawing); diff --git a/src/canvas-base.ts b/src/canvas-base.ts new file mode 100644 index 0000000..3496379 --- /dev/null +++ b/src/canvas-base.ts @@ -0,0 +1,137 @@ +import { ResolvedOptions, Drawable, OpSet } from './core'; +import { RoughRenderer } from './renderer'; + +const hasDocument = typeof document !== 'undefined'; + +export abstract class RoughCanvasBase { + protected canvas: HTMLCanvasElement; + protected ctx: CanvasRenderingContext2D; + + constructor(canvas: HTMLCanvasElement) { + this.canvas = canvas; + this.ctx = this.canvas.getContext('2d')!; + } + + static createRenderer(): RoughRenderer { + return new RoughRenderer(); + } + + abstract getDefaultOptions(): ResolvedOptions; + + draw(drawable: Drawable) { + const sets = drawable.sets || []; + const o = drawable.options || this.getDefaultOptions(); + const ctx = this.ctx; + for (const drawing of sets) { + switch (drawing.type) { + case 'path': + ctx.save(); + ctx.strokeStyle = o.stroke; + ctx.lineWidth = o.strokeWidth; + this._drawToContext(ctx, drawing); + ctx.restore(); + break; + case 'fillPath': + ctx.save(); + ctx.fillStyle = o.fill || ''; + this._drawToContext(ctx, drawing); + ctx.restore(); + break; + case 'fillSketch': + this.fillSketch(ctx, drawing, o); + break; + case 'path2Dfill': { + this.ctx.save(); + this.ctx.fillStyle = o.fill || ''; + const p2d = new Path2D(drawing.path); + this.ctx.fill(p2d); + this.ctx.restore(); + break; + } + case 'path2Dpattern': { + const doc = this.canvas.ownerDocument || (hasDocument && document); + if (doc) { + const size = drawing.size!; + const hcanvas = doc.createElement('canvas'); + const hcontext = hcanvas.getContext('2d')!; + const bbox = this.computeBBox(drawing.path!); + if (bbox && (bbox.width || bbox.height)) { + hcanvas.width = this.canvas.width; + hcanvas.height = this.canvas.height; + hcontext.translate(bbox.x || 0, bbox.y || 0); + } else { + hcanvas.width = size[0]; + hcanvas.height = size[1]; + } + this.fillSketch(hcontext, drawing, o); + this.ctx.save(); + this.ctx.fillStyle = this.ctx.createPattern(hcanvas, 'repeat'); + const p2d = new Path2D(drawing.path); + this.ctx.fill(p2d); + this.ctx.restore(); + } else { + console.error('Cannot render path2Dpattern. No defs/document defined.'); + } + break; + } + } + } + } + + private computeBBox(d: string): SVGRect | null { + if (hasDocument) { + try { + const ns = 'http://www.w3.org/2000/svg'; + const svg = document.createElementNS(ns, 'svg'); + svg.setAttribute('width', '0'); + svg.setAttribute('height', '0'); + const pathNode = self.document.createElementNS(ns, 'path'); + pathNode.setAttribute('d', d); + svg.appendChild(pathNode); + document.body.appendChild(svg); + const bbox = pathNode.getBBox(); + document.body.removeChild(svg); + return bbox; + } catch (err) { } + } + return null; + } + + private fillSketch(ctx: CanvasRenderingContext2D, drawing: OpSet, o: ResolvedOptions) { + let fweight = o.fillWeight; + if (fweight < 0) { + fweight = o.strokeWidth / 2; + } + ctx.save(); + ctx.strokeStyle = o.fill || ''; + ctx.lineWidth = fweight; + this._drawToContext(ctx, drawing); + ctx.restore(); + } + + private _drawToContext(ctx: CanvasRenderingContext2D, drawing: OpSet) { + ctx.beginPath(); + for (const item of drawing.ops) { + const data = item.data; + switch (item.op) { + case 'move': + ctx.moveTo(data[0], data[1]); + break; + case 'bcurveTo': + ctx.bezierCurveTo(data[0], data[1], data[2], data[3], data[4], data[5]); + break; + case 'qcurveTo': + ctx.quadraticCurveTo(data[0], data[1], data[2], data[3]); + break; + case 'lineTo': + ctx.lineTo(data[0], data[1]); + break; + } + } + if (drawing.type === 'fillPath') { + ctx.fill(); + } else { + ctx.stroke(); + } + } +} \ No newline at end of file diff --git a/src/canvas.ts b/src/canvas.ts index 83d9b1a..92316c2 100644 --- a/src/canvas.ts +++ b/src/canvas.ts @@ -1,18 +1,13 @@ -import { Config, Options, ResolvedOptions, Drawable, OpSet } from './core'; +import { Config, Options, ResolvedOptions, Drawable } from './core'; import { RoughGenerator } from './generator'; -import { RoughRenderer } from './renderer'; import { Point } from './geometry'; +import { RoughCanvasBase } from './canvas-base'; -const hasDocument = typeof document !== 'undefined'; - -export class RoughCanvas { - protected canvas: HTMLCanvasElement; - protected ctx: CanvasRenderingContext2D; +export class RoughCanvas extends RoughCanvasBase { private gen: RoughGenerator; constructor(canvas: HTMLCanvasElement, config?: Config) { - this.canvas = canvas; - this.ctx = this.canvas.getContext('2d')!; + super(canvas); this.gen = new RoughGenerator(config || null, this.canvas); } @@ -20,178 +15,61 @@ export class RoughCanvas { return this.gen; } - static createRenderer(): RoughRenderer { - return new RoughRenderer(); + getDefaultOptions(): ResolvedOptions { + return this.gen.defaultOptions; } - line(x1: number, y1: number, x2: number, y2: number, options?: Options) { + line(x1: number, y1: number, x2: number, y2: number, options?: Options): Drawable { const d = this.gen.line(x1, y1, x2, y2, options); this.draw(d); return d; } - rectangle(x: number, y: number, width: number, height: number, options?: Options) { + rectangle(x: number, y: number, width: number, height: number, options?: Options): Drawable { const d = this.gen.rectangle(x, y, width, height, options); this.draw(d); return d; } - ellipse(x: number, y: number, width: number, height: number, options?: Options) { + ellipse(x: number, y: number, width: number, height: number, options?: Options): Drawable { const d = this.gen.ellipse(x, y, width, height, options); this.draw(d); return d; } - circle(x: number, y: number, diameter: number, options?: Options) { + circle(x: number, y: number, diameter: number, options?: Options): Drawable { const d = this.gen.circle(x, y, diameter, options); this.draw(d); return d; } - linearPath(points: Point[], options?: Options) { + linearPath(points: Point[], options?: Options): Drawable { const d = this.gen.linearPath(points, options); this.draw(d); return d; } - polygon(points: Point[], options?: Options) { + polygon(points: Point[], options?: Options): Drawable { const d = this.gen.polygon(points, options); this.draw(d); return d; } - arc(x: number, y: number, width: number, height: number, start: number, stop: number, closed: boolean = false, options?: Options) { + arc(x: number, y: number, width: number, height: number, start: number, stop: number, closed: boolean = false, options?: Options): Drawable { const d = this.gen.arc(x, y, width, height, start, stop, closed, options); this.draw(d); return d; } - curve(points: Point[], options?: Options) { + curve(points: Point[], options?: Options): Drawable { const d = this.gen.curve(points, options); this.draw(d); return d; } - path(d: string, options?: Options) { + path(d: string, options?: Options): Drawable { const drawing = this.gen.path(d, options); this.draw(drawing); return drawing; } - - draw(drawable: Drawable) { - const sets = drawable.sets || []; - const o = drawable.options || this.gen.defaultOptions; - const ctx = this.ctx; - for (const drawing of sets) { - switch (drawing.type) { - case 'path': - ctx.save(); - ctx.strokeStyle = o.stroke; - ctx.lineWidth = o.strokeWidth; - this._drawToContext(ctx, drawing); - ctx.restore(); - break; - case 'fillPath': - ctx.save(); - ctx.fillStyle = o.fill || ''; - this._drawToContext(ctx, drawing); - ctx.restore(); - break; - case 'fillSketch': - this.fillSketch(ctx, drawing, o); - break; - case 'path2Dfill': { - this.ctx.save(); - this.ctx.fillStyle = o.fill || ''; - const p2d = new Path2D(drawing.path); - this.ctx.fill(p2d); - this.ctx.restore(); - break; - } - case 'path2Dpattern': { - const doc = this.canvas.ownerDocument || (hasDocument && document); - if (doc) { - const size = drawing.size!; - const hcanvas = doc.createElement('canvas'); - const hcontext = hcanvas.getContext('2d')!; - const bbox = this.computeBBox(drawing.path!); - if (bbox && (bbox.width || bbox.height)) { - hcanvas.width = this.canvas.width; - hcanvas.height = this.canvas.height; - hcontext.translate(bbox.x || 0, bbox.y || 0); - } else { - hcanvas.width = size[0]; - hcanvas.height = size[1]; - } - this.fillSketch(hcontext, drawing, o); - this.ctx.save(); - this.ctx.fillStyle = this.ctx.createPattern(hcanvas, 'repeat'); - const p2d = new Path2D(drawing.path); - this.ctx.fill(p2d); - this.ctx.restore(); - } else { - console.error('Cannot render path2Dpattern. No defs/document defined.'); - } - break; - } - } - } - } - - private computeBBox(d: string): SVGRect | null { - if (hasDocument) { - try { - const ns = 'http://www.w3.org/2000/svg'; - const svg = document.createElementNS(ns, 'svg'); - svg.setAttribute('width', '0'); - svg.setAttribute('height', '0'); - const pathNode = self.document.createElementNS(ns, 'path'); - pathNode.setAttribute('d', d); - svg.appendChild(pathNode); - document.body.appendChild(svg); - const bbox = pathNode.getBBox(); - document.body.removeChild(svg); - return bbox; - } catch (err) { } - } - return null; - } - - private fillSketch(ctx: CanvasRenderingContext2D, drawing: OpSet, o: ResolvedOptions) { - let fweight = o.fillWeight; - if (fweight < 0) { - fweight = o.strokeWidth / 2; - } - ctx.save(); - ctx.strokeStyle = o.fill || ''; - ctx.lineWidth = fweight; - this._drawToContext(ctx, drawing); - ctx.restore(); - } - - private _drawToContext(ctx: CanvasRenderingContext2D, drawing: OpSet) { - ctx.beginPath(); - for (const item of drawing.ops) { - const data = item.data; - switch (item.op) { - case 'move': - ctx.moveTo(data[0], data[1]); - break; - case 'bcurveTo': - ctx.bezierCurveTo(data[0], data[1], data[2], data[3], data[4], data[5]); - break; - case 'qcurveTo': - ctx.quadraticCurveTo(data[0], data[1], data[2], data[3]); - break; - case 'lineTo': - ctx.lineTo(data[0], data[1]); - break; - } - } - if (drawing.type === 'fillPath') { - ctx.fill(); - } else { - ctx.stroke(); - } - } } \ No newline at end of file diff --git a/src/generator-async.ts b/src/generator-async.ts index 46a5950..7a56461 100644 --- a/src/generator-async.ts +++ b/src/generator-async.ts @@ -1,15 +1,14 @@ -import { RoughGenerator } from './generator'; import { Options, Drawable, OpSet } from './core'; import { Point } from './geometry.js'; +import { RoughGeneratorBase } from './generator-base'; + +export class RoughGeneratorAsync extends RoughGeneratorBase { -export class RoughGeneratorAsync extends RoughGenerator { - // @ts-ignore async line(x1: number, y1: number, x2: number, y2: number, options?: Options): Promise { const o = this._options(options); return this._drawable('line', [await this.lib.line(x1, y1, x2, y2, o)], o); } - // @ts-ignore async rectangle(x: number, y: number, width: number, height: number, options?: Options): Promise { const o = this._options(options); const paths = []; @@ -25,7 +24,6 @@ export class RoughGeneratorAsync extends RoughGenerator { return this._drawable('rectangle', paths, o); } - // @ts-ignore async ellipse(x: number, y: number, width: number, height: number, options?: Options): Promise { const o = this._options(options); const paths = []; @@ -42,20 +40,17 @@ export class RoughGeneratorAsync extends RoughGenerator { return this._drawable('ellipse', paths, o); } - // @ts-ignore async circle(x: number, y: number, diameter: number, options?: Options): Promise { const ret = await this.ellipse(x, y, diameter, diameter, options); ret.shape = 'circle'; return ret; } - // @ts-ignore async linearPath(points: Point[], options?: Options): Promise { const o = this._options(options); return this._drawable('linearPath', [await this.lib.linearPath(points, false, o)], o); } - // @ts-ignore async arc(x: number, y: number, width: number, height: number, start: number, stop: number, closed: boolean = false, options?: Options): Promise { const o = this._options(options); const paths = []; @@ -72,13 +67,11 @@ export class RoughGeneratorAsync extends RoughGenerator { return this._drawable('arc', paths, o); } - // @ts-ignore async curve(points: Point[], options?: Options): Promise { const o = this._options(options); return this._drawable('curve', [await this.lib.curve(points, o)], o); } - // @ts-ignore async polygon(points: Point[], options?: Options): Promise { const o = this._options(options); const paths = []; @@ -104,7 +97,6 @@ export class RoughGeneratorAsync extends RoughGenerator { return this._drawable('polygon', paths, o); } - // @ts-ignore async path(d: string, options?: Options): Promise { const o = this._options(options); const paths: OpSet[] = []; diff --git a/src/generator-base.ts b/src/generator-base.ts new file mode 100644 index 0000000..f89fb41 --- /dev/null +++ b/src/generator-base.ts @@ -0,0 +1,209 @@ +import { RoughRenderer } from './renderer.js'; +import { Config, DrawingSurface, Options, ResolvedOptions, Drawable, OpSet, PathInfo, PatternInfo } from './core'; +import { Point } from './geometry.js'; +import { createRenderer } from './renderer-factory.js'; + +const hasSelf = typeof self !== 'undefined'; + +export abstract class RoughGeneratorBase { + protected config: Config; + protected surface: DrawingSurface; + protected renderer: RoughRenderer; + defaultOptions: ResolvedOptions = { + maxRandomnessOffset: 2, + roughness: 1, + bowing: 1, + stroke: '#000', + strokeWidth: 1, + curveTightness: 0, + curveStepCount: 9, + fillStyle: 'hachure', + fillWeight: -1, + hachureAngle: -41, + hachureGap: -1 + }; + + constructor(config: Config | null, surface: DrawingSurface) { + this.config = config || {}; + this.surface = surface; + this.renderer = createRenderer(this.config); + if (this.config.options) { + this.defaultOptions = this._options(this.config.options); + } + } + + protected _options(options?: Options): ResolvedOptions { + return options ? Object.assign({}, this.defaultOptions, options) : this.defaultOptions; + } + + protected _drawable(shape: string, sets: OpSet[], options: ResolvedOptions): Drawable { + return { shape, sets: sets || [], options: options || this.defaultOptions }; + } + + protected get lib(): RoughRenderer { + return this.renderer; + } + + private getCanvasSize(): Point { + const val = (w: any): number => { + if (w && typeof w === 'object') { + if (w.baseVal && w.baseVal.value) { + return w.baseVal.value; + } + } + return w || 100; + }; + if (this.surface) { + return [val(this.surface.width), val(this.surface.height)]; + } + return [100, 100]; + } + + protected computePolygonSize(points: Point[]): Point { + if (points.length) { + let left = points[0][0]; + let right = points[0][0]; + let top = points[0][1]; + let bottom = points[0][1]; + for (let i = 1; i < points.length; i++) { + left = Math.min(left, points[i][0]); + right = Math.max(right, points[i][0]); + top = Math.min(top, points[i][1]); + bottom = Math.max(bottom, points[i][1]); + } + return [(right - left), (bottom - top)]; + } + return [0, 0]; + } + + protected polygonPath(points: Point[]): string { + let d = ''; + if (points.length) { + d = `M${points[0][0]},${points[0][1]}`; + for (let i = 1; i < points.length; i++) { + d = `${d} L${points[i][0]},${points[i][1]}`; + } + } + return d; + } + + protected computePathSize(d: string): Point { + let size: Point = [0, 0]; + if (hasSelf && self.document) { + try { + const ns = 'http://www.w3.org/2000/svg'; + const svg = self.document.createElementNS(ns, 'svg'); + svg.setAttribute('width', '0'); + svg.setAttribute('height', '0'); + const pathNode = self.document.createElementNS(ns, 'path'); + pathNode.setAttribute('d', d); + svg.appendChild(pathNode); + self.document.body.appendChild(svg); + const bb = pathNode.getBBox(); + if (bb) { + size[0] = bb.width || 0; + size[1] = bb.height || 0; + } + self.document.body.removeChild(svg); + } catch (err) { } + } + const canvasSize = this.getCanvasSize(); + if (!(size[0] * size[1])) { + size = canvasSize; + } + return size; + } + + toPaths(drawable: Drawable): PathInfo[] { + const sets = drawable.sets || []; + const o = drawable.options || this.defaultOptions; + const paths: PathInfo[] = []; + for (const drawing of sets) { + let path: PathInfo | null = null; + switch (drawing.type) { + case 'path': + path = { + d: this.opsToPath(drawing), + stroke: o.stroke, + strokeWidth: o.strokeWidth, + fill: 'none' + }; + break; + case 'fillPath': + path = { + d: this.opsToPath(drawing), + stroke: 'none', + strokeWidth: 0, + fill: o.fill || 'none' + }; + break; + case 'fillSketch': + path = this.fillSketch(drawing, o); + break; + case 'path2Dfill': + path = { + d: drawing.path || '', + stroke: 'none', + strokeWidth: 0, + fill: o.fill || 'none' + }; + break; + case 'path2Dpattern': { + const size = drawing.size!; + const pattern: PatternInfo = { + x: 0, y: 0, width: 1, height: 1, + viewBox: `0 0 ${Math.round(size[0])} ${Math.round(size[1])}`, + patternUnits: 'objectBoundingBox', + path: this.fillSketch(drawing, o) + }; + path = { + d: drawing.path!, + stroke: 'none', + strokeWidth: 0, + pattern: pattern + }; + break; + } + } + if (path) { + paths.push(path); + } + } + return paths; + } + + private fillSketch(drawing: OpSet, o: ResolvedOptions): PathInfo { + let fweight = o.fillWeight; + if (fweight < 0) { + fweight = o.strokeWidth / 2; + } + return { + d: this.opsToPath(drawing), + stroke: o.fill || 'none', + strokeWidth: fweight, + fill: 'none' + }; + } + + opsToPath(drawing: OpSet): string { + let path = ''; + for (const item of drawing.ops) { + const data = item.data; + switch (item.op) { + case 'move': + path += `M${data[0]} ${data[1]} `; + break; + case 'bcurveTo': + path += `C${data[0]} ${data[1]}, ${data[2]} ${data[3]}, ${data[4]} ${data[5]} `; + break; + case 'qcurveTo': + path += `Q${data[0]} ${data[1]}, ${data[2]} ${data[3]} `; + break; + case 'lineTo': + path += `L${data[0]} ${data[1]} `; + break; + } + } + return path.trim(); + } +} \ No newline at end of file diff --git a/src/generator.ts b/src/generator.ts index 440fad0..96b4cc3 100644 --- a/src/generator.ts +++ b/src/generator.ts @@ -1,117 +1,10 @@ -import { RoughRenderer } from './renderer.js'; -import { Config, DrawingSurface, Options, ResolvedOptions, Drawable, OpSet, PathInfo, PatternInfo } from './core'; +import { Config, DrawingSurface, Options, Drawable, OpSet } from './core'; import { Point } from './geometry.js'; -import { createRenderer } from './renderer-factory.js'; - -const hasSelf = typeof self !== 'undefined'; - -export class RoughGenerator { - private config: Config; - private surface: DrawingSurface; - private renderer: RoughRenderer; - defaultOptions: ResolvedOptions = { - maxRandomnessOffset: 2, - roughness: 1, - bowing: 1, - stroke: '#000', - strokeWidth: 1, - curveTightness: 0, - curveStepCount: 9, - fillStyle: 'hachure', - fillWeight: -1, - hachureAngle: -41, - hachureGap: -1 - }; +import { RoughGeneratorBase } from './generator-base'; +export class RoughGenerator extends RoughGeneratorBase { constructor(config: Config | null, surface: DrawingSurface) { - this.config = config || {}; - this.surface = surface; - this.renderer = createRenderer(this.config); - if (this.config.options) { - this.defaultOptions = this._options(this.config.options); - } - } - - protected _options(options?: Options): ResolvedOptions { - return options ? Object.assign({}, this.defaultOptions, options) : this.defaultOptions; - } - - protected _drawable(shape: string, sets: OpSet[], options: ResolvedOptions): Drawable { - return { shape, sets: sets || [], options: options || this.defaultOptions }; - } - - protected get lib(): RoughRenderer { - return this.renderer; - } - - private getCanvasSize(): Point { - const val = (w: any): number => { - if (w && typeof w === 'object') { - if (w.baseVal && w.baseVal.value) { - return w.baseVal.value; - } - } - return w || 100; - }; - if (this.surface) { - return [val(this.surface.width), val(this.surface.height)]; - } - return [100, 100]; - } - - protected computePolygonSize(points: Point[]): Point { - if (points.length) { - let left = points[0][0]; - let right = points[0][0]; - let top = points[0][1]; - let bottom = points[0][1]; - for (let i = 1; i < points.length; i++) { - left = Math.min(left, points[i][0]); - right = Math.max(right, points[i][0]); - top = Math.min(top, points[i][1]); - bottom = Math.max(bottom, points[i][1]); - } - return [(right - left), (bottom - top)]; - } - return [0, 0]; - } - - protected polygonPath(points: Point[]): string { - let d = ''; - if (points.length) { - d = `M${points[0][0]},${points[0][1]}`; - for (let i = 1; i < points.length; i++) { - d = `${d} L${points[i][0]},${points[i][1]}`; - } - } - return d; - } - - protected computePathSize(d: string): Point { - let size: Point = [0, 0]; - if (hasSelf && self.document) { - try { - const ns = 'http://www.w3.org/2000/svg'; - const svg = self.document.createElementNS(ns, 'svg'); - svg.setAttribute('width', '0'); - svg.setAttribute('height', '0'); - const pathNode = self.document.createElementNS(ns, 'path'); - pathNode.setAttribute('d', d); - svg.appendChild(pathNode); - self.document.body.appendChild(svg); - const bb = pathNode.getBBox(); - if (bb) { - size[0] = bb.width || 0; - size[1] = bb.height || 0; - } - self.document.body.removeChild(svg); - } catch (err) { } - } - const canvasSize = this.getCanvasSize(); - if (!(size[0] * size[1])) { - size = canvasSize; - } - return size; + super(config, surface); } line(x1: number, y1: number, x2: number, y2: number, options?: Options): Drawable { @@ -235,97 +128,4 @@ export class RoughGenerator { paths.push(this.lib.svgPath(d, o)); return this._drawable('path', paths, o); } - - toPaths(drawable: Drawable): PathInfo[] { - const sets = drawable.sets || []; - const o = drawable.options || this.defaultOptions; - const paths: PathInfo[] = []; - for (const drawing of sets) { - let path: PathInfo | null = null; - switch (drawing.type) { - case 'path': - path = { - d: this.opsToPath(drawing), - stroke: o.stroke, - strokeWidth: o.strokeWidth, - fill: 'none' - }; - break; - case 'fillPath': - path = { - d: this.opsToPath(drawing), - stroke: 'none', - strokeWidth: 0, - fill: o.fill || 'none' - }; - break; - case 'fillSketch': - path = this.fillSketch(drawing, o); - break; - case 'path2Dfill': - path = { - d: drawing.path || '', - stroke: 'none', - strokeWidth: 0, - fill: o.fill || 'none' - }; - break; - case 'path2Dpattern': { - const size = drawing.size!; - const pattern: PatternInfo = { - x: 0, y: 0, width: 1, height: 1, - viewBox: `0 0 ${Math.round(size[0])} ${Math.round(size[1])}`, - patternUnits: 'objectBoundingBox', - path: this.fillSketch(drawing, o) - }; - path = { - d: drawing.path!, - stroke: 'none', - strokeWidth: 0, - pattern: pattern - }; - break; - } - } - if (path) { - paths.push(path); - } - } - return paths; - } - - private fillSketch(drawing: OpSet, o: ResolvedOptions): PathInfo { - let fweight = o.fillWeight; - if (fweight < 0) { - fweight = o.strokeWidth / 2; - } - return { - d: this.opsToPath(drawing), - stroke: o.fill || 'none', - strokeWidth: fweight, - fill: 'none' - }; - } - - opsToPath(drawing: OpSet): string { - let path = ''; - for (const item of drawing.ops) { - const data = item.data; - switch (item.op) { - case 'move': - path += `M${data[0]} ${data[1]} `; - break; - case 'bcurveTo': - path += `C${data[0]} ${data[1]}, ${data[2]} ${data[3]}, ${data[4]} ${data[5]} `; - break; - case 'qcurveTo': - path += `Q${data[0]} ${data[1]}, ${data[2]} ${data[3]} `; - break; - case 'lineTo': - path += `L${data[0]} ${data[1]} `; - break; - } - } - return path.trim(); - } } \ No newline at end of file diff --git a/src/rough.ts b/src/rough.ts index 339a768..51029d2 100644 --- a/src/rough.ts +++ b/src/rough.ts @@ -8,14 +8,14 @@ import { RoughSVG } from './svg'; import { RoughSVGAsync } from './svg-async'; export default { - canvas(canvas: HTMLCanvasElement, config?: Config) { + canvas(canvas: HTMLCanvasElement, config?: Config): RoughCanvas | RoughCanvasAsync { if (config && config.async) { return new RoughCanvasAsync(canvas, config); } return new RoughCanvas(canvas, config); }, - svg(svg: SVGSVGElement, config?: Config) { + svg(svg: SVGSVGElement, config?: Config): RoughSVG | RoughSVGAsync { if (config && config.async) { return new RoughSVGAsync(svg, config); } @@ -26,7 +26,7 @@ export default { return RoughCanvas.createRenderer(); }, - generator(config: Config | null, surface: DrawingSurface) { + generator(config: Config | null, surface: DrawingSurface): RoughGenerator | RoughGeneratorAsync { if (config && config.async) { return new RoughGeneratorAsync(config, surface); } diff --git a/src/svg-async.ts b/src/svg-async.ts index 97ec6cd..ea8be12 100644 --- a/src/svg-async.ts +++ b/src/svg-async.ts @@ -1,70 +1,68 @@ -import { RoughSVG } from './svg'; -import { Config, Options } from './core'; +import { Config, Options, ResolvedOptions, OpSet } from './core'; import { RoughGeneratorAsync } from './generator-async'; import { Point } from './geometry'; +import { RoughSVGBase } from './svg-base'; -export class RoughSVGAsync extends RoughSVG { +export class RoughSVGAsync extends RoughSVGBase { private genAsync: RoughGeneratorAsync; constructor(svg: SVGSVGElement, config?: Config) { - super(svg, config); + super(svg); this.genAsync = new RoughGeneratorAsync(config || null, this.svg); } - // @ts-ignore get generator(): RoughGeneratorAsync { return this.genAsync; } - // @ts-ignore + getDefaultOptions(): ResolvedOptions { + return this.genAsync.defaultOptions; + } + + opsToPath(drawing: OpSet): string { + return this.genAsync.opsToPath(drawing); + } + async line(x1: number, y1: number, x2: number, y2: number, options?: Options): Promise { const d = await this.genAsync.line(x1, y1, x2, y2, options); return this.draw(d); } - // @ts-ignore async rectangle(x: number, y: number, width: number, height: number, options?: Options): Promise { const d = await this.genAsync.rectangle(x, y, width, height, options); return this.draw(d); } - // @ts-ignore async ellipse(x: number, y: number, width: number, height: number, options?: Options): Promise { const d = await this.genAsync.ellipse(x, y, width, height, options); return this.draw(d); } - // @ts-ignore async circle(x: number, y: number, diameter: number, options?: Options): Promise { const d = await this.genAsync.circle(x, y, diameter, options); return this.draw(d); } - // @ts-ignore async linearPath(points: Point[], options?: Options): Promise { const d = await this.genAsync.linearPath(points, options); return this.draw(d); } - // @ts-ignore async polygon(points: Point[], options?: Options): Promise { const d = await this.genAsync.polygon(points, options); return this.draw(d); } - // @ts-ignore async arc(x: number, y: number, width: number, height: number, start: number, stop: number, closed: boolean = false, options?: Options): Promise { const d = await this.genAsync.arc(x, y, width, height, start, stop, closed, options); return this.draw(d); } - // @ts-ignore async curve(points: Point[], options?: Options): Promise { const d = await this.genAsync.curve(points, options); return this.draw(d); } - // @ts-ignore async path(d: string, options?: Options): Promise { const drawing = await this.genAsync.path(d, options); return this.draw(drawing); diff --git a/src/svg-base.ts b/src/svg-base.ts new file mode 100644 index 0000000..23dfae4 --- /dev/null +++ b/src/svg-base.ts @@ -0,0 +1,121 @@ +import { Drawable, OpSet, ResolvedOptions } from './core'; +import { RoughRenderer } from './renderer'; + +const hasDocument = typeof document !== 'undefined'; + +export abstract class RoughSVGBase { + protected svg: SVGSVGElement; + protected _defs?: SVGDefsElement; + + constructor(svg: SVGSVGElement) { + this.svg = svg; + } + + abstract getDefaultOptions(): ResolvedOptions; + + abstract opsToPath(drawing: OpSet): string; + + static createRenderer(): RoughRenderer { + return new RoughRenderer(); + } + + get defs(): SVGDefsElement | null { + const doc = this.svg.ownerDocument || (hasDocument && document); + if (doc) { + if (!this._defs) { + const dnode = doc.createElementNS('http://www.w3.org/2000/svg', 'defs'); + if (this.svg.firstChild) { + this.svg.insertBefore(dnode, this.svg.firstChild); + } else { + this.svg.appendChild(dnode); + } + this._defs = dnode; + } + } + return this._defs || null; + } + + draw(drawable: Drawable): SVGGElement { + const sets = drawable.sets || []; + const o = drawable.options || this.getDefaultOptions(); + const doc = this.svg.ownerDocument || (hasDocument && document); + const g = doc.createElementNS('http://www.w3.org/2000/svg', 'g'); + for (const drawing of sets) { + let path = null; + switch (drawing.type) { + case 'path': { + path = doc.createElementNS('http://www.w3.org/2000/svg', 'path'); + path.setAttribute('d', this.opsToPath(drawing)); + path.style.stroke = o.stroke; + path.style.strokeWidth = o.strokeWidth + ''; + path.style.fill = 'none'; + break; + } + case 'fillPath': { + path = doc.createElementNS('http://www.w3.org/2000/svg', 'path'); + path.setAttribute('d', this.opsToPath(drawing)); + path.style.stroke = 'none'; + path.style.strokeWidth = '0'; + path.style.fill = o.fill || null; + break; + } + case 'fillSketch': { + path = this.fillSketch(doc, drawing, o); + break; + } + case 'path2Dfill': { + path = doc.createElementNS('http://www.w3.org/2000/svg', 'path'); + path.setAttribute('d', drawing.path || ''); + path.style.stroke = 'none'; + path.style.strokeWidth = '0'; + path.style.fill = o.fill || null; + break; + } + case 'path2Dpattern': { + if (!this.defs) { + console.error('Cannot render path2Dpattern. No defs/document defined.'); + } else { + const size = drawing.size!; + const pattern = doc.createElementNS('http://www.w3.org/2000/svg', 'pattern'); + const id = `rough-${Math.floor(Math.random() * (Number.MAX_SAFE_INTEGER || 999999))}`; + pattern.setAttribute('id', id); + pattern.setAttribute('x', '0'); + pattern.setAttribute('y', '0'); + pattern.setAttribute('width', '1'); + pattern.setAttribute('height', '1'); + pattern.setAttribute('height', '1'); + pattern.setAttribute('viewBox', `0 0 ${Math.round(size[0])} ${Math.round(size[1])}`); + pattern.setAttribute('patternUnits', 'objectBoundingBox'); + const patternPath = this.fillSketch(doc, drawing, o); + pattern.appendChild(patternPath); + this.defs!.appendChild(pattern); + + path = doc.createElementNS('http://www.w3.org/2000/svg', 'path'); + path.setAttribute('d', drawing.path || ''); + path.style.stroke = 'none'; + path.style.strokeWidth = '0'; + path.style.fill = `url(#${id})`; + } + break; + } + } + if (path) { + g.appendChild(path); + } + } + return g; + } + + private fillSketch(doc: Document, drawing: OpSet, o: ResolvedOptions): SVGPathElement { + let fweight = o.fillWeight; + if (fweight < 0) { + fweight = o.strokeWidth / 2; + } + const path = doc.createElementNS('http://www.w3.org/2000/svg', 'path'); + path.setAttribute('d', this.opsToPath(drawing)); + path.style.stroke = o.fill || null; + path.style.strokeWidth = fweight + ''; + path.style.fill = 'none'; + return path; + } +} \ No newline at end of file diff --git a/src/svg.ts b/src/svg.ts index 800e456..57b18d6 100644 --- a/src/svg.ts +++ b/src/svg.ts @@ -1,17 +1,13 @@ -import { Config, Options, Drawable, OpSet, ResolvedOptions } from './core'; +import { Config, Options, OpSet, ResolvedOptions } from './core'; import { RoughGenerator } from './generator'; -import { RoughRenderer } from './renderer'; import { Point } from './geometry'; +import { RoughSVGBase } from './svg-base'; -const hasDocument = typeof document !== 'undefined'; - -export class RoughSVG { - protected svg: SVGSVGElement; +export class RoughSVG extends RoughSVGBase { private gen: RoughGenerator; - protected _defs?: SVGDefsElement; constructor(svg: SVGSVGElement, config?: Config) { - this.svg = svg; + super(svg); this.gen = new RoughGenerator(config || null, this.svg); } @@ -19,24 +15,12 @@ export class RoughSVG { return this.gen; } - static createRenderer(): RoughRenderer { - return new RoughRenderer(); + getDefaultOptions(): ResolvedOptions { + return this.gen.defaultOptions; } - get defs(): SVGDefsElement | null { - const doc = this.svg.ownerDocument || (hasDocument && document); - if (doc) { - if (!this._defs) { - const dnode = doc.createElementNS('http://www.w3.org/2000/svg', 'defs'); - if (this.svg.firstChild) { - this.svg.insertBefore(dnode, this.svg.firstChild); - } else { - this.svg.appendChild(dnode); - } - this._defs = dnode; - } - } - return this._defs || null; + opsToPath(drawing: OpSet): string { + return this.gen.opsToPath(drawing); } line(x1: number, y1: number, x2: number, y2: number, options?: Options) { @@ -83,92 +67,4 @@ export class RoughSVG { const drawing = this.gen.path(d, options); return this.draw(drawing); } - - draw(drawable: Drawable): SVGGElement { - const sets = drawable.sets || []; - const o = drawable.options || this.gen.defaultOptions; - const doc = this.svg.ownerDocument || (hasDocument && document); - const g = doc.createElementNS('http://www.w3.org/2000/svg', 'g'); - for (const drawing of sets) { - let path = null; - switch (drawing.type) { - case 'path': { - path = doc.createElementNS('http://www.w3.org/2000/svg', 'path'); - path.setAttribute('d', this.opsToPath(drawing)); - path.style.stroke = o.stroke; - path.style.strokeWidth = o.strokeWidth + ''; - path.style.fill = 'none'; - break; - } - case 'fillPath': { - path = doc.createElementNS('http://www.w3.org/2000/svg', 'path'); - path.setAttribute('d', this.opsToPath(drawing)); - path.style.stroke = 'none'; - path.style.strokeWidth = '0'; - path.style.fill = o.fill || null; - break; - } - case 'fillSketch': { - path = this.fillSketch(doc, drawing, o); - break; - } - case 'path2Dfill': { - path = doc.createElementNS('http://www.w3.org/2000/svg', 'path'); - path.setAttribute('d', drawing.path || ''); - path.style.stroke = 'none'; - path.style.strokeWidth = '0'; - path.style.fill = o.fill || null; - break; - } - case 'path2Dpattern': { - if (!this.defs) { - console.error('Cannot render path2Dpattern. No defs/document defined.'); - } else { - const size = drawing.size!; - const pattern = doc.createElementNS('http://www.w3.org/2000/svg', 'pattern'); - const id = `rough-${Math.floor(Math.random() * (Number.MAX_SAFE_INTEGER || 999999))}`; - pattern.setAttribute('id', id); - pattern.setAttribute('x', '0'); - pattern.setAttribute('y', '0'); - pattern.setAttribute('width', '1'); - pattern.setAttribute('height', '1'); - pattern.setAttribute('height', '1'); - pattern.setAttribute('viewBox', `0 0 ${Math.round(size[0])} ${Math.round(size[1])}`); - pattern.setAttribute('patternUnits', 'objectBoundingBox'); - const patternPath = this.fillSketch(doc, drawing, o); - pattern.appendChild(patternPath); - this.defs!.appendChild(pattern); - - path = doc.createElementNS('http://www.w3.org/2000/svg', 'path'); - path.setAttribute('d', drawing.path || ''); - path.style.stroke = 'none'; - path.style.strokeWidth = '0'; - path.style.fill = `url(#${id})`; - } - break; - } - } - if (path) { - g.appendChild(path); - } - } - return g; - } - - private opsToPath(drawing: OpSet) { - return this.gen.opsToPath(drawing); - } - - private fillSketch(doc: Document, drawing: OpSet, o: ResolvedOptions): SVGPathElement { - let fweight = o.fillWeight; - if (fweight < 0) { - fweight = o.strokeWidth / 2; - } - const path = doc.createElementNS('http://www.w3.org/2000/svg', 'path'); - path.setAttribute('d', this.opsToPath(drawing)); - path.style.stroke = o.fill || null; - path.style.strokeWidth = fweight + ''; - path.style.fill = 'none'; - return path; - } } \ No newline at end of file