diff --git a/demo/index.ts b/demo/index.ts index f5f32d06..a45f40b0 100644 --- a/demo/index.ts +++ b/demo/index.ts @@ -1,4 +1,5 @@ import * as svgVariableWidthLine from '@'; +import { Point } from '@'; class DrawingHandler { public el: SVGSVGElement; @@ -37,8 +38,9 @@ class DrawingHandler { return; } this.lastDrawTime = Date.now(); - const p = svgVariableWidthLine.util.translatePoint(this.el, e); - p.w = e.pressure * this.width; + const { x, y } = svgVariableWidthLine.util.translatePoint(this.el, e); + const w = e.pressure * this.width; + const p: Point = { x, y, w }; const lastPoint = this.points.slice(-1)[0]; if ( lastPoint && @@ -60,7 +62,9 @@ class DrawingHandler { this.el.addEventListener('pointerup', this.onPointerup.bind(this)); } update(): void { - const { d } = svgVariableWidthLine.compute(...this.points); + const { d } = svgVariableWidthLine.compute( + ...svgVariableWidthLine.smooth(this.points, 4) + ); this.mustTarget.setAttribute('d', d); } } diff --git a/src/index.ts b/src/index.ts index f3e43121..4147976d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,3 +3,4 @@ import * as vector2 from './vector2'; export * from './compute'; export * from './types'; export { util, vector2 }; +export * from './smooth'; diff --git a/src/smooth.ts b/src/smooth.ts new file mode 100644 index 00000000..cf256166 --- /dev/null +++ b/src/smooth.ts @@ -0,0 +1,40 @@ +import { Point } from './types'; + +// Refer: https://github.com/Jam3/chaikin-smooth/blob/master/index.js + +export function smoothOnce(...points: Point[]): Point[] { + const ret: Point[] = []; + if (points.length === 0) { + return []; + } + ret.push({ ...points[0] }); + for (let i = 0; i < points.length - 1; i++) { + const p0 = points[i]; + const p1 = points[i + 1]; + + ret.push( + { + x: 0.75 * p0.x + 0.25 * p1.x, + y: 0.75 * p0.y + 0.25 * p1.y, + w: p0.w * 0.75 + p1.w * 0.25, + }, + { + x: 0.25 * p0.x + 0.75 * p1.x, + y: 0.25 * p0.y + 0.75 * p1.y, + w: p0.w * 0.25 + p1.w * 0.75, + } + ); + } + if (points.length > 2) { + ret.push({ ...points[points.length - 1] }); + } + return ret; +} + +export function smooth(points: Point[], times = 1): Point[] { + let ret = points; + for (let count = 0; count < times; count += 1) { + ret = smoothOnce(...ret); + } + return ret; +}