1674 lines
47 KiB
JavaScript
1674 lines
47 KiB
JavaScript
|
|
/*eslint-disable */
|
||
|
|
// This is a slightly modified version of rough.js for D2
|
||
|
|
//
|
||
|
|
// rough.js is from https://github.com/rough-stuff/rough.
|
||
|
|
// Attribution for this file is as follows:
|
||
|
|
//
|
||
|
|
// MIT License
|
||
|
|
//
|
||
|
|
// Copyright (c) 2019 Preet Shihn
|
||
|
|
//
|
||
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||
|
|
// of this software and associated documentation files (the "Software"), to deal
|
||
|
|
// in the Software without restriction, including without limitation the rights
|
||
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||
|
|
// copies of the Software, and to permit persons to whom the Software is
|
||
|
|
// furnished to do so, subject to the following conditions:
|
||
|
|
//
|
||
|
|
// The above copyright notice and this permission notice shall be included in all
|
||
|
|
// copies or substantial portions of the Software.
|
||
|
|
//
|
||
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||
|
|
// SOFTWARE.
|
||
|
|
//
|
||
|
|
const t = "http://www.w3.org/2000/svg";
|
||
|
|
function e(t, e, s) {
|
||
|
|
if (t && t.length) {
|
||
|
|
const [n, i] = e,
|
||
|
|
a = (Math.PI / 180) * s,
|
||
|
|
o = Math.cos(a),
|
||
|
|
h = Math.sin(a);
|
||
|
|
t.forEach((t) => {
|
||
|
|
const [e, s] = t;
|
||
|
|
(t[0] = (e - n) * o - (s - i) * h + n), (t[1] = (e - n) * h + (s - i) * o + i);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function s(t) {
|
||
|
|
const e = t[0],
|
||
|
|
s = t[1];
|
||
|
|
return Math.sqrt(Math.pow(e[0] - s[0], 2) + Math.pow(e[1] - s[1], 2));
|
||
|
|
}
|
||
|
|
function n(t, e) {
|
||
|
|
return t.type === e;
|
||
|
|
}
|
||
|
|
const i = {
|
||
|
|
A: 7,
|
||
|
|
a: 7,
|
||
|
|
C: 6,
|
||
|
|
c: 6,
|
||
|
|
H: 1,
|
||
|
|
h: 1,
|
||
|
|
L: 2,
|
||
|
|
l: 2,
|
||
|
|
M: 2,
|
||
|
|
m: 2,
|
||
|
|
Q: 4,
|
||
|
|
q: 4,
|
||
|
|
S: 4,
|
||
|
|
s: 4,
|
||
|
|
T: 4,
|
||
|
|
t: 2,
|
||
|
|
V: 1,
|
||
|
|
v: 1,
|
||
|
|
Z: 0,
|
||
|
|
z: 0,
|
||
|
|
};
|
||
|
|
class a {
|
||
|
|
constructor(t) {
|
||
|
|
(this.COMMAND = 0),
|
||
|
|
(this.NUMBER = 1),
|
||
|
|
(this.EOD = 2),
|
||
|
|
(this.segments = []),
|
||
|
|
this.parseData(t),
|
||
|
|
this.processPoints();
|
||
|
|
}
|
||
|
|
tokenize(t) {
|
||
|
|
const e = new Array();
|
||
|
|
|
||
|
|
for (; "" !== t; ) {
|
||
|
|
const a = t.match(/^([ \t\r\n,]+)/);
|
||
|
|
const b = t.match(/^([aAcChHlLmMqQsStTvVzZ])/);
|
||
|
|
const c = t.match(/^(([-+]?[0-9]+(\.[0-9]*)?|[-+]?\.[0-9]+)([eE][-+]?[0-9]+)?)/);
|
||
|
|
if (a) t = t.substr(a[0].length);
|
||
|
|
else if (b)
|
||
|
|
(e[e.length] = { type: this.COMMAND, text: b[0] }), (t = t.substr(b[0].length));
|
||
|
|
else {
|
||
|
|
if (!c) return [];
|
||
|
|
(e[e.length] = { type: this.NUMBER, text: `${parseFloat(c[0])}` }),
|
||
|
|
(t = t.substr(c[0].length));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return (e[e.length] = { type: this.EOD, text: "" }), e;
|
||
|
|
}
|
||
|
|
parseData(t) {
|
||
|
|
const e = this.tokenize(t);
|
||
|
|
let s = 0,
|
||
|
|
a = e[s],
|
||
|
|
o = "BOD";
|
||
|
|
for (this.segments = new Array(); !n(a, this.EOD); ) {
|
||
|
|
let h;
|
||
|
|
const r = new Array();
|
||
|
|
if ("BOD" === o) {
|
||
|
|
if ("M" !== a.text && "m" !== a.text) return void this.parseData("M0,0" + t);
|
||
|
|
s++, (h = i[a.text]), (o = a.text);
|
||
|
|
} else n(a, this.NUMBER) ? (h = i[o]) : (s++, (h = i[a.text]), (o = a.text));
|
||
|
|
if (s + h < e.length) {
|
||
|
|
for (let t = s; t < s + h; t++) {
|
||
|
|
const s = e[t];
|
||
|
|
if (!n(s, this.NUMBER))
|
||
|
|
return void console.error("Param not a number: " + o + "," + s.text);
|
||
|
|
r[r.length] = +s.text;
|
||
|
|
}
|
||
|
|
if ("number" != typeof i[o]) return void console.error("Bad segment: " + o);
|
||
|
|
{
|
||
|
|
const t = { key: o, data: r };
|
||
|
|
this.segments.push(t),
|
||
|
|
(s += h),
|
||
|
|
(a = e[s]),
|
||
|
|
"M" === o && (o = "L"),
|
||
|
|
"m" === o && (o = "l");
|
||
|
|
}
|
||
|
|
} else console.error("Path data ended short");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
get closed() {
|
||
|
|
if (void 0 === this._closed) {
|
||
|
|
this._closed = !1;
|
||
|
|
for (const t of this.segments) "z" === t.key.toLowerCase() && (this._closed = !0);
|
||
|
|
}
|
||
|
|
return this._closed;
|
||
|
|
}
|
||
|
|
processPoints() {
|
||
|
|
let t = null,
|
||
|
|
e = [0, 0];
|
||
|
|
for (let s = 0; s < this.segments.length; s++) {
|
||
|
|
const n = this.segments[s];
|
||
|
|
switch (n.key) {
|
||
|
|
case "M":
|
||
|
|
case "L":
|
||
|
|
case "T":
|
||
|
|
n.point = [n.data[0], n.data[1]];
|
||
|
|
break;
|
||
|
|
case "m":
|
||
|
|
case "l":
|
||
|
|
case "t":
|
||
|
|
n.point = [n.data[0] + e[0], n.data[1] + e[1]];
|
||
|
|
break;
|
||
|
|
case "H":
|
||
|
|
n.point = [n.data[0], e[1]];
|
||
|
|
break;
|
||
|
|
case "h":
|
||
|
|
n.point = [n.data[0] + e[0], e[1]];
|
||
|
|
break;
|
||
|
|
case "V":
|
||
|
|
n.point = [e[0], n.data[0]];
|
||
|
|
break;
|
||
|
|
case "v":
|
||
|
|
n.point = [e[0], n.data[0] + e[1]];
|
||
|
|
break;
|
||
|
|
case "z":
|
||
|
|
case "Z":
|
||
|
|
t && (n.point = [t[0], t[1]]);
|
||
|
|
break;
|
||
|
|
case "C":
|
||
|
|
n.point = [n.data[4], n.data[5]];
|
||
|
|
break;
|
||
|
|
case "c":
|
||
|
|
n.point = [n.data[4] + e[0], n.data[5] + e[1]];
|
||
|
|
break;
|
||
|
|
case "S":
|
||
|
|
n.point = [n.data[2], n.data[3]];
|
||
|
|
break;
|
||
|
|
case "s":
|
||
|
|
n.point = [n.data[2] + e[0], n.data[3] + e[1]];
|
||
|
|
break;
|
||
|
|
case "Q":
|
||
|
|
n.point = [n.data[2], n.data[3]];
|
||
|
|
break;
|
||
|
|
case "q":
|
||
|
|
n.point = [n.data[2] + e[0], n.data[3] + e[1]];
|
||
|
|
break;
|
||
|
|
case "A":
|
||
|
|
n.point = [n.data[5], n.data[6]];
|
||
|
|
break;
|
||
|
|
case "a":
|
||
|
|
n.point = [n.data[5] + e[0], n.data[6] + e[1]];
|
||
|
|
}
|
||
|
|
("m" !== n.key && "M" !== n.key) || (t = null),
|
||
|
|
n.point && ((e = n.point), t || (t = n.point)),
|
||
|
|
("z" !== n.key && "Z" !== n.key) || (t = null);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
class o {
|
||
|
|
constructor(t) {
|
||
|
|
(this._position = [0, 0]),
|
||
|
|
(this._first = null),
|
||
|
|
(this.bezierReflectionPoint = null),
|
||
|
|
(this.quadReflectionPoint = null),
|
||
|
|
(this.parsed = new a(t));
|
||
|
|
}
|
||
|
|
get segments() {
|
||
|
|
return this.parsed.segments;
|
||
|
|
}
|
||
|
|
get closed() {
|
||
|
|
return this.parsed.closed;
|
||
|
|
}
|
||
|
|
get linearPoints() {
|
||
|
|
if (!this._linearPoints) {
|
||
|
|
const t = [];
|
||
|
|
let e = [];
|
||
|
|
for (const s of this.parsed.segments) {
|
||
|
|
const n = s.key.toLowerCase();
|
||
|
|
(("m" !== n && "z" !== n) || (e.length && (t.push(e), (e = [])), "z" !== n)) &&
|
||
|
|
s.point &&
|
||
|
|
e.push(s.point);
|
||
|
|
}
|
||
|
|
e.length && (t.push(e), (e = [])), (this._linearPoints = t);
|
||
|
|
}
|
||
|
|
return this._linearPoints;
|
||
|
|
}
|
||
|
|
get first() {
|
||
|
|
return this._first;
|
||
|
|
}
|
||
|
|
set first(t) {
|
||
|
|
this._first = t;
|
||
|
|
}
|
||
|
|
setPosition(t, e) {
|
||
|
|
(this._position = [t, e]), this._first || (this._first = [t, e]);
|
||
|
|
}
|
||
|
|
get position() {
|
||
|
|
return this._position;
|
||
|
|
}
|
||
|
|
get x() {
|
||
|
|
return this._position[0];
|
||
|
|
}
|
||
|
|
get y() {
|
||
|
|
return this._position[1];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
class h {
|
||
|
|
constructor(t, e, s, n, i, a) {
|
||
|
|
if (
|
||
|
|
((this._segIndex = 0),
|
||
|
|
(this._numSegs = 0),
|
||
|
|
(this._rx = 0),
|
||
|
|
(this._ry = 0),
|
||
|
|
(this._sinPhi = 0),
|
||
|
|
(this._cosPhi = 0),
|
||
|
|
(this._C = [0, 0]),
|
||
|
|
(this._theta = 0),
|
||
|
|
(this._delta = 0),
|
||
|
|
(this._T = 0),
|
||
|
|
(this._from = t),
|
||
|
|
t[0] === e[0] && t[1] === e[1])
|
||
|
|
)
|
||
|
|
return;
|
||
|
|
const o = Math.PI / 180;
|
||
|
|
(this._rx = Math.abs(s[0])),
|
||
|
|
(this._ry = Math.abs(s[1])),
|
||
|
|
(this._sinPhi = Math.sin(n * o)),
|
||
|
|
(this._cosPhi = Math.cos(n * o));
|
||
|
|
const h = (this._cosPhi * (t[0] - e[0])) / 2 + (this._sinPhi * (t[1] - e[1])) / 2,
|
||
|
|
r = (-this._sinPhi * (t[0] - e[0])) / 2 + (this._cosPhi * (t[1] - e[1])) / 2;
|
||
|
|
let c = 0;
|
||
|
|
const l =
|
||
|
|
this._rx * this._rx * this._ry * this._ry -
|
||
|
|
this._rx * this._rx * r * r -
|
||
|
|
this._ry * this._ry * h * h;
|
||
|
|
if (l < 0) {
|
||
|
|
const t = Math.sqrt(1 - l / (this._rx * this._rx * this._ry * this._ry));
|
||
|
|
(this._rx = this._rx * t), (this._ry = this._ry * t), (c = 0);
|
||
|
|
} else
|
||
|
|
c =
|
||
|
|
(i === a ? -1 : 1) *
|
||
|
|
Math.sqrt(l / (this._rx * this._rx * r * r + this._ry * this._ry * h * h));
|
||
|
|
const u = (c * this._rx * r) / this._ry,
|
||
|
|
p = (-c * this._ry * h) / this._rx;
|
||
|
|
(this._C = [0, 0]),
|
||
|
|
(this._C[0] = this._cosPhi * u - this._sinPhi * p + (t[0] + e[0]) / 2),
|
||
|
|
(this._C[1] = this._sinPhi * u + this._cosPhi * p + (t[1] + e[1]) / 2),
|
||
|
|
(this._theta = this.calculateVectorAngle(
|
||
|
|
1,
|
||
|
|
0,
|
||
|
|
(h - u) / this._rx,
|
||
|
|
(r - p) / this._ry
|
||
|
|
));
|
||
|
|
let d = this.calculateVectorAngle(
|
||
|
|
(h - u) / this._rx,
|
||
|
|
(r - p) / this._ry,
|
||
|
|
(-h - u) / this._rx,
|
||
|
|
(-r - p) / this._ry
|
||
|
|
);
|
||
|
|
!a && d > 0 ? (d -= 2 * Math.PI) : a && d < 0 && (d += 2 * Math.PI),
|
||
|
|
(this._numSegs = Math.ceil(Math.abs(d / (Math.PI / 2)))),
|
||
|
|
(this._delta = d / this._numSegs),
|
||
|
|
(this._T =
|
||
|
|
((8 / 3) * Math.sin(this._delta / 4) * Math.sin(this._delta / 4)) /
|
||
|
|
Math.sin(this._delta / 2));
|
||
|
|
}
|
||
|
|
getNextSegment() {
|
||
|
|
if (this._segIndex === this._numSegs) return null;
|
||
|
|
const t = Math.cos(this._theta),
|
||
|
|
e = Math.sin(this._theta),
|
||
|
|
s = this._theta + this._delta,
|
||
|
|
n = Math.cos(s),
|
||
|
|
i = Math.sin(s),
|
||
|
|
a = [
|
||
|
|
this._cosPhi * this._rx * n - this._sinPhi * this._ry * i + this._C[0],
|
||
|
|
this._sinPhi * this._rx * n + this._cosPhi * this._ry * i + this._C[1],
|
||
|
|
],
|
||
|
|
o = [
|
||
|
|
this._from[0] +
|
||
|
|
this._T * (-this._cosPhi * this._rx * e - this._sinPhi * this._ry * t),
|
||
|
|
this._from[1] +
|
||
|
|
this._T * (-this._sinPhi * this._rx * e + this._cosPhi * this._ry * t),
|
||
|
|
],
|
||
|
|
h = [
|
||
|
|
a[0] + this._T * (this._cosPhi * this._rx * i + this._sinPhi * this._ry * n),
|
||
|
|
a[1] + this._T * (this._sinPhi * this._rx * i - this._cosPhi * this._ry * n),
|
||
|
|
];
|
||
|
|
return (
|
||
|
|
(this._theta = s),
|
||
|
|
(this._from = [a[0], a[1]]),
|
||
|
|
this._segIndex++,
|
||
|
|
{ cp1: o, cp2: h, to: a }
|
||
|
|
);
|
||
|
|
}
|
||
|
|
calculateVectorAngle(t, e, s, n) {
|
||
|
|
const i = Math.atan2(e, t),
|
||
|
|
a = Math.atan2(n, s);
|
||
|
|
return a >= i ? a - i : 2 * Math.PI - (i - a);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
class r {
|
||
|
|
constructor(t, e) {
|
||
|
|
(this.sets = t), (this.closed = e);
|
||
|
|
}
|
||
|
|
fit(t) {
|
||
|
|
const e = [];
|
||
|
|
for (const s of this.sets) {
|
||
|
|
const n = s.length;
|
||
|
|
let i = Math.floor(t * n);
|
||
|
|
if (i < 5) {
|
||
|
|
if (n <= 5) continue;
|
||
|
|
i = 5;
|
||
|
|
}
|
||
|
|
e.push(this.reduce(s, i));
|
||
|
|
}
|
||
|
|
let s = "";
|
||
|
|
for (const t of e) {
|
||
|
|
for (let e = 0; e < t.length; e++) {
|
||
|
|
const n = t[e];
|
||
|
|
s += 0 === e ? "M" + n[0] + "," + n[1] : "L" + n[0] + "," + n[1];
|
||
|
|
}
|
||
|
|
this.closed && (s += "z ");
|
||
|
|
}
|
||
|
|
return s;
|
||
|
|
}
|
||
|
|
reduce(t, e) {
|
||
|
|
if (t.length <= e) return t;
|
||
|
|
const n = t.slice(0);
|
||
|
|
for (; n.length > e; ) {
|
||
|
|
let t = -1,
|
||
|
|
e = -1;
|
||
|
|
for (let i = 1; i < n.length - 1; i++) {
|
||
|
|
const a = s([n[i - 1], n[i]]),
|
||
|
|
o = s([n[i], n[i + 1]]),
|
||
|
|
h = s([n[i - 1], n[i + 1]]),
|
||
|
|
r = (a + o + h) / 2,
|
||
|
|
c = Math.sqrt(r * (r - a) * (r - o) * (r - h));
|
||
|
|
(t < 0 || c < t) && ((t = c), (e = i));
|
||
|
|
}
|
||
|
|
if (!(e > 0)) break;
|
||
|
|
n.splice(e, 1);
|
||
|
|
}
|
||
|
|
return n;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function c(t, s) {
|
||
|
|
const n = [0, 0],
|
||
|
|
i = Math.round(s.hachureAngle + 90);
|
||
|
|
i && e(t, n, i);
|
||
|
|
const a = (function (t, e) {
|
||
|
|
const s = [...t];
|
||
|
|
s[0].join(",") !== s[s.length - 1].join(",") && s.push([s[0][0], s[0][1]]);
|
||
|
|
const n = [];
|
||
|
|
if (s && s.length > 2) {
|
||
|
|
let t = e.hachureGap;
|
||
|
|
t < 0 && (t = 4 * e.strokeWidth), (t = Math.max(t, 0.1));
|
||
|
|
const i = [];
|
||
|
|
for (let t = 0; t < s.length - 1; t++) {
|
||
|
|
const e = s[t],
|
||
|
|
n = s[t + 1];
|
||
|
|
if (e[1] !== n[1]) {
|
||
|
|
const t = Math.min(e[1], n[1]);
|
||
|
|
i.push({
|
||
|
|
ymin: t,
|
||
|
|
ymax: Math.max(e[1], n[1]),
|
||
|
|
x: t === e[1] ? e[0] : n[0],
|
||
|
|
islope: (n[0] - e[0]) / (n[1] - e[1]),
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (
|
||
|
|
(i.sort((t, e) =>
|
||
|
|
t.ymin < e.ymin
|
||
|
|
? -1
|
||
|
|
: t.ymin > e.ymin
|
||
|
|
? 1
|
||
|
|
: t.x < e.x
|
||
|
|
? -1
|
||
|
|
: t.x > e.x
|
||
|
|
? 1
|
||
|
|
: t.ymax === e.ymax
|
||
|
|
? 0
|
||
|
|
: (t.ymax - e.ymax) / Math.abs(t.ymax - e.ymax)
|
||
|
|
),
|
||
|
|
!i.length)
|
||
|
|
)
|
||
|
|
return n;
|
||
|
|
let a = [],
|
||
|
|
o = i[0].ymin;
|
||
|
|
for (; a.length || i.length; ) {
|
||
|
|
if (i.length) {
|
||
|
|
let t = -1;
|
||
|
|
for (let e = 0; e < i.length && !(i[e].ymin > o); e++) t = e;
|
||
|
|
i.splice(0, t + 1).forEach((t) => {
|
||
|
|
a.push({ s: o, edge: t });
|
||
|
|
});
|
||
|
|
}
|
||
|
|
if (
|
||
|
|
((a = a.filter((t) => !(t.edge.ymax <= o))),
|
||
|
|
a.sort((t, e) =>
|
||
|
|
t.edge.x === e.edge.x
|
||
|
|
? 0
|
||
|
|
: (t.edge.x - e.edge.x) / Math.abs(t.edge.x - e.edge.x)
|
||
|
|
),
|
||
|
|
a.length > 1)
|
||
|
|
)
|
||
|
|
for (let t = 0; t < a.length; t += 2) {
|
||
|
|
const e = t + 1;
|
||
|
|
if (e >= a.length) break;
|
||
|
|
const s = a[t].edge,
|
||
|
|
i = a[e].edge;
|
||
|
|
n.push([
|
||
|
|
[Math.round(s.x), o],
|
||
|
|
[Math.round(i.x), o],
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
(o += t),
|
||
|
|
a.forEach((e) => {
|
||
|
|
e.edge.x = e.edge.x + t * e.edge.islope;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return n;
|
||
|
|
})(t, s);
|
||
|
|
return (
|
||
|
|
i &&
|
||
|
|
(e(t, n, -i),
|
||
|
|
(function (t, s, n) {
|
||
|
|
const i = [];
|
||
|
|
t.forEach((t) => i.push(...t)), e(i, s, n);
|
||
|
|
})(a, n, -i)),
|
||
|
|
a
|
||
|
|
);
|
||
|
|
}
|
||
|
|
class l {
|
||
|
|
constructor(t) {
|
||
|
|
this.helper = t;
|
||
|
|
}
|
||
|
|
fillPolygon(t, e) {
|
||
|
|
return this._fillPolygon(t, e);
|
||
|
|
}
|
||
|
|
_fillPolygon(t, e, s = !1) {
|
||
|
|
const n = c(t, e);
|
||
|
|
return { type: "fillSketch", ops: this.renderLines(n, e, s) };
|
||
|
|
}
|
||
|
|
renderLines(t, e, s) {
|
||
|
|
let n = [],
|
||
|
|
i = null;
|
||
|
|
for (const a of t)
|
||
|
|
(n = n.concat(this.helper.doubleLineOps(a[0][0], a[0][1], a[1][0], a[1][1], e))),
|
||
|
|
s &&
|
||
|
|
i &&
|
||
|
|
(n = n.concat(this.helper.doubleLineOps(i[0], i[1], a[0][0], a[0][1], e))),
|
||
|
|
(i = a[1]);
|
||
|
|
return n;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
class u extends l {
|
||
|
|
fillPolygon(t, e) {
|
||
|
|
return this._fillPolygon(t, e, !0);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
class p extends l {
|
||
|
|
fillPolygon(t, e) {
|
||
|
|
const s = this._fillPolygon(t, e),
|
||
|
|
n = Object.assign({}, e, { hachureAngle: e.hachureAngle + 90 }),
|
||
|
|
i = this._fillPolygon(t, n);
|
||
|
|
return (s.ops = s.ops.concat(i.ops)), s;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
class d {
|
||
|
|
constructor(t) {
|
||
|
|
this.helper = t;
|
||
|
|
}
|
||
|
|
fillPolygon(t, e) {
|
||
|
|
const s = c(
|
||
|
|
t,
|
||
|
|
(e = Object.assign({}, e, {
|
||
|
|
curveStepCount: 4,
|
||
|
|
hachureAngle: 0,
|
||
|
|
roughness: 1,
|
||
|
|
}))
|
||
|
|
);
|
||
|
|
return this.dotsOnLines(s, e);
|
||
|
|
}
|
||
|
|
dotsOnLines(t, e) {
|
||
|
|
let n = [],
|
||
|
|
i = e.hachureGap;
|
||
|
|
i < 0 && (i = 4 * e.strokeWidth), (i = Math.max(i, 0.1));
|
||
|
|
let a = e.fillWeight;
|
||
|
|
a < 0 && (a = e.strokeWidth / 2);
|
||
|
|
for (const o of t) {
|
||
|
|
const t = s(o) / i,
|
||
|
|
h = Math.ceil(t) - 1,
|
||
|
|
r = Math.atan((o[1][1] - o[0][1]) / (o[1][0] - o[0][0]));
|
||
|
|
for (let t = 0; t < h; t++) {
|
||
|
|
const s = i * (t + 1),
|
||
|
|
h = s * Math.sin(r),
|
||
|
|
c = s * Math.cos(r),
|
||
|
|
l = [o[0][0] - c, o[0][1] + h],
|
||
|
|
u = this.helper.randOffsetWithRange(l[0] - i / 4, l[0] + i / 4, e),
|
||
|
|
p = this.helper.randOffsetWithRange(l[1] - i / 4, l[1] + i / 4, e),
|
||
|
|
d = this.helper.ellipse(u, p, a, a, e);
|
||
|
|
n = n.concat(d.ops);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return { type: "fillSketch", ops: n };
|
||
|
|
}
|
||
|
|
}
|
||
|
|
class f {
|
||
|
|
constructor(t) {
|
||
|
|
this.helper = t;
|
||
|
|
}
|
||
|
|
fillPolygon(t, e) {
|
||
|
|
const s = c(t, e);
|
||
|
|
return { type: "fillSketch", ops: this.dashedLine(s, e) };
|
||
|
|
}
|
||
|
|
dashedLine(t, e) {
|
||
|
|
const n =
|
||
|
|
e.dashOffset < 0
|
||
|
|
? e.hachureGap < 0
|
||
|
|
? 4 * e.strokeWidth
|
||
|
|
: e.hachureGap
|
||
|
|
: e.dashOffset,
|
||
|
|
i =
|
||
|
|
e.dashGap < 0 ? (e.hachureGap < 0 ? 4 * e.strokeWidth : e.hachureGap) : e.dashGap;
|
||
|
|
let a = [];
|
||
|
|
return (
|
||
|
|
t.forEach((t) => {
|
||
|
|
const o = s(t),
|
||
|
|
h = Math.floor(o / (n + i)),
|
||
|
|
r = (o + i - h * (n + i)) / 2;
|
||
|
|
let c = t[0],
|
||
|
|
l = t[1];
|
||
|
|
c[0] > l[0] && ((c = t[1]), (l = t[0]));
|
||
|
|
const u = Math.atan((l[1] - c[1]) / (l[0] - c[0]));
|
||
|
|
for (let t = 0; t < h; t++) {
|
||
|
|
const s = t * (n + i),
|
||
|
|
o = s + n,
|
||
|
|
h = [
|
||
|
|
c[0] + s * Math.cos(u) + r * Math.cos(u),
|
||
|
|
c[1] + s * Math.sin(u) + r * Math.sin(u),
|
||
|
|
],
|
||
|
|
l = [
|
||
|
|
c[0] + o * Math.cos(u) + r * Math.cos(u),
|
||
|
|
c[1] + o * Math.sin(u) + r * Math.sin(u),
|
||
|
|
];
|
||
|
|
a = a.concat(this.helper.doubleLineOps(h[0], h[1], l[0], l[1], e));
|
||
|
|
}
|
||
|
|
}),
|
||
|
|
a
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
class g {
|
||
|
|
constructor(t) {
|
||
|
|
this.helper = t;
|
||
|
|
}
|
||
|
|
fillPolygon(t, e) {
|
||
|
|
const s = e.hachureGap < 0 ? 4 * e.strokeWidth : e.hachureGap,
|
||
|
|
n = e.zigzagOffset < 0 ? s : e.zigzagOffset,
|
||
|
|
i = c(t, (e = Object.assign({}, e, { hachureGap: s + n })));
|
||
|
|
return { type: "fillSketch", ops: this.zigzagLines(i, n, e) };
|
||
|
|
}
|
||
|
|
zigzagLines(t, e, n) {
|
||
|
|
let i = [];
|
||
|
|
return (
|
||
|
|
t.forEach((t) => {
|
||
|
|
const a = s(t),
|
||
|
|
o = Math.round(a / (2 * e));
|
||
|
|
let h = t[0],
|
||
|
|
r = t[1];
|
||
|
|
h[0] > r[0] && ((h = t[1]), (r = t[0]));
|
||
|
|
const c = Math.atan((r[1] - h[1]) / (r[0] - h[0]));
|
||
|
|
for (let t = 0; t < o; t++) {
|
||
|
|
const s = 2 * t * e,
|
||
|
|
a = 2 * (t + 1) * e,
|
||
|
|
o = Math.sqrt(2 * Math.pow(e, 2)),
|
||
|
|
r = [h[0] + s * Math.cos(c), h[1] + s * Math.sin(c)],
|
||
|
|
l = [h[0] + a * Math.cos(c), h[1] + a * Math.sin(c)],
|
||
|
|
u = [
|
||
|
|
r[0] + o * Math.cos(c + Math.PI / 4),
|
||
|
|
r[1] + o * Math.sin(c + Math.PI / 4),
|
||
|
|
];
|
||
|
|
(i = i.concat(this.helper.doubleLineOps(r[0], r[1], u[0], u[1], n))),
|
||
|
|
(i = i.concat(this.helper.doubleLineOps(u[0], u[1], l[0], l[1], n)));
|
||
|
|
}
|
||
|
|
}),
|
||
|
|
i
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
const y = {};
|
||
|
|
class _ {
|
||
|
|
constructor(t) {
|
||
|
|
this.seed = t;
|
||
|
|
}
|
||
|
|
next() {
|
||
|
|
return this.seed
|
||
|
|
? ((Math.pow(2, 31) - 1) & (this.seed = Math.imul(48271, this.seed))) /
|
||
|
|
Math.pow(2, 31)
|
||
|
|
: Math.random();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
const M = {
|
||
|
|
randOffset: function (t, e) {
|
||
|
|
return z(t, e);
|
||
|
|
},
|
||
|
|
randOffsetWithRange: function (t, e, s) {
|
||
|
|
return C(t, e, s);
|
||
|
|
},
|
||
|
|
ellipse: function (t, e, s, n, i) {
|
||
|
|
const a = P(s, n, i);
|
||
|
|
return w(t, e, i, a).opset;
|
||
|
|
},
|
||
|
|
doubleLineOps: function (t, e, s, n, i) {
|
||
|
|
return A(t, e, s, n, i);
|
||
|
|
},
|
||
|
|
};
|
||
|
|
function x(t, e, s, n, i) {
|
||
|
|
return { type: "path", ops: A(t, e, s, n, i) };
|
||
|
|
}
|
||
|
|
function m(t, e, s) {
|
||
|
|
const n = (t || []).length;
|
||
|
|
if (n > 2) {
|
||
|
|
let i = [];
|
||
|
|
for (let e = 0; e < n - 1; e++)
|
||
|
|
i = i.concat(A(t[e][0], t[e][1], t[e + 1][0], t[e + 1][1], s));
|
||
|
|
return (
|
||
|
|
e && (i = i.concat(A(t[n - 1][0], t[n - 1][1], t[0][0], t[0][1], s))),
|
||
|
|
{ type: "path", ops: i }
|
||
|
|
);
|
||
|
|
}
|
||
|
|
return 2 === n ? x(t[0][0], t[0][1], t[1][0], t[1][1], s) : { type: "path", ops: [] };
|
||
|
|
}
|
||
|
|
function k(t, e, s, n, i) {
|
||
|
|
return (function (t, e) {
|
||
|
|
return m(t, !0, e);
|
||
|
|
})(
|
||
|
|
[
|
||
|
|
[t, e],
|
||
|
|
[t + s, e],
|
||
|
|
[t + s, e + n],
|
||
|
|
[t, e + n],
|
||
|
|
],
|
||
|
|
i
|
||
|
|
);
|
||
|
|
}
|
||
|
|
function b(t, e) {
|
||
|
|
const s = W(t, 1 * (1 + 0.2 * e.roughness), e),
|
||
|
|
n = W(t, 1.5 * (1 + 0.22 * e.roughness), e);
|
||
|
|
return { type: "path", ops: s.concat(n) };
|
||
|
|
}
|
||
|
|
function P(t, e, s) {
|
||
|
|
const n = Math.sqrt(
|
||
|
|
2 * Math.PI * Math.sqrt((Math.pow(t / 2, 2) + Math.pow(e / 2, 2)) / 2)
|
||
|
|
),
|
||
|
|
i = Math.max(s.curveStepCount, (s.curveStepCount / Math.sqrt(200)) * n),
|
||
|
|
a = (2 * Math.PI) / i;
|
||
|
|
let o = Math.abs(t / 2),
|
||
|
|
h = Math.abs(e / 2);
|
||
|
|
const r = 1 - s.curveFitting;
|
||
|
|
return (o += z(o * r, s)), (h += z(h * r, s)), { increment: a, rx: o, ry: h };
|
||
|
|
}
|
||
|
|
function w(t, e, s, n) {
|
||
|
|
const [i, a] = D(
|
||
|
|
n.increment,
|
||
|
|
t,
|
||
|
|
e,
|
||
|
|
n.rx,
|
||
|
|
n.ry,
|
||
|
|
1,
|
||
|
|
n.increment * C(0.1, C(0.4, 1, s), s),
|
||
|
|
s
|
||
|
|
),
|
||
|
|
[o] = D(n.increment, t, e, n.rx, n.ry, 1.5, 0, s),
|
||
|
|
h = R(i, null, s),
|
||
|
|
r = R(o, null, s);
|
||
|
|
return { estimatedPoints: a, opset: { type: "path", ops: h.concat(r) } };
|
||
|
|
}
|
||
|
|
function v(t, e, s, n, i, a, o, h, r) {
|
||
|
|
const c = t,
|
||
|
|
l = e;
|
||
|
|
let u = Math.abs(s / 2),
|
||
|
|
p = Math.abs(n / 2);
|
||
|
|
(u += z(0.01 * u, r)), (p += z(0.01 * p, r));
|
||
|
|
let d = i,
|
||
|
|
f = a;
|
||
|
|
for (; d < 0; ) (d += 2 * Math.PI), (f += 2 * Math.PI);
|
||
|
|
f - d > 2 * Math.PI && ((d = 0), (f = 2 * Math.PI));
|
||
|
|
const g = (2 * Math.PI) / r.curveStepCount,
|
||
|
|
y = Math.min(g / 2, (f - d) / 2),
|
||
|
|
_ = I(y, c, l, u, p, d, f, 1, r),
|
||
|
|
M = I(y, c, l, u, p, d, f, 1.5, r);
|
||
|
|
let x = _.concat(M);
|
||
|
|
return (
|
||
|
|
o &&
|
||
|
|
(h
|
||
|
|
? ((x = x.concat(A(c, l, c + u * Math.cos(d), l + p * Math.sin(d), r))),
|
||
|
|
(x = x.concat(A(c, l, c + u * Math.cos(f), l + p * Math.sin(f), r))))
|
||
|
|
: (x.push({ op: "lineTo", data: [c, l] }),
|
||
|
|
x.push({
|
||
|
|
op: "lineTo",
|
||
|
|
data: [c + u * Math.cos(d), l + p * Math.sin(d)],
|
||
|
|
}))),
|
||
|
|
{ type: "path", ops: x }
|
||
|
|
);
|
||
|
|
}
|
||
|
|
function S(t, e) {
|
||
|
|
const s = [];
|
||
|
|
if (t.length) {
|
||
|
|
const n = e.maxRandomnessOffset || 0,
|
||
|
|
i = t.length;
|
||
|
|
if (i > 2) {
|
||
|
|
s.push({ op: "move", data: [t[0][0] + z(n, e), t[0][1] + z(n, e)] });
|
||
|
|
for (let a = 1; a < i; a++)
|
||
|
|
s.push({ op: "lineTo", data: [t[a][0] + z(n, e), t[a][1] + z(n, e)] });
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return { type: "fillPath", ops: s };
|
||
|
|
}
|
||
|
|
function O(t, e) {
|
||
|
|
return (function (t, e) {
|
||
|
|
let s = t.fillStyle || "hachure";
|
||
|
|
if (!y[s])
|
||
|
|
switch (s) {
|
||
|
|
case "zigzag":
|
||
|
|
y[s] || (y[s] = new u(e));
|
||
|
|
break;
|
||
|
|
case "cross-hatch":
|
||
|
|
y[s] || (y[s] = new p(e));
|
||
|
|
break;
|
||
|
|
case "dots":
|
||
|
|
y[s] || (y[s] = new d(e));
|
||
|
|
break;
|
||
|
|
case "dashed":
|
||
|
|
y[s] || (y[s] = new f(e));
|
||
|
|
break;
|
||
|
|
case "zigzag-line":
|
||
|
|
y[s] || (y[s] = new g(e));
|
||
|
|
break;
|
||
|
|
case "hachure":
|
||
|
|
default:
|
||
|
|
(s = "hachure"), y[s] || (y[s] = new l(e));
|
||
|
|
}
|
||
|
|
return y[s];
|
||
|
|
})(e, M).fillPolygon(t, e);
|
||
|
|
}
|
||
|
|
function T(t) {
|
||
|
|
return t.randomizer || (t.randomizer = new _(t.seed || 0)), t.randomizer.next();
|
||
|
|
}
|
||
|
|
function C(t, e, s) {
|
||
|
|
return s.roughness * s.roughnessGain * (T(s) * (e - t) + t);
|
||
|
|
}
|
||
|
|
function z(t, e) {
|
||
|
|
return C(-t, t, e);
|
||
|
|
}
|
||
|
|
function A(t, e, s, n, i) {
|
||
|
|
const a = E(t, e, s, n, i, !0, !1),
|
||
|
|
o = E(t, e, s, n, i, !0, !0);
|
||
|
|
return a.concat(o);
|
||
|
|
}
|
||
|
|
function E(t, e, s, n, i, a, o) {
|
||
|
|
const h = Math.pow(t - s, 2) + Math.pow(e - n, 2),
|
||
|
|
r = Math.sqrt(h);
|
||
|
|
i.roughnessGain = r < 200 ? 1 : r > 500 ? 0.4 : -0.0016668 * r + 1.233334;
|
||
|
|
let c = i.maxRandomnessOffset || 0;
|
||
|
|
c * c * 100 > h && (c = r / 10);
|
||
|
|
const l = c / 2,
|
||
|
|
u = 0.2 + 0.2 * T(i);
|
||
|
|
let p = (i.bowing * i.maxRandomnessOffset * (n - e)) / 200,
|
||
|
|
d = (i.bowing * i.maxRandomnessOffset * (t - s)) / 200;
|
||
|
|
(p = z(p, i)), (d = z(d, i));
|
||
|
|
const f = [],
|
||
|
|
g = () => z(l, i),
|
||
|
|
y = () => z(c, i);
|
||
|
|
return (
|
||
|
|
a &&
|
||
|
|
(o
|
||
|
|
? f.push({ op: "move", data: [t + g(), e + g()] })
|
||
|
|
: f.push({ op: "move", data: [t + z(c, i), e + z(c, i)] })),
|
||
|
|
o
|
||
|
|
? f.push({
|
||
|
|
op: "bcurveTo",
|
||
|
|
data: [
|
||
|
|
p + t + (s - t) * u + g(),
|
||
|
|
d + e + (n - e) * u + g(),
|
||
|
|
p + t + 2 * (s - t) * u + g(),
|
||
|
|
d + e + 2 * (n - e) * u + g(),
|
||
|
|
s + g(),
|
||
|
|
n + g(),
|
||
|
|
],
|
||
|
|
})
|
||
|
|
: f.push({
|
||
|
|
op: "bcurveTo",
|
||
|
|
data: [
|
||
|
|
p + t + (s - t) * u + y(),
|
||
|
|
d + e + (n - e) * u + y(),
|
||
|
|
p + t + 2 * (s - t) * u + y(),
|
||
|
|
d + e + 2 * (n - e) * u + y(),
|
||
|
|
s + y(),
|
||
|
|
n + y(),
|
||
|
|
],
|
||
|
|
}),
|
||
|
|
f
|
||
|
|
);
|
||
|
|
}
|
||
|
|
function W(t, e, s) {
|
||
|
|
const n = [];
|
||
|
|
n.push([t[0][0] + z(e, s), t[0][1] + z(e, s)]),
|
||
|
|
n.push([t[0][0] + z(e, s), t[0][1] + z(e, s)]);
|
||
|
|
for (let i = 1; i < t.length; i++)
|
||
|
|
n.push([t[i][0] + z(e, s), t[i][1] + z(e, s)]),
|
||
|
|
i === t.length - 1 && n.push([t[i][0] + z(e, s), t[i][1] + z(e, s)]);
|
||
|
|
return R(n, null, s);
|
||
|
|
}
|
||
|
|
function R(t, e, s) {
|
||
|
|
const n = t.length;
|
||
|
|
let i = [];
|
||
|
|
if (n > 3) {
|
||
|
|
const a = [],
|
||
|
|
o = 1 - s.curveTightness;
|
||
|
|
i.push({ op: "move", data: [t[1][0], t[1][1]] });
|
||
|
|
for (let e = 1; e + 2 < n; e++) {
|
||
|
|
const s = t[e];
|
||
|
|
(a[0] = [s[0], s[1]]),
|
||
|
|
(a[1] = [
|
||
|
|
s[0] + (o * t[e + 1][0] - o * t[e - 1][0]) / 6,
|
||
|
|
s[1] + (o * t[e + 1][1] - o * t[e - 1][1]) / 6,
|
||
|
|
]),
|
||
|
|
(a[2] = [
|
||
|
|
t[e + 1][0] + (o * t[e][0] - o * t[e + 2][0]) / 6,
|
||
|
|
t[e + 1][1] + (o * t[e][1] - o * t[e + 2][1]) / 6,
|
||
|
|
]),
|
||
|
|
(a[3] = [t[e + 1][0], t[e + 1][1]]),
|
||
|
|
i.push({
|
||
|
|
op: "bcurveTo",
|
||
|
|
data: [a[1][0], a[1][1], a[2][0], a[2][1], a[3][0], a[3][1]],
|
||
|
|
});
|
||
|
|
}
|
||
|
|
if (e && 2 === e.length) {
|
||
|
|
const t = s.maxRandomnessOffset;
|
||
|
|
i.push({ op: "lineTo", data: [e[0] + z(t, s), e[1] + z(t, s)] });
|
||
|
|
}
|
||
|
|
} else
|
||
|
|
3 === n
|
||
|
|
? (i.push({ op: "move", data: [t[1][0], t[1][1]] }),
|
||
|
|
i.push({
|
||
|
|
op: "bcurveTo",
|
||
|
|
data: [t[1][0], t[1][1], t[2][0], t[2][1], t[2][0], t[2][1]],
|
||
|
|
}))
|
||
|
|
: 2 === n && (i = i.concat(A(t[0][0], t[0][1], t[1][0], t[1][1], s)));
|
||
|
|
return i;
|
||
|
|
}
|
||
|
|
function D(t, e, s, n, i, a, o, h) {
|
||
|
|
const r = [],
|
||
|
|
c = [],
|
||
|
|
l = z(0.5, h) - Math.PI / 2;
|
||
|
|
c.push([
|
||
|
|
z(a, h) + e + 0.9 * n * Math.cos(l - t),
|
||
|
|
z(a, h) + s + 0.9 * i * Math.sin(l - t),
|
||
|
|
]);
|
||
|
|
for (let o = l; o < 2 * Math.PI + l - 0.01; o += t) {
|
||
|
|
const t = [z(a, h) + e + n * Math.cos(o), z(a, h) + s + i * Math.sin(o)];
|
||
|
|
r.push(t), c.push(t);
|
||
|
|
}
|
||
|
|
return (
|
||
|
|
c.push([
|
||
|
|
z(a, h) + e + n * Math.cos(l + 2 * Math.PI + 0.5 * o),
|
||
|
|
z(a, h) + s + i * Math.sin(l + 2 * Math.PI + 0.5 * o),
|
||
|
|
]),
|
||
|
|
c.push([
|
||
|
|
z(a, h) + e + 0.98 * n * Math.cos(l + o),
|
||
|
|
z(a, h) + s + 0.98 * i * Math.sin(l + o),
|
||
|
|
]),
|
||
|
|
c.push([
|
||
|
|
z(a, h) + e + 0.9 * n * Math.cos(l + 0.5 * o),
|
||
|
|
z(a, h) + s + 0.9 * i * Math.sin(l + 0.5 * o),
|
||
|
|
]),
|
||
|
|
[c, r]
|
||
|
|
);
|
||
|
|
}
|
||
|
|
function I(t, e, s, n, i, a, o, h, r) {
|
||
|
|
const c = a + z(0.1, r),
|
||
|
|
l = [];
|
||
|
|
l.push([
|
||
|
|
z(h, r) + e + 0.9 * n * Math.cos(c - t),
|
||
|
|
z(h, r) + s + 0.9 * i * Math.sin(c - t),
|
||
|
|
]);
|
||
|
|
for (let a = c; a <= o; a += t)
|
||
|
|
l.push([z(h, r) + e + n * Math.cos(a), z(h, r) + s + i * Math.sin(a)]);
|
||
|
|
return (
|
||
|
|
l.push([e + n * Math.cos(o), s + i * Math.sin(o)]),
|
||
|
|
l.push([e + n * Math.cos(o), s + i * Math.sin(o)]),
|
||
|
|
R(l, null, r)
|
||
|
|
);
|
||
|
|
}
|
||
|
|
function q(t, e, s, n, i, a, o, h) {
|
||
|
|
const r = [],
|
||
|
|
c = [h.maxRandomnessOffset || 1, (h.maxRandomnessOffset || 1) + 0.5];
|
||
|
|
let l = [0, 0];
|
||
|
|
for (let u = 0; u < 2; u++)
|
||
|
|
0 === u
|
||
|
|
? r.push({ op: "move", data: [o.x, o.y] })
|
||
|
|
: r.push({ op: "move", data: [o.x + z(c[0], h), o.y + z(c[0], h)] }),
|
||
|
|
(l = [i + z(c[u], h), a + z(c[u], h)]),
|
||
|
|
r.push({
|
||
|
|
op: "bcurveTo",
|
||
|
|
data: [
|
||
|
|
t + z(c[u], h),
|
||
|
|
e + z(c[u], h),
|
||
|
|
s + z(c[u], h),
|
||
|
|
n + z(c[u], h),
|
||
|
|
l[0],
|
||
|
|
l[1],
|
||
|
|
],
|
||
|
|
});
|
||
|
|
return o.setPosition(l[0], l[1]), r;
|
||
|
|
}
|
||
|
|
function $(t, e, s, n) {
|
||
|
|
let i = [];
|
||
|
|
switch (e.key) {
|
||
|
|
case "M":
|
||
|
|
case "m": {
|
||
|
|
const s = "m" === e.key;
|
||
|
|
if (e.data.length >= 2) {
|
||
|
|
let a = +e.data[0],
|
||
|
|
o = +e.data[1];
|
||
|
|
s && ((a += t.x), (o += t.y));
|
||
|
|
const h = 1 * (n.maxRandomnessOffset || 0);
|
||
|
|
(a += z(h, n)),
|
||
|
|
(o += z(h, n)),
|
||
|
|
t.setPosition(a, o),
|
||
|
|
i.push({ op: "move", data: [a, o] });
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case "L":
|
||
|
|
case "l": {
|
||
|
|
const s = "l" === e.key;
|
||
|
|
if (e.data.length >= 2) {
|
||
|
|
let a = +e.data[0],
|
||
|
|
o = +e.data[1];
|
||
|
|
s && ((a += t.x), (o += t.y)),
|
||
|
|
(i = i.concat(A(t.x, t.y, a, o, n))),
|
||
|
|
t.setPosition(a, o);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case "H":
|
||
|
|
case "h": {
|
||
|
|
const s = "h" === e.key;
|
||
|
|
if (e.data.length) {
|
||
|
|
let a = +e.data[0];
|
||
|
|
s && (a += t.x), (i = i.concat(A(t.x, t.y, a, t.y, n))), t.setPosition(a, t.y);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case "V":
|
||
|
|
case "v": {
|
||
|
|
const s = "v" === e.key;
|
||
|
|
if (e.data.length) {
|
||
|
|
let a = +e.data[0];
|
||
|
|
s && (a += t.y), (i = i.concat(A(t.x, t.y, t.x, a, n))), t.setPosition(t.x, a);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case "Z":
|
||
|
|
case "z":
|
||
|
|
t.first &&
|
||
|
|
((i = i.concat(A(t.x, t.y, t.first[0], t.first[1], n))),
|
||
|
|
t.setPosition(t.first[0], t.first[1]),
|
||
|
|
(t.first = null));
|
||
|
|
break;
|
||
|
|
case "C":
|
||
|
|
case "c": {
|
||
|
|
const s = "c" === e.key;
|
||
|
|
if (e.data.length >= 6) {
|
||
|
|
let a = +e.data[0],
|
||
|
|
o = +e.data[1],
|
||
|
|
h = +e.data[2],
|
||
|
|
r = +e.data[3],
|
||
|
|
c = +e.data[4],
|
||
|
|
l = +e.data[5];
|
||
|
|
s && ((a += t.x), (h += t.x), (c += t.x), (o += t.y), (r += t.y), (l += t.y));
|
||
|
|
const u = q(a, o, h, r, c, l, t, n);
|
||
|
|
(i = i.concat(u)), (t.bezierReflectionPoint = [c + (c - h), l + (l - r)]);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case "S":
|
||
|
|
case "s": {
|
||
|
|
const a = "s" === e.key;
|
||
|
|
if (e.data.length >= 4) {
|
||
|
|
let o = +e.data[0],
|
||
|
|
h = +e.data[1],
|
||
|
|
r = +e.data[2],
|
||
|
|
c = +e.data[3];
|
||
|
|
a && ((o += t.x), (r += t.x), (h += t.y), (c += t.y));
|
||
|
|
let l = o,
|
||
|
|
u = h;
|
||
|
|
const p = s ? s.key : "";
|
||
|
|
let d = null;
|
||
|
|
("c" !== p && "C" !== p && "s" !== p && "S" !== p) ||
|
||
|
|
(d = t.bezierReflectionPoint),
|
||
|
|
d && ((l = d[0]), (u = d[1]));
|
||
|
|
const f = q(l, u, o, h, r, c, t, n);
|
||
|
|
(i = i.concat(f)), (t.bezierReflectionPoint = [r + (r - o), c + (c - h)]);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case "Q":
|
||
|
|
case "q": {
|
||
|
|
const s = "q" === e.key;
|
||
|
|
if (e.data.length >= 4) {
|
||
|
|
let a = +e.data[0],
|
||
|
|
o = +e.data[1],
|
||
|
|
h = +e.data[2],
|
||
|
|
r = +e.data[3];
|
||
|
|
s && ((a += t.x), (h += t.x), (o += t.y), (r += t.y));
|
||
|
|
const c = 1 * (1 + 0.2 * n.roughness),
|
||
|
|
l = 1.5 * (1 + 0.22 * n.roughness);
|
||
|
|
i.push({ op: "move", data: [t.x + z(c, n), t.y + z(c, n)] });
|
||
|
|
let u = [h + z(c, n), r + z(c, n)];
|
||
|
|
i.push({
|
||
|
|
op: "qcurveTo",
|
||
|
|
data: [a + z(c, n), o + z(c, n), u[0], u[1]],
|
||
|
|
}),
|
||
|
|
i.push({ op: "move", data: [t.x + z(l, n), t.y + z(l, n)] }),
|
||
|
|
(u = [h + z(l, n), r + z(l, n)]),
|
||
|
|
i.push({
|
||
|
|
op: "qcurveTo",
|
||
|
|
data: [a + z(l, n), o + z(l, n), u[0], u[1]],
|
||
|
|
}),
|
||
|
|
t.setPosition(u[0], u[1]),
|
||
|
|
(t.quadReflectionPoint = [h + (h - a), r + (r - o)]);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case "T":
|
||
|
|
case "t": {
|
||
|
|
const a = "t" === e.key;
|
||
|
|
if (e.data.length >= 2) {
|
||
|
|
let o = +e.data[0],
|
||
|
|
h = +e.data[1];
|
||
|
|
a && ((o += t.x), (h += t.y));
|
||
|
|
let r = o,
|
||
|
|
c = h;
|
||
|
|
const l = s ? s.key : "";
|
||
|
|
let u = null;
|
||
|
|
("q" !== l && "Q" !== l && "t" !== l && "T" !== l) || (u = t.quadReflectionPoint),
|
||
|
|
u && ((r = u[0]), (c = u[1]));
|
||
|
|
const p = 1 * (1 + 0.2 * n.roughness),
|
||
|
|
d = 1.5 * (1 + 0.22 * n.roughness);
|
||
|
|
i.push({ op: "move", data: [t.x + z(p, n), t.y + z(p, n)] });
|
||
|
|
let f = [o + z(p, n), h + z(p, n)];
|
||
|
|
i.push({
|
||
|
|
op: "qcurveTo",
|
||
|
|
data: [r + z(p, n), c + z(p, n), f[0], f[1]],
|
||
|
|
}),
|
||
|
|
i.push({ op: "move", data: [t.x + z(d, n), t.y + z(d, n)] }),
|
||
|
|
(f = [o + z(d, n), h + z(d, n)]),
|
||
|
|
i.push({
|
||
|
|
op: "qcurveTo",
|
||
|
|
data: [r + z(d, n), c + z(d, n), f[0], f[1]],
|
||
|
|
}),
|
||
|
|
t.setPosition(f[0], f[1]),
|
||
|
|
(t.quadReflectionPoint = [o + (o - r), h + (h - c)]);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case "A":
|
||
|
|
case "a": {
|
||
|
|
const s = "a" === e.key;
|
||
|
|
if (e.data.length >= 7) {
|
||
|
|
const a = +e.data[0],
|
||
|
|
o = +e.data[1],
|
||
|
|
r = +e.data[2],
|
||
|
|
c = +e.data[3],
|
||
|
|
l = +e.data[4];
|
||
|
|
let u = +e.data[5],
|
||
|
|
p = +e.data[6];
|
||
|
|
if ((s && ((u += t.x), (p += t.y)), u === t.x && p === t.y)) break;
|
||
|
|
if (0 === a || 0 === o) (i = i.concat(A(t.x, t.y, u, p, n))), t.setPosition(u, p);
|
||
|
|
else
|
||
|
|
for (let e = 0; e < 1; e++) {
|
||
|
|
const e = new h([t.x, t.y], [u, p], [a, o], r, !!c, !!l);
|
||
|
|
let s = e.getNextSegment();
|
||
|
|
for (; s; ) {
|
||
|
|
const a = q(s.cp1[0], s.cp1[1], s.cp2[0], s.cp2[1], s.to[0], s.to[1], t, n);
|
||
|
|
(i = i.concat(a)), (s = e.getNextSegment());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return i;
|
||
|
|
}
|
||
|
|
const N = "undefined" != typeof self,
|
||
|
|
L = "none";
|
||
|
|
class B {
|
||
|
|
constructor(t, e) {
|
||
|
|
(this.defaultOptions = {
|
||
|
|
maxRandomnessOffset: 2,
|
||
|
|
roughness: 1,
|
||
|
|
bowing: 1,
|
||
|
|
stroke: "#000",
|
||
|
|
strokeWidth: 1,
|
||
|
|
curveTightness: 0,
|
||
|
|
curveFitting: 0.95,
|
||
|
|
curveStepCount: 9,
|
||
|
|
fillStyle: "hachure",
|
||
|
|
fillWeight: -1,
|
||
|
|
hachureAngle: -41,
|
||
|
|
hachureGap: -1,
|
||
|
|
dashOffset: -1,
|
||
|
|
dashGap: -1,
|
||
|
|
zigzagOffset: -1,
|
||
|
|
seed: 0,
|
||
|
|
roughnessGain: 1,
|
||
|
|
}),
|
||
|
|
(this.config = t || {}),
|
||
|
|
(this.surface = e),
|
||
|
|
this.config.options && (this.defaultOptions = this._options(this.config.options));
|
||
|
|
}
|
||
|
|
static newSeed() {
|
||
|
|
return Math.floor(Math.random() * Math.pow(2, 31));
|
||
|
|
}
|
||
|
|
_options(t) {
|
||
|
|
return t ? Object.assign({}, this.defaultOptions, t) : this.defaultOptions;
|
||
|
|
}
|
||
|
|
_drawable(t, e, s) {
|
||
|
|
return { shape: t, sets: e || [], options: s || this.defaultOptions };
|
||
|
|
}
|
||
|
|
line(t, e, s, n, i) {
|
||
|
|
const a = this._options(i);
|
||
|
|
return this._drawable("line", [x(t, e, s, n, a)], a);
|
||
|
|
}
|
||
|
|
rectangle(t, e, s, n, i) {
|
||
|
|
const a = this._options(i),
|
||
|
|
o = [],
|
||
|
|
h = k(t, e, s, n, a);
|
||
|
|
if (a.fill) {
|
||
|
|
const i = [
|
||
|
|
[t, e],
|
||
|
|
[t + s, e],
|
||
|
|
[t + s, e + n],
|
||
|
|
[t, e + n],
|
||
|
|
];
|
||
|
|
"solid" === a.fillStyle ? o.push(S(i, a)) : o.push(O(i, a));
|
||
|
|
}
|
||
|
|
return a.stroke !== L && o.push(h), this._drawable("rectangle", o, a);
|
||
|
|
}
|
||
|
|
ellipse(t, e, s, n, i) {
|
||
|
|
const a = this._options(i),
|
||
|
|
o = [],
|
||
|
|
h = P(s, n, a),
|
||
|
|
r = w(t, e, a, h);
|
||
|
|
if (a.fill)
|
||
|
|
if ("solid" === a.fillStyle) {
|
||
|
|
const s = w(t, e, a, h).opset;
|
||
|
|
(s.type = "fillPath"), o.push(s);
|
||
|
|
} else o.push(O(r.estimatedPoints, a));
|
||
|
|
return a.stroke !== L && o.push(r.opset), this._drawable("ellipse", o, a);
|
||
|
|
}
|
||
|
|
circle(t, e, s, n) {
|
||
|
|
const i = this.ellipse(t, e, s, s, n);
|
||
|
|
return (i.shape = "circle"), i;
|
||
|
|
}
|
||
|
|
linearPath(t, e) {
|
||
|
|
const s = this._options(e);
|
||
|
|
return this._drawable("linearPath", [m(t, !1, s)], s);
|
||
|
|
}
|
||
|
|
arc(t, e, s, n, i, a, o = !1, h) {
|
||
|
|
const r = this._options(h),
|
||
|
|
c = [],
|
||
|
|
l = v(t, e, s, n, i, a, o, !0, r);
|
||
|
|
if (o && r.fill)
|
||
|
|
if ("solid" === r.fillStyle) {
|
||
|
|
const o = v(t, e, s, n, i, a, !0, !1, r);
|
||
|
|
(o.type = "fillPath"), c.push(o);
|
||
|
|
} else
|
||
|
|
c.push(
|
||
|
|
(function (t, e, s, n, i, a, o) {
|
||
|
|
const h = t,
|
||
|
|
r = e;
|
||
|
|
let c = Math.abs(s / 2),
|
||
|
|
l = Math.abs(n / 2);
|
||
|
|
(c += z(0.01 * c, o)), (l += z(0.01 * l, o));
|
||
|
|
let u = i,
|
||
|
|
p = a;
|
||
|
|
for (; u < 0; ) (u += 2 * Math.PI), (p += 2 * Math.PI);
|
||
|
|
p - u > 2 * Math.PI && ((u = 0), (p = 2 * Math.PI));
|
||
|
|
const d = (p - u) / o.curveStepCount,
|
||
|
|
f = [];
|
||
|
|
for (let t = u; t <= p; t += d)
|
||
|
|
f.push([h + c * Math.cos(t), r + l * Math.sin(t)]);
|
||
|
|
return (
|
||
|
|
f.push([h + c * Math.cos(p), r + l * Math.sin(p)]), f.push([h, r]), O(f, o)
|
||
|
|
);
|
||
|
|
})(t, e, s, n, i, a, r)
|
||
|
|
);
|
||
|
|
return r.stroke !== L && c.push(l), this._drawable("arc", c, r);
|
||
|
|
}
|
||
|
|
curve(t, e) {
|
||
|
|
const s = this._options(e);
|
||
|
|
return this._drawable("curve", [b(t, s)], s);
|
||
|
|
}
|
||
|
|
polygon(t, e) {
|
||
|
|
const s = this._options(e),
|
||
|
|
n = [],
|
||
|
|
i = m(t, !0, s);
|
||
|
|
return (
|
||
|
|
s.fill && ("solid" === s.fillStyle ? n.push(S(t, s)) : n.push(O(t, s))),
|
||
|
|
s.stroke !== L && n.push(i),
|
||
|
|
this._drawable("polygon", n, s)
|
||
|
|
);
|
||
|
|
}
|
||
|
|
path(t, e) {
|
||
|
|
const s = this._options(e),
|
||
|
|
n = [];
|
||
|
|
if (!t) return this._drawable("path", n, s);
|
||
|
|
const i = (function (t, e) {
|
||
|
|
t = (t || "").replace(/\n/g, " ").replace(/(-\s)/g, "-").replace("/(ss)/g", " ");
|
||
|
|
let s = new o(t);
|
||
|
|
if (e.simplification) {
|
||
|
|
const t = new r(s.linearPoints, s.closed).fit(e.simplification);
|
||
|
|
s = new o(t);
|
||
|
|
}
|
||
|
|
let n = [];
|
||
|
|
const i = s.segments || [];
|
||
|
|
for (let t = 0; t < i.length; t++) {
|
||
|
|
const a = $(s, i[t], t > 0 ? i[t - 1] : null, e);
|
||
|
|
a && a.length && (n = n.concat(a));
|
||
|
|
}
|
||
|
|
return { type: "path", ops: n };
|
||
|
|
})(t, s);
|
||
|
|
if (s.fill)
|
||
|
|
if ("solid" === s.fillStyle) {
|
||
|
|
const e = { type: "path2Dfill", path: t, ops: [] };
|
||
|
|
n.push(e);
|
||
|
|
} else {
|
||
|
|
const e = this.computePathSize(t),
|
||
|
|
i = O(
|
||
|
|
[
|
||
|
|
[0, 0],
|
||
|
|
[e[0], 0],
|
||
|
|
[e[0], e[1]],
|
||
|
|
[0, e[1]],
|
||
|
|
],
|
||
|
|
s
|
||
|
|
);
|
||
|
|
(i.type = "path2Dpattern"), (i.size = e), (i.path = t), n.push(i);
|
||
|
|
}
|
||
|
|
return s.stroke !== L && n.push(i), this._drawable("path", n, s);
|
||
|
|
}
|
||
|
|
computePathSize(e) {
|
||
|
|
let s = [0, 0];
|
||
|
|
if (N && self.document)
|
||
|
|
try {
|
||
|
|
const n = self.document.createElementNS(t, "svg");
|
||
|
|
n.setAttribute("width", "0"), n.setAttribute("height", "0");
|
||
|
|
const i = self.document.createElementNS(t, "path");
|
||
|
|
i.setAttribute("d", e), n.appendChild(i), self.document.body.appendChild(n);
|
||
|
|
const a = i.getBBox();
|
||
|
|
a && ((s[0] = a.width || 0), (s[1] = a.height || 0)),
|
||
|
|
self.document.body.removeChild(n);
|
||
|
|
} catch (t) {}
|
||
|
|
const n = this.getCanvasSize();
|
||
|
|
return s[0] * s[1] || (s = n), s;
|
||
|
|
}
|
||
|
|
getCanvasSize() {
|
||
|
|
const t = (t) =>
|
||
|
|
t && "object" == typeof t && t.baseVal && t.baseVal.value
|
||
|
|
? t.baseVal.value
|
||
|
|
: t || 100;
|
||
|
|
return this.surface ? [t(this.surface.width), t(this.surface.height)] : [100, 100];
|
||
|
|
}
|
||
|
|
opsToPath(t) {
|
||
|
|
let e = "";
|
||
|
|
for (const s of t.ops) {
|
||
|
|
const t = s.data;
|
||
|
|
switch (s.op) {
|
||
|
|
case "move":
|
||
|
|
e += `M${t[0]} ${t[1]} `;
|
||
|
|
break;
|
||
|
|
case "bcurveTo":
|
||
|
|
e += `C${t[0]} ${t[1]}, ${t[2]} ${t[3]}, ${t[4]} ${t[5]} `;
|
||
|
|
break;
|
||
|
|
case "qcurveTo":
|
||
|
|
e += `Q${t[0]} ${t[1]}, ${t[2]} ${t[3]} `;
|
||
|
|
break;
|
||
|
|
case "lineTo":
|
||
|
|
e += `L${t[0]} ${t[1]} `;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return e.trim();
|
||
|
|
}
|
||
|
|
toPaths(t) {
|
||
|
|
const e = t.sets || [],
|
||
|
|
s = t.options || this.defaultOptions,
|
||
|
|
n = [];
|
||
|
|
for (const t of e) {
|
||
|
|
let e = null;
|
||
|
|
switch (t.type) {
|
||
|
|
case "path":
|
||
|
|
e = {
|
||
|
|
d: this.opsToPath(t),
|
||
|
|
stroke: s.stroke,
|
||
|
|
strokeWidth: s.strokeWidth,
|
||
|
|
fill: L,
|
||
|
|
};
|
||
|
|
break;
|
||
|
|
case "fillPath":
|
||
|
|
e = {
|
||
|
|
d: this.opsToPath(t),
|
||
|
|
stroke: L,
|
||
|
|
strokeWidth: 0,
|
||
|
|
fill: s.fill || L,
|
||
|
|
};
|
||
|
|
break;
|
||
|
|
case "fillSketch":
|
||
|
|
e = this.fillSketch(t, s);
|
||
|
|
break;
|
||
|
|
case "path2Dfill":
|
||
|
|
e = { d: t.path || "", stroke: L, strokeWidth: 0, fill: s.fill || L };
|
||
|
|
break;
|
||
|
|
case "path2Dpattern": {
|
||
|
|
const n = t.size,
|
||
|
|
i = {
|
||
|
|
x: 0,
|
||
|
|
y: 0,
|
||
|
|
width: 1,
|
||
|
|
height: 1,
|
||
|
|
viewBox: `0 0 ${Math.round(n[0])} ${Math.round(n[1])}`,
|
||
|
|
patternUnits: "objectBoundingBox",
|
||
|
|
path: this.fillSketch(t, s),
|
||
|
|
};
|
||
|
|
e = { d: t.path, stroke: L, strokeWidth: 0, pattern: i };
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
e && n.push(e);
|
||
|
|
}
|
||
|
|
return n;
|
||
|
|
}
|
||
|
|
fillSketch(t, e) {
|
||
|
|
let s = e.fillWeight;
|
||
|
|
return (
|
||
|
|
s < 0 && (s = e.strokeWidth / 2),
|
||
|
|
{ d: this.opsToPath(t), stroke: e.fill || L, strokeWidth: s, fill: L }
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
const G = "undefined" != typeof document;
|
||
|
|
class V {
|
||
|
|
constructor(t, e) {
|
||
|
|
(this.canvas = t),
|
||
|
|
(this.ctx = this.canvas.getContext("2d")),
|
||
|
|
(this.gen = new B(e, this.canvas));
|
||
|
|
}
|
||
|
|
draw(t) {
|
||
|
|
const e = t.sets || [],
|
||
|
|
s = t.options || this.getDefaultOptions(),
|
||
|
|
n = this.ctx;
|
||
|
|
for (const t of e)
|
||
|
|
switch (t.type) {
|
||
|
|
case "path":
|
||
|
|
n.save(),
|
||
|
|
(n.strokeStyle = "none" === s.stroke ? "transparent" : s.stroke),
|
||
|
|
(n.lineWidth = s.strokeWidth),
|
||
|
|
this._drawToContext(n, t),
|
||
|
|
n.restore();
|
||
|
|
break;
|
||
|
|
case "fillPath":
|
||
|
|
n.save(), (n.fillStyle = s.fill || ""), this._drawToContext(n, t), n.restore();
|
||
|
|
break;
|
||
|
|
case "fillSketch":
|
||
|
|
this.fillSketch(n, t, s);
|
||
|
|
break;
|
||
|
|
case "path2Dfill": {
|
||
|
|
this.ctx.save(), (this.ctx.fillStyle = s.fill || "");
|
||
|
|
const e = new Path2D(t.path);
|
||
|
|
this.ctx.fill(e), this.ctx.restore();
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case "path2Dpattern": {
|
||
|
|
const e = this.canvas.ownerDocument || (G && document);
|
||
|
|
if (e) {
|
||
|
|
const n = t.size,
|
||
|
|
i = e.createElement("canvas"),
|
||
|
|
a = i.getContext("2d"),
|
||
|
|
o = this.computeBBox(t.path);
|
||
|
|
o && (o.width || o.height)
|
||
|
|
? ((i.width = this.canvas.width),
|
||
|
|
(i.height = this.canvas.height),
|
||
|
|
a.translate(o.x || 0, o.y || 0))
|
||
|
|
: ((i.width = n[0]), (i.height = n[1])),
|
||
|
|
this.fillSketch(a, t, s),
|
||
|
|
this.ctx.save(),
|
||
|
|
(this.ctx.fillStyle = this.ctx.createPattern(i, "repeat"));
|
||
|
|
const h = new Path2D(t.path);
|
||
|
|
this.ctx.fill(h), this.ctx.restore();
|
||
|
|
} else console.error("Pattern fill fail: No defs");
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
computeBBox(e) {
|
||
|
|
if (G)
|
||
|
|
try {
|
||
|
|
const s = document.createElementNS(t, "svg");
|
||
|
|
s.setAttribute("width", "0"), s.setAttribute("height", "0");
|
||
|
|
const n = self.document.createElementNS(t, "path");
|
||
|
|
n.setAttribute("d", e), s.appendChild(n), document.body.appendChild(s);
|
||
|
|
const i = n.getBBox();
|
||
|
|
return document.body.removeChild(s), i;
|
||
|
|
} catch (t) {}
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
fillSketch(t, e, s) {
|
||
|
|
let n = s.fillWeight;
|
||
|
|
n < 0 && (n = s.strokeWidth / 2),
|
||
|
|
t.save(),
|
||
|
|
(t.strokeStyle = s.fill || ""),
|
||
|
|
(t.lineWidth = n),
|
||
|
|
this._drawToContext(t, e),
|
||
|
|
t.restore();
|
||
|
|
}
|
||
|
|
_drawToContext(t, e) {
|
||
|
|
t.beginPath();
|
||
|
|
for (const s of e.ops) {
|
||
|
|
const e = s.data;
|
||
|
|
switch (s.op) {
|
||
|
|
case "move":
|
||
|
|
t.moveTo(e[0], e[1]);
|
||
|
|
break;
|
||
|
|
case "bcurveTo":
|
||
|
|
t.bezierCurveTo(e[0], e[1], e[2], e[3], e[4], e[5]);
|
||
|
|
break;
|
||
|
|
case "qcurveTo":
|
||
|
|
t.quadraticCurveTo(e[0], e[1], e[2], e[3]);
|
||
|
|
break;
|
||
|
|
case "lineTo":
|
||
|
|
t.lineTo(e[0], e[1]);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
"fillPath" === e.type ? t.fill() : t.stroke();
|
||
|
|
}
|
||
|
|
get generator() {
|
||
|
|
return this.gen;
|
||
|
|
}
|
||
|
|
getDefaultOptions() {
|
||
|
|
return this.gen.defaultOptions;
|
||
|
|
}
|
||
|
|
line(t, e, s, n, i) {
|
||
|
|
const a = this.gen.line(t, e, s, n, i);
|
||
|
|
return this.draw(a), a;
|
||
|
|
}
|
||
|
|
rectangle(t, e, s, n, i) {
|
||
|
|
const a = this.gen.rectangle(t, e, s, n, i);
|
||
|
|
return this.draw(a), a;
|
||
|
|
}
|
||
|
|
ellipse(t, e, s, n, i) {
|
||
|
|
const a = this.gen.ellipse(t, e, s, n, i);
|
||
|
|
return this.draw(a), a;
|
||
|
|
}
|
||
|
|
circle(t, e, s, n) {
|
||
|
|
const i = this.gen.circle(t, e, s, n);
|
||
|
|
return this.draw(i), i;
|
||
|
|
}
|
||
|
|
linearPath(t, e) {
|
||
|
|
const s = this.gen.linearPath(t, e);
|
||
|
|
return this.draw(s), s;
|
||
|
|
}
|
||
|
|
polygon(t, e) {
|
||
|
|
const s = this.gen.polygon(t, e);
|
||
|
|
return this.draw(s), s;
|
||
|
|
}
|
||
|
|
arc(t, e, s, n, i, a, o = !1, h) {
|
||
|
|
const r = this.gen.arc(t, e, s, n, i, a, o, h);
|
||
|
|
return this.draw(r), r;
|
||
|
|
}
|
||
|
|
curve(t, e) {
|
||
|
|
const s = this.gen.curve(t, e);
|
||
|
|
return this.draw(s), s;
|
||
|
|
}
|
||
|
|
path(t, e) {
|
||
|
|
const s = this.gen.path(t, e);
|
||
|
|
return this.draw(s), s;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
const j = "undefined" != typeof document;
|
||
|
|
class Q {
|
||
|
|
constructor(t, e) {
|
||
|
|
(this.svg = t), (this.gen = new B(e, this.svg));
|
||
|
|
}
|
||
|
|
get defs() {
|
||
|
|
const e = this.svg.ownerDocument || (j && document);
|
||
|
|
if (e && !this._defs) {
|
||
|
|
const s = e.createElementNS(t, "defs");
|
||
|
|
this.svg.firstChild
|
||
|
|
? this.svg.insertBefore(s, this.svg.firstChild)
|
||
|
|
: this.svg.appendChild(s),
|
||
|
|
(this._defs = s);
|
||
|
|
}
|
||
|
|
return this._defs || null;
|
||
|
|
}
|
||
|
|
draw(e) {
|
||
|
|
const s = e.sets || [],
|
||
|
|
n = e.options || this.getDefaultOptions(),
|
||
|
|
i = this.svg.ownerDocument || window.document,
|
||
|
|
a = i.createElementNS(t, "g");
|
||
|
|
for (const e of s) {
|
||
|
|
let s = null;
|
||
|
|
switch (e.type) {
|
||
|
|
case "path":
|
||
|
|
(s = i.createElementNS(t, "path")),
|
||
|
|
s.setAttribute("d", this.opsToPath(e)),
|
||
|
|
(s.style.stroke = n.stroke),
|
||
|
|
(s.style.strokeWidth = n.strokeWidth + ""),
|
||
|
|
(s.style.fill = "none");
|
||
|
|
break;
|
||
|
|
case "fillPath":
|
||
|
|
(s = i.createElementNS(t, "path")),
|
||
|
|
s.setAttribute("d", this.opsToPath(e)),
|
||
|
|
(s.style.stroke = "none"),
|
||
|
|
(s.style.strokeWidth = "0"),
|
||
|
|
(s.style.fill = n.fill || "");
|
||
|
|
break;
|
||
|
|
case "fillSketch":
|
||
|
|
s = this.fillSketch(i, e, n);
|
||
|
|
break;
|
||
|
|
case "path2Dfill":
|
||
|
|
(s = i.createElementNS(t, "path")),
|
||
|
|
s.setAttribute("d", e.path || ""),
|
||
|
|
(s.style.stroke = "none"),
|
||
|
|
(s.style.strokeWidth = "0"),
|
||
|
|
(s.style.fill = n.fill || "");
|
||
|
|
break;
|
||
|
|
case "path2Dpattern":
|
||
|
|
if (this.defs) {
|
||
|
|
const a = e.size,
|
||
|
|
o = i.createElementNS(t, "pattern"),
|
||
|
|
h = `rough-${Math.floor(
|
||
|
|
Math.random() * (Number.MAX_SAFE_INTEGER || 999999)
|
||
|
|
)}`;
|
||
|
|
o.setAttribute("id", h),
|
||
|
|
o.setAttribute("x", "0"),
|
||
|
|
o.setAttribute("y", "0"),
|
||
|
|
o.setAttribute("width", "1"),
|
||
|
|
o.setAttribute("height", "1"),
|
||
|
|
o.setAttribute("height", "1"),
|
||
|
|
o.setAttribute("viewBox", `0 0 ${Math.round(a[0])} ${Math.round(a[1])}`),
|
||
|
|
o.setAttribute("patternUnits", "objectBoundingBox");
|
||
|
|
const r = this.fillSketch(i, e, n);
|
||
|
|
o.appendChild(r),
|
||
|
|
this.defs.appendChild(o),
|
||
|
|
(s = i.createElementNS(t, "path")),
|
||
|
|
s.setAttribute("d", e.path || ""),
|
||
|
|
(s.style.stroke = "none"),
|
||
|
|
(s.style.strokeWidth = "0"),
|
||
|
|
(s.style.fill = `url(#${h})`);
|
||
|
|
} else console.error("Pattern fill fail: No defs");
|
||
|
|
}
|
||
|
|
s && a.appendChild(s);
|
||
|
|
}
|
||
|
|
return a;
|
||
|
|
}
|
||
|
|
fillSketch(e, s, n) {
|
||
|
|
let i = n.fillWeight;
|
||
|
|
i < 0 && (i = n.strokeWidth / 2);
|
||
|
|
const a = e.createElementNS(t, "path");
|
||
|
|
return (
|
||
|
|
a.setAttribute("d", this.opsToPath(s)),
|
||
|
|
(a.style.stroke = n.fill || ""),
|
||
|
|
(a.style.strokeWidth = i + ""),
|
||
|
|
(a.style.fill = "none"),
|
||
|
|
a
|
||
|
|
);
|
||
|
|
}
|
||
|
|
get generator() {
|
||
|
|
return this.gen;
|
||
|
|
}
|
||
|
|
getDefaultOptions() {
|
||
|
|
return this.gen.defaultOptions;
|
||
|
|
}
|
||
|
|
opsToPath(t) {
|
||
|
|
return this.gen.opsToPath(t);
|
||
|
|
}
|
||
|
|
line(t, e, s, n, i) {
|
||
|
|
const a = this.gen.line(t, e, s, n, i);
|
||
|
|
return this.draw(a);
|
||
|
|
}
|
||
|
|
rectangle(t, e, s, n, i) {
|
||
|
|
const a = this.gen.rectangle(t, e, s, n, i);
|
||
|
|
return this.draw(a);
|
||
|
|
}
|
||
|
|
ellipse(t, e, s, n, i) {
|
||
|
|
const a = this.gen.ellipse(t, e, s, n, i);
|
||
|
|
return this.draw(a);
|
||
|
|
}
|
||
|
|
circle(t, e, s, n) {
|
||
|
|
const i = this.gen.circle(t, e, s, n);
|
||
|
|
return this.draw(i);
|
||
|
|
}
|
||
|
|
linearPath(t, e) {
|
||
|
|
const s = this.gen.linearPath(t, e);
|
||
|
|
return this.draw(s);
|
||
|
|
}
|
||
|
|
polygon(t, e) {
|
||
|
|
const s = this.gen.polygon(t, e);
|
||
|
|
return this.draw(s);
|
||
|
|
}
|
||
|
|
arc(t, e, s, n, i, a, o = !1, h) {
|
||
|
|
const r = this.gen.arc(t, e, s, n, i, a, o, h);
|
||
|
|
return this.draw(r);
|
||
|
|
}
|
||
|
|
curve(t, e) {
|
||
|
|
const s = this.gen.curve(t, e);
|
||
|
|
return this.draw(s);
|
||
|
|
}
|
||
|
|
path(t, e) {
|
||
|
|
const s = this.gen.path(t, e);
|
||
|
|
return this.draw(s);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
var rough = {
|
||
|
|
canvas: (t, e) => new V(t, e),
|
||
|
|
svg: (t, e) => new Q(t, e),
|
||
|
|
generator: (t, e) => new B(t, e),
|
||
|
|
newSeed: () => B.newSeed(),
|
||
|
|
};
|