@pixerate/editor 0.74.0 → 0.76.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/THIRD_PARTY_NOTICES.md +2 -0
- package/dist/agent/index.cjs +28 -28
- package/dist/agent/index.js +3 -3
- package/dist/animation-editor/index.cjs +322 -273
- package/dist/animation-editor/index.cjs.map +1 -1
- package/dist/animation-editor/index.d.cts +96 -3
- package/dist/animation-editor/index.d.ts +96 -3
- package/dist/animation-editor/index.js +138 -89
- package/dist/animation-editor/index.js.map +1 -1
- package/dist/canvas/index.cjs +26 -26
- package/dist/canvas/index.js +2 -2
- package/dist/{chunk-3TLL5OID.js → chunk-4JLB2USO.js} +2 -2
- package/dist/{chunk-YJLCBA7V.cjs → chunk-7MD7C6XQ.cjs} +87 -87
- package/dist/{chunk-YJLCBA7V.cjs.map → chunk-7MD7C6XQ.cjs.map} +1 -1
- package/dist/{chunk-OK7T2LHK.js → chunk-GNO5PEMH.js} +2 -2
- package/dist/{chunk-EIXXBKUB.js → chunk-IMSX4IVG.js} +7 -7
- package/dist/chunk-INZJALPY.js +87 -0
- package/dist/chunk-INZJALPY.js.map +1 -0
- package/dist/{chunk-MLREO6J3.cjs → chunk-JEYDXRWQ.cjs} +46 -46
- package/dist/{chunk-MLREO6J3.cjs.map → chunk-JEYDXRWQ.cjs.map} +1 -1
- package/dist/{chunk-PL3MPFPA.cjs → chunk-MXF4DP2C.cjs} +77 -77
- package/dist/{chunk-PL3MPFPA.cjs.map → chunk-MXF4DP2C.cjs.map} +1 -1
- package/dist/{chunk-T4XWVPJK.cjs → chunk-RKJDBXTY.cjs} +3 -3
- package/dist/{chunk-T4XWVPJK.cjs.map → chunk-RKJDBXTY.cjs.map} +1 -1
- package/dist/{chunk-HNDSPZ5T.cjs → chunk-ROXFP2LQ.cjs} +4 -4
- package/dist/{chunk-HNDSPZ5T.cjs.map → chunk-ROXFP2LQ.cjs.map} +1 -1
- package/dist/{chunk-WON34HKM.js → chunk-SVW2UNUC.js} +2 -2
- package/dist/{chunk-66IMF6OD.cjs → chunk-TYOAJDFD.cjs} +3 -3
- package/dist/{chunk-66IMF6OD.cjs.map → chunk-TYOAJDFD.cjs.map} +1 -1
- package/dist/chunk-WAJQKWQU.cjs +87 -0
- package/dist/chunk-WAJQKWQU.cjs.map +1 -0
- package/dist/{chunk-O2UH7LZE.cjs → chunk-XGD3FSNC.cjs} +239 -239
- package/dist/chunk-XGD3FSNC.cjs.map +1 -0
- package/dist/{chunk-VWZB6BCY.js → chunk-Y3NW4VJE.js} +2 -2
- package/dist/{chunk-GTMJ4Y3S.js → chunk-YCSFS3GK.js} +244 -244
- package/dist/{chunk-GTMJ4Y3S.js.map → chunk-YCSFS3GK.js.map} +1 -1
- package/dist/{chunk-UKI64KUD.js → chunk-ZQNDSUZO.js} +6 -6
- package/dist/extensions/index.cjs +7 -7
- package/dist/extensions/index.cjs.map +1 -1
- package/dist/extensions/index.js +6 -6
- package/dist/index.cjs +35 -35
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +17 -17
- package/dist/serializers/index.cjs +4 -4
- package/dist/serializers/index.cjs.map +1 -1
- package/dist/serializers/index.js +3 -3
- package/dist/vector/index.cjs +532 -532
- package/dist/vector/index.js +3 -3
- package/dist/video-editor/index.cjs +2219 -0
- package/dist/video-editor/index.cjs.map +1 -0
- package/dist/video-editor/index.d.cts +985 -0
- package/dist/video-editor/index.d.ts +985 -0
- package/dist/video-editor/index.js +2219 -0
- package/dist/video-editor/index.js.map +1 -0
- package/package.json +6 -1
- package/dist/chunk-O2UH7LZE.cjs.map +0 -1
- /package/dist/{chunk-3TLL5OID.js.map → chunk-4JLB2USO.js.map} +0 -0
- /package/dist/{chunk-OK7T2LHK.js.map → chunk-GNO5PEMH.js.map} +0 -0
- /package/dist/{chunk-EIXXBKUB.js.map → chunk-IMSX4IVG.js.map} +0 -0
- /package/dist/{chunk-WON34HKM.js.map → chunk-SVW2UNUC.js.map} +0 -0
- /package/dist/{chunk-VWZB6BCY.js.map → chunk-Y3NW4VJE.js.map} +0 -0
- /package/dist/{chunk-UKI64KUD.js.map → chunk-ZQNDSUZO.js.map} +0 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// src/animation-editor/issues.ts
|
|
2
|
+
var MOTION_ISSUE_CODES = {
|
|
3
|
+
"no-shots": { severity: "note", wording: "The scene has no shots yet." },
|
|
4
|
+
"duplicate-shot-id": { severity: "error", wording: "Two shots share an id." },
|
|
5
|
+
"unknown-target": { severity: "error", wording: "A command names a node the artwork does not have." },
|
|
6
|
+
"unknown-path": { severity: "error", wording: "A follow command names a path the artwork does not have." },
|
|
7
|
+
"not-a-path": { severity: "error", wording: "A follow path must be a path node, not a group." },
|
|
8
|
+
"reveal-no-box": { severity: "warning", wording: "A wipe, iris or split cannot clip a node with no width or height (a lone straight line), so it fades instead." },
|
|
9
|
+
"driver-cycle": { severity: "error", wording: "Drivers follow each other in a loop, so none of them has a value." },
|
|
10
|
+
"split-not-text": { severity: "warning", wording: "A command splits a target into letters, but it is not a group of letter paths, so it animates as a whole." },
|
|
11
|
+
"unknown-clip": { severity: "error", wording: "A play command names a clip the scene does not have." },
|
|
12
|
+
"unknown-shape": { severity: "error", wording: "A morph names a shape the artwork does not have." },
|
|
13
|
+
"match-self": { severity: "error", wording: "A match turns a group into itself or into a group it holds (or that holds it)." },
|
|
14
|
+
"match-unpaired": { severity: "note", wording: `Parts of a match's "into" group have no partner in the target, so they do not appear.` },
|
|
15
|
+
"unknown-effect": { severity: "error", wording: "An effect command names an effect the node does not have." },
|
|
16
|
+
"unknown-effect-param": { severity: "error", wording: "An effect command names a parameter that is not a number of that effect." },
|
|
17
|
+
"unknown-frame": { severity: "error", wording: "A camera frames a node the artwork does not have." },
|
|
18
|
+
"invalid-camera": { severity: "error", wording: "A camera rectangle has no area." },
|
|
19
|
+
"invalid-color": { severity: "error", wording: "A colour cannot be read." },
|
|
20
|
+
"paint-not-color": { severity: "warning", wording: "A style command recolours a gradient or empty paint, which only switches at the end, or a colour pulse has no solid paint to tint." },
|
|
21
|
+
"overlap": { severity: "warning", wording: "Two commands change the same property of a node at the same time; the later one wins." },
|
|
22
|
+
"enter-visible": { severity: "warning", wording: "A node enters while it is already showing, so it blinks out first." },
|
|
23
|
+
"exit-hidden": { severity: "warning", wording: "A node exits or animates while it is hidden." },
|
|
24
|
+
"out-of-frame": { severity: "warning", wording: "A node a command animates ends up outside the camera." },
|
|
25
|
+
"too-fast": { severity: "warning", wording: "A change is too quick to follow." },
|
|
26
|
+
"spring-cut-short": { severity: "warning", wording: "A spring is given a duration shorter than it takes to settle, so it jumps to its end." },
|
|
27
|
+
"unknown-cue": { severity: "error", wording: "A shot is cued to a beat with no beat grid, or to a word the narration does not have." },
|
|
28
|
+
"cue-missed": { severity: "warning", wording: "A shot starts after its cue, because the shot before runs past it." },
|
|
29
|
+
"trigger-loop": { severity: "note", wording: "A scene that plays on a trigger ignores its loop." },
|
|
30
|
+
"click-cue": { severity: "warning", wording: "A shot of a click-triggered scene is cued, but clicks decide when its shots start." },
|
|
31
|
+
"click-one-shot": { severity: "note", wording: "A click-triggered scene has one shot, so every click replays it." },
|
|
32
|
+
"scene-too-long": { severity: "warning", wording: "The scene runs past its target length." },
|
|
33
|
+
"scene-too-short": { severity: "warning", wording: "The scene ends before its target length." },
|
|
34
|
+
"unknown-control-color": { severity: "warning", wording: "A control stands for a colour the scene never uses." },
|
|
35
|
+
"empty-shot": { severity: "note", wording: "A shot neither moves the camera nor runs a command." },
|
|
36
|
+
"camera-aspect": { severity: "note", wording: "A camera rectangle has a different shape from the artwork, so it is letterboxed." }
|
|
37
|
+
};
|
|
38
|
+
function motionIssue(code, message, extra = {}) {
|
|
39
|
+
return { code, severity: MOTION_ISSUE_CODES[code].severity, message, ...extra };
|
|
40
|
+
}
|
|
41
|
+
function motionIssueKey(issue) {
|
|
42
|
+
if (_optionalChain([issue, 'access', _2 => _2.ids, 'optionalAccess', _3 => _3.length])) return `${issue.code}:${[...issue.ids].sort().join(",")}`;
|
|
43
|
+
return `${issue.code}@${_nullishCoalesce(issue.shot, () => ( ""))}#${_nullishCoalesce(issue.command, () => ( ""))}`;
|
|
44
|
+
}
|
|
45
|
+
function motionIssueLine(issue) {
|
|
46
|
+
const where = issue.shot !== void 0 ? `Shot "${issue.shot}"${issue.command !== void 0 ? `, command ${issue.command + 1}` : ""}: ` : "";
|
|
47
|
+
return `${where}${issue.message}`;
|
|
48
|
+
}
|
|
49
|
+
function editDistance(a, b) {
|
|
50
|
+
const d = Array.from({ length: a.length + 1 }, (_, i) => [i, ...Array(b.length).fill(0)]);
|
|
51
|
+
for (let j = 1; j <= b.length; j++) d[0][j] = j;
|
|
52
|
+
for (let i = 1; i <= a.length; i++) {
|
|
53
|
+
for (let j = 1; j <= b.length; j++) {
|
|
54
|
+
const cost = a[i - 1] === b[j - 1] ? 0 : 1;
|
|
55
|
+
d[i][j] = Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost);
|
|
56
|
+
if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) d[i][j] = Math.min(d[i][j], d[i - 2][j - 2] + 1);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return d[a.length][b.length];
|
|
60
|
+
}
|
|
61
|
+
function suggestName(word, candidates) {
|
|
62
|
+
const w = word.toLowerCase();
|
|
63
|
+
let best;
|
|
64
|
+
let bestDistance = Infinity;
|
|
65
|
+
for (const c of candidates) {
|
|
66
|
+
const distance = editDistance(w, c.toLowerCase());
|
|
67
|
+
if (distance < bestDistance) {
|
|
68
|
+
best = c;
|
|
69
|
+
bestDistance = distance;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return best !== void 0 && bestDistance <= Math.max(1, Math.floor(word.length / 3)) ? best : void 0;
|
|
73
|
+
}
|
|
74
|
+
function namedWithSuggestion(word, candidates) {
|
|
75
|
+
const s = suggestName(word, candidates);
|
|
76
|
+
return s !== void 0 && s !== word ? `"${word}" (did you mean "${s}"?)` : `"${word}"`;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
exports.MOTION_ISSUE_CODES = MOTION_ISSUE_CODES; exports.motionIssue = motionIssue; exports.motionIssueKey = motionIssueKey; exports.motionIssueLine = motionIssueLine; exports.suggestName = suggestName; exports.namedWithSuggestion = namedWithSuggestion;
|
|
87
|
+
//# sourceMappingURL=chunk-WAJQKWQU.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/editor/editor/packages/core/dist/chunk-WAJQKWQU.cjs","../src/animation-editor/issues.ts"],"names":[],"mappings":"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","file":"/home/runner/work/editor/editor/packages/core/dist/chunk-WAJQKWQU.cjs","sourcesContent":[null,"/**\n * Problems with a scene, as data: every issue has a stable `code`, a severity, the shot and\n * command it is in and the ids it is about, beside its prose `message`, so an agent (or a UI)\n * can act on it without parsing sentences.\n */\n\n/** `error`: the scene does not play as written. `warning`: it plays, but probably not as meant. `note`: may well be intended. */\nexport type MotionIssueSeverity = 'error' | 'warning' | 'note';\n\n/** Every issue code with its severity and what it means. */\nexport const MOTION_ISSUE_CODES = {\n\t'no-shots': { severity: 'note', wording: 'The scene has no shots yet.' },\n\t'duplicate-shot-id': { severity: 'error', wording: 'Two shots share an id.' },\n\t'unknown-target': { severity: 'error', wording: 'A command names a node the artwork does not have.' },\n\t'unknown-path': { severity: 'error', wording: 'A follow command names a path the artwork does not have.' },\n\t'not-a-path': { severity: 'error', wording: 'A follow path must be a path node, not a group.' },\n\t'reveal-no-box': { severity: 'warning', wording: 'A wipe, iris or split cannot clip a node with no width or height (a lone straight line), so it fades instead.' },\n\t'driver-cycle': { severity: 'error', wording: 'Drivers follow each other in a loop, so none of them has a value.' },\n\t'split-not-text': { severity: 'warning', wording: 'A command splits a target into letters, but it is not a group of letter paths, so it animates as a whole.' },\n\t'unknown-clip': { severity: 'error', wording: 'A play command names a clip the scene does not have.' },\n\t'unknown-shape': { severity: 'error', wording: 'A morph names a shape the artwork does not have.' },\n\t'match-self': { severity: 'error', wording: 'A match turns a group into itself or into a group it holds (or that holds it).' },\n\t'match-unpaired': { severity: 'note', wording: 'Parts of a match\\'s \"into\" group have no partner in the target, so they do not appear.' },\n\t'unknown-effect': { severity: 'error', wording: 'An effect command names an effect the node does not have.' },\n\t'unknown-effect-param': { severity: 'error', wording: 'An effect command names a parameter that is not a number of that effect.' },\n\t'unknown-frame': { severity: 'error', wording: 'A camera frames a node the artwork does not have.' },\n\t'invalid-camera': { severity: 'error', wording: 'A camera rectangle has no area.' },\n\t'invalid-color': { severity: 'error', wording: 'A colour cannot be read.' },\n\t'paint-not-color': { severity: 'warning', wording: 'A style command recolours a gradient or empty paint, which only switches at the end, or a colour pulse has no solid paint to tint.' },\n\t'overlap': { severity: 'warning', wording: 'Two commands change the same property of a node at the same time; the later one wins.' },\n\t'enter-visible': { severity: 'warning', wording: 'A node enters while it is already showing, so it blinks out first.' },\n\t'exit-hidden': { severity: 'warning', wording: 'A node exits or animates while it is hidden.' },\n\t'out-of-frame': { severity: 'warning', wording: 'A node a command animates ends up outside the camera.' },\n\t'too-fast': { severity: 'warning', wording: 'A change is too quick to follow.' },\n\t'spring-cut-short': { severity: 'warning', wording: 'A spring is given a duration shorter than it takes to settle, so it jumps to its end.' },\n\t'unknown-cue': { severity: 'error', wording: 'A shot is cued to a beat with no beat grid, or to a word the narration does not have.' },\n\t'cue-missed': { severity: 'warning', wording: 'A shot starts after its cue, because the shot before runs past it.' },\n\t'trigger-loop': { severity: 'note', wording: 'A scene that plays on a trigger ignores its loop.' },\n\t'click-cue': { severity: 'warning', wording: 'A shot of a click-triggered scene is cued, but clicks decide when its shots start.' },\n\t'click-one-shot': { severity: 'note', wording: 'A click-triggered scene has one shot, so every click replays it.' },\n\t'scene-too-long': { severity: 'warning', wording: 'The scene runs past its target length.' },\n\t'scene-too-short': { severity: 'warning', wording: 'The scene ends before its target length.' },\n\t'unknown-control-color': { severity: 'warning', wording: 'A control stands for a colour the scene never uses.' },\n\t'empty-shot': { severity: 'note', wording: 'A shot neither moves the camera nor runs a command.' },\n\t'camera-aspect': { severity: 'note', wording: 'A camera rectangle has a different shape from the artwork, so it is letterboxed.' }\n} as const satisfies Record<string, { severity: MotionIssueSeverity; wording: string }>;\n\nexport type MotionIssueCode = keyof typeof MOTION_ISSUE_CODES;\n\nexport interface MotionIssue {\n\tcode: MotionIssueCode;\n\tseverity: MotionIssueSeverity;\n\tmessage: string;\n\t/** Id of the shot it is in, when it is in one. */\n\tshot?: string;\n\t/** Index of the command in that shot's `run`. */\n\tcommand?: number;\n\t/** Node ids it is about. */\n\tids?: string[];\n\t/** What was measured, what was needed and in what unit (e.g. 80 vs 120 ms). */\n\tmeasured?: number;\n\tneeded?: number;\n\tunit?: 'ms' | 's' | 'units';\n}\n\nexport function motionIssue(code: MotionIssueCode, message: string, extra: Omit<MotionIssue, 'code' | 'severity' | 'message'> = {}): MotionIssue {\n\treturn { code, severity: MOTION_ISSUE_CODES[code].severity, message, ...extra };\n}\n\n/** A stable key for an issue (code and ids, else code and place), to compare two checks. */\nexport function motionIssueKey(issue: MotionIssue): string {\n\tif (issue.ids?.length) return `${issue.code}:${[...issue.ids].sort().join(',')}`;\n\treturn `${issue.code}@${issue.shot ?? ''}#${issue.command ?? ''}`;\n}\n\n/** One line: `Shot \"intro\", command 2: …`. */\nexport function motionIssueLine(issue: MotionIssue): string {\n\tconst where = issue.shot !== undefined ? `Shot \"${issue.shot}\"${issue.command !== undefined ? `, command ${issue.command + 1}` : ''}: ` : '';\n\treturn `${where}${issue.message}`;\n}\n\n/** Optimal string alignment (Damerau–Levenshtein) distance. */\nfunction editDistance(a: string, b: string): number {\n\tconst d: number[][] = Array.from({ length: a.length + 1 }, (_, i) => [i, ...Array(b.length).fill(0)]);\n\tfor (let j = 1; j <= b.length; j++) d[0][j] = j;\n\tfor (let i = 1; i <= a.length; i++) {\n\t\tfor (let j = 1; j <= b.length; j++) {\n\t\t\tconst cost = a[i - 1] === b[j - 1] ? 0 : 1;\n\t\t\td[i][j] = Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost);\n\t\t\tif (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) d[i][j] = Math.min(d[i][j], d[i - 2][j - 2] + 1);\n\t\t}\n\t}\n\treturn d[a.length][b.length];\n}\n\n/** The candidate closest to `word` (case-insensitive), if it is within a third of its length. */\nexport function suggestName(word: string, candidates: Iterable<string>): string | undefined {\n\tconst w = word.toLowerCase();\n\tlet best: string | undefined;\n\tlet bestDistance = Infinity;\n\tfor (const c of candidates) {\n\t\tconst distance = editDistance(w, c.toLowerCase());\n\t\tif (distance < bestDistance) {\n\t\t\tbest = c;\n\t\t\tbestDistance = distance;\n\t\t}\n\t}\n\treturn best !== undefined && bestDistance <= Math.max(1, Math.floor(word.length / 3)) ? best : undefined;\n}\n\n/** `\"sunn\" (did you mean \"sun\"?)`, or just `\"sunn\"`. */\nexport function namedWithSuggestion(word: string, candidates: Iterable<string>): string {\n\tconst s = suggestName(word, candidates);\n\treturn s !== undefined && s !== word ? `\"${word}\" (did you mean \"${s}\"?)` : `\"${word}\"`;\n}\n"]}
|
|
@@ -1,4 +1,240 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3;// src/canvas/
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3;// src/canvas/gradient.ts
|
|
2
|
+
var PIXERATE_BRAND_GRADIENT = {
|
|
3
|
+
type: "linear",
|
|
4
|
+
angle: 135,
|
|
5
|
+
stops: [
|
|
6
|
+
{ offset: 0, color: "#8E51FF" },
|
|
7
|
+
{ offset: 1, color: "#e12afb" }
|
|
8
|
+
]
|
|
9
|
+
};
|
|
10
|
+
var CANVAS_GRADIENT_PRESETS = {
|
|
11
|
+
pixerate: PIXERATE_BRAND_GRADIENT,
|
|
12
|
+
sunset: {
|
|
13
|
+
type: "linear",
|
|
14
|
+
angle: 90,
|
|
15
|
+
stops: [
|
|
16
|
+
{ offset: 0, color: "#f97316" },
|
|
17
|
+
{ offset: 1, color: "#ec4899" }
|
|
18
|
+
]
|
|
19
|
+
},
|
|
20
|
+
ocean: {
|
|
21
|
+
type: "linear",
|
|
22
|
+
angle: 90,
|
|
23
|
+
stops: [
|
|
24
|
+
{ offset: 0, color: "#06b6d4" },
|
|
25
|
+
{ offset: 1, color: "#3b82f6" }
|
|
26
|
+
]
|
|
27
|
+
},
|
|
28
|
+
aurora: {
|
|
29
|
+
type: "linear",
|
|
30
|
+
angle: 90,
|
|
31
|
+
stops: [
|
|
32
|
+
{ offset: 0, color: "#10b981" },
|
|
33
|
+
{ offset: 1, color: "#6366f1" }
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
neon: {
|
|
37
|
+
type: "linear",
|
|
38
|
+
angle: 90,
|
|
39
|
+
stops: [
|
|
40
|
+
{ offset: 0, color: "#a855f7" },
|
|
41
|
+
{ offset: 1, color: "#ec4899" }
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
amber: {
|
|
45
|
+
type: "linear",
|
|
46
|
+
angle: 90,
|
|
47
|
+
stops: [
|
|
48
|
+
{ offset: 0, color: "#f59e0b" },
|
|
49
|
+
{ offset: 1, color: "#ef4444" }
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
cosmic: {
|
|
53
|
+
type: "linear",
|
|
54
|
+
angle: 90,
|
|
55
|
+
stops: [
|
|
56
|
+
{ offset: 0, color: "#3b82f6" },
|
|
57
|
+
{ offset: 0.5, color: "#8b5cf6" },
|
|
58
|
+
{ offset: 1, color: "#ec4899" }
|
|
59
|
+
]
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
function isCanvasGradient(value) {
|
|
63
|
+
if (!value || typeof value !== "object") return false;
|
|
64
|
+
const val = value;
|
|
65
|
+
if (val.type !== "linear" && val.type !== "radial") return false;
|
|
66
|
+
if (!Array.isArray(val.stops)) return false;
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
function splitCssArgs(str) {
|
|
70
|
+
const parts = [];
|
|
71
|
+
let depth = 0;
|
|
72
|
+
let current = "";
|
|
73
|
+
for (let i = 0; i < str.length; i++) {
|
|
74
|
+
const char = str[i];
|
|
75
|
+
if (char === "(") depth++;
|
|
76
|
+
else if (char === ")") depth = Math.max(0, depth - 1);
|
|
77
|
+
if (char === "," && depth === 0) {
|
|
78
|
+
if (current.trim()) parts.push(current.trim());
|
|
79
|
+
current = "";
|
|
80
|
+
} else {
|
|
81
|
+
current += char;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (current.trim()) parts.push(current.trim());
|
|
85
|
+
return parts;
|
|
86
|
+
}
|
|
87
|
+
function parseCssAngle(val) {
|
|
88
|
+
const trimmed = val.trim().toLowerCase();
|
|
89
|
+
if (trimmed.endsWith("deg")) {
|
|
90
|
+
return parseFloat(trimmed);
|
|
91
|
+
}
|
|
92
|
+
if (trimmed.endsWith("turn")) {
|
|
93
|
+
return parseFloat(trimmed) * 360;
|
|
94
|
+
}
|
|
95
|
+
if (trimmed.endsWith("rad")) {
|
|
96
|
+
return parseFloat(trimmed) * 180 / Math.PI;
|
|
97
|
+
}
|
|
98
|
+
if (trimmed.startsWith("to ")) {
|
|
99
|
+
const dir = trimmed.slice(3).trim();
|
|
100
|
+
if (dir === "bottom") return 180;
|
|
101
|
+
if (dir === "top") return 0;
|
|
102
|
+
if (dir === "right") return 90;
|
|
103
|
+
if (dir === "left") return 270;
|
|
104
|
+
if (dir === "bottom right" || dir === "right bottom") return 135;
|
|
105
|
+
if (dir === "bottom left" || dir === "left bottom") return 225;
|
|
106
|
+
if (dir === "top right" || dir === "right top") return 45;
|
|
107
|
+
if (dir === "top left" || dir === "left top") return 315;
|
|
108
|
+
}
|
|
109
|
+
const n = parseFloat(trimmed);
|
|
110
|
+
return Number.isFinite(n) ? n : 180;
|
|
111
|
+
}
|
|
112
|
+
function parseCssGradient(css) {
|
|
113
|
+
const trimmed = css.trim();
|
|
114
|
+
const linearMatch = trimmed.match(/^linear-gradient\s*\((.*)\)$/is);
|
|
115
|
+
if (linearMatch) {
|
|
116
|
+
const rawArgs = splitCssArgs(linearMatch[1]);
|
|
117
|
+
if (rawArgs.length === 0) return null;
|
|
118
|
+
let angle = 180;
|
|
119
|
+
let stopStartIndex = 0;
|
|
120
|
+
const first = rawArgs[0].trim().toLowerCase();
|
|
121
|
+
if (first.endsWith("deg") || first.endsWith("turn") || first.endsWith("rad") || first.startsWith("to ")) {
|
|
122
|
+
angle = parseCssAngle(first);
|
|
123
|
+
stopStartIndex = 1;
|
|
124
|
+
}
|
|
125
|
+
const stopStrings = rawArgs.slice(stopStartIndex);
|
|
126
|
+
if (stopStrings.length === 0) return null;
|
|
127
|
+
const stops = parseStopStrings(stopStrings);
|
|
128
|
+
if (stops.length === 0) return null;
|
|
129
|
+
return {
|
|
130
|
+
type: "linear",
|
|
131
|
+
angle,
|
|
132
|
+
stops
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
const radialMatch = trimmed.match(/^radial-gradient\s*\((.*)\)$/is);
|
|
136
|
+
if (radialMatch) {
|
|
137
|
+
const rawArgs = splitCssArgs(radialMatch[1]);
|
|
138
|
+
if (rawArgs.length === 0) return null;
|
|
139
|
+
let stopStartIndex = 0;
|
|
140
|
+
const first = rawArgs[0].trim().toLowerCase();
|
|
141
|
+
if (first.startsWith("circle") || first.startsWith("ellipse") || first.includes("at ")) {
|
|
142
|
+
stopStartIndex = 1;
|
|
143
|
+
}
|
|
144
|
+
const stopStrings = rawArgs.slice(stopStartIndex);
|
|
145
|
+
if (stopStrings.length === 0) return null;
|
|
146
|
+
const stops = parseStopStrings(stopStrings);
|
|
147
|
+
if (stops.length === 0) return null;
|
|
148
|
+
return {
|
|
149
|
+
type: "radial",
|
|
150
|
+
cx: 0.5,
|
|
151
|
+
cy: 0.5,
|
|
152
|
+
r: 0.5,
|
|
153
|
+
stops
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
function parseStopStrings(stopStrings) {
|
|
159
|
+
const count = stopStrings.length;
|
|
160
|
+
return stopStrings.map((str, idx) => {
|
|
161
|
+
const parts = str.trim().split(/\s+(?=[0-9%])/);
|
|
162
|
+
const color = parts[0];
|
|
163
|
+
let offset = count === 1 ? 0 : idx / (count - 1);
|
|
164
|
+
if (parts.length > 1) {
|
|
165
|
+
const posStr = parts[1].trim();
|
|
166
|
+
if (posStr.endsWith("%")) {
|
|
167
|
+
offset = parseFloat(posStr) / 100;
|
|
168
|
+
} else {
|
|
169
|
+
const val = parseFloat(posStr);
|
|
170
|
+
if (Number.isFinite(val)) offset = val;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return {
|
|
174
|
+
offset: Math.min(1, Math.max(0, offset)),
|
|
175
|
+
color
|
|
176
|
+
};
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
function resolveCanvasGradient(value) {
|
|
180
|
+
if (!value) return null;
|
|
181
|
+
if (isCanvasGradient(value)) return value;
|
|
182
|
+
if (typeof value === "string") {
|
|
183
|
+
const lower = value.trim().toLowerCase();
|
|
184
|
+
if (CANVAS_GRADIENT_PRESETS[lower]) {
|
|
185
|
+
return CANVAS_GRADIENT_PRESETS[lower];
|
|
186
|
+
}
|
|
187
|
+
if (lower.startsWith("linear-gradient") || lower.startsWith("radial-gradient")) {
|
|
188
|
+
return parseCssGradient(value);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
function angleToSvgLinearCoords(angleDeg = 180) {
|
|
194
|
+
const rad = (90 - angleDeg) * Math.PI / 180;
|
|
195
|
+
const dx = Math.cos(rad);
|
|
196
|
+
const dy = -Math.sin(rad);
|
|
197
|
+
const half = 0.5;
|
|
198
|
+
return {
|
|
199
|
+
x1: Math.round((half - dx * half) * 1e3) / 1e3,
|
|
200
|
+
y1: Math.round((half - dy * half) * 1e3) / 1e3,
|
|
201
|
+
x2: Math.round((half + dx * half) * 1e3) / 1e3,
|
|
202
|
+
y2: Math.round((half + dy * half) * 1e3) / 1e3
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
function gradientToSvgDef(gradient, id) {
|
|
206
|
+
const stops = (_nullishCoalesce(gradient.stops, () => ( []))).map((s) => ({
|
|
207
|
+
offset: `${Math.round(s.offset * 1e3) / 10}%`,
|
|
208
|
+
stopColor: s.color,
|
|
209
|
+
stopOpacity: s.opacity
|
|
210
|
+
}));
|
|
211
|
+
if (gradient.type === "radial") {
|
|
212
|
+
return {
|
|
213
|
+
id,
|
|
214
|
+
type: "radial",
|
|
215
|
+
attrs: {
|
|
216
|
+
cx: gradient.cx !== void 0 ? `${gradient.cx * 100}%` : "50%",
|
|
217
|
+
cy: gradient.cy !== void 0 ? `${gradient.cy * 100}%` : "50%",
|
|
218
|
+
r: gradient.r !== void 0 ? `${gradient.r * 100}%` : "50%"
|
|
219
|
+
},
|
|
220
|
+
stops
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
const coords = angleToSvgLinearCoords(_nullishCoalesce(gradient.angle, () => ( 180)));
|
|
224
|
+
return {
|
|
225
|
+
id,
|
|
226
|
+
type: "linear",
|
|
227
|
+
attrs: {
|
|
228
|
+
x1: `${coords.x1 * 100}%`,
|
|
229
|
+
y1: `${coords.y1 * 100}%`,
|
|
230
|
+
x2: `${coords.x2 * 100}%`,
|
|
231
|
+
y2: `${coords.y2 * 100}%`
|
|
232
|
+
},
|
|
233
|
+
stops
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// src/canvas/curveFit.ts
|
|
2
238
|
function formatNumber(value, precision) {
|
|
3
239
|
const factor = 10 ** precision;
|
|
4
240
|
const rounded = Math.round(value * factor) / factor;
|
|
@@ -343,242 +579,6 @@ function fitFreehandPath(points, options = {}) {
|
|
|
343
579
|
return fitPathData(points, { tolerance: 1, ...options, closed: false });
|
|
344
580
|
}
|
|
345
581
|
|
|
346
|
-
// src/canvas/gradient.ts
|
|
347
|
-
var PIXERATE_BRAND_GRADIENT = {
|
|
348
|
-
type: "linear",
|
|
349
|
-
angle: 135,
|
|
350
|
-
stops: [
|
|
351
|
-
{ offset: 0, color: "#8E51FF" },
|
|
352
|
-
{ offset: 1, color: "#e12afb" }
|
|
353
|
-
]
|
|
354
|
-
};
|
|
355
|
-
var CANVAS_GRADIENT_PRESETS = {
|
|
356
|
-
pixerate: PIXERATE_BRAND_GRADIENT,
|
|
357
|
-
sunset: {
|
|
358
|
-
type: "linear",
|
|
359
|
-
angle: 90,
|
|
360
|
-
stops: [
|
|
361
|
-
{ offset: 0, color: "#f97316" },
|
|
362
|
-
{ offset: 1, color: "#ec4899" }
|
|
363
|
-
]
|
|
364
|
-
},
|
|
365
|
-
ocean: {
|
|
366
|
-
type: "linear",
|
|
367
|
-
angle: 90,
|
|
368
|
-
stops: [
|
|
369
|
-
{ offset: 0, color: "#06b6d4" },
|
|
370
|
-
{ offset: 1, color: "#3b82f6" }
|
|
371
|
-
]
|
|
372
|
-
},
|
|
373
|
-
aurora: {
|
|
374
|
-
type: "linear",
|
|
375
|
-
angle: 90,
|
|
376
|
-
stops: [
|
|
377
|
-
{ offset: 0, color: "#10b981" },
|
|
378
|
-
{ offset: 1, color: "#6366f1" }
|
|
379
|
-
]
|
|
380
|
-
},
|
|
381
|
-
neon: {
|
|
382
|
-
type: "linear",
|
|
383
|
-
angle: 90,
|
|
384
|
-
stops: [
|
|
385
|
-
{ offset: 0, color: "#a855f7" },
|
|
386
|
-
{ offset: 1, color: "#ec4899" }
|
|
387
|
-
]
|
|
388
|
-
},
|
|
389
|
-
amber: {
|
|
390
|
-
type: "linear",
|
|
391
|
-
angle: 90,
|
|
392
|
-
stops: [
|
|
393
|
-
{ offset: 0, color: "#f59e0b" },
|
|
394
|
-
{ offset: 1, color: "#ef4444" }
|
|
395
|
-
]
|
|
396
|
-
},
|
|
397
|
-
cosmic: {
|
|
398
|
-
type: "linear",
|
|
399
|
-
angle: 90,
|
|
400
|
-
stops: [
|
|
401
|
-
{ offset: 0, color: "#3b82f6" },
|
|
402
|
-
{ offset: 0.5, color: "#8b5cf6" },
|
|
403
|
-
{ offset: 1, color: "#ec4899" }
|
|
404
|
-
]
|
|
405
|
-
}
|
|
406
|
-
};
|
|
407
|
-
function isCanvasGradient(value) {
|
|
408
|
-
if (!value || typeof value !== "object") return false;
|
|
409
|
-
const val = value;
|
|
410
|
-
if (val.type !== "linear" && val.type !== "radial") return false;
|
|
411
|
-
if (!Array.isArray(val.stops)) return false;
|
|
412
|
-
return true;
|
|
413
|
-
}
|
|
414
|
-
function splitCssArgs(str) {
|
|
415
|
-
const parts = [];
|
|
416
|
-
let depth = 0;
|
|
417
|
-
let current = "";
|
|
418
|
-
for (let i = 0; i < str.length; i++) {
|
|
419
|
-
const char = str[i];
|
|
420
|
-
if (char === "(") depth++;
|
|
421
|
-
else if (char === ")") depth = Math.max(0, depth - 1);
|
|
422
|
-
if (char === "," && depth === 0) {
|
|
423
|
-
if (current.trim()) parts.push(current.trim());
|
|
424
|
-
current = "";
|
|
425
|
-
} else {
|
|
426
|
-
current += char;
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
if (current.trim()) parts.push(current.trim());
|
|
430
|
-
return parts;
|
|
431
|
-
}
|
|
432
|
-
function parseCssAngle(val) {
|
|
433
|
-
const trimmed = val.trim().toLowerCase();
|
|
434
|
-
if (trimmed.endsWith("deg")) {
|
|
435
|
-
return parseFloat(trimmed);
|
|
436
|
-
}
|
|
437
|
-
if (trimmed.endsWith("turn")) {
|
|
438
|
-
return parseFloat(trimmed) * 360;
|
|
439
|
-
}
|
|
440
|
-
if (trimmed.endsWith("rad")) {
|
|
441
|
-
return parseFloat(trimmed) * 180 / Math.PI;
|
|
442
|
-
}
|
|
443
|
-
if (trimmed.startsWith("to ")) {
|
|
444
|
-
const dir = trimmed.slice(3).trim();
|
|
445
|
-
if (dir === "bottom") return 180;
|
|
446
|
-
if (dir === "top") return 0;
|
|
447
|
-
if (dir === "right") return 90;
|
|
448
|
-
if (dir === "left") return 270;
|
|
449
|
-
if (dir === "bottom right" || dir === "right bottom") return 135;
|
|
450
|
-
if (dir === "bottom left" || dir === "left bottom") return 225;
|
|
451
|
-
if (dir === "top right" || dir === "right top") return 45;
|
|
452
|
-
if (dir === "top left" || dir === "left top") return 315;
|
|
453
|
-
}
|
|
454
|
-
const n = parseFloat(trimmed);
|
|
455
|
-
return Number.isFinite(n) ? n : 180;
|
|
456
|
-
}
|
|
457
|
-
function parseCssGradient(css) {
|
|
458
|
-
const trimmed = css.trim();
|
|
459
|
-
const linearMatch = trimmed.match(/^linear-gradient\s*\((.*)\)$/is);
|
|
460
|
-
if (linearMatch) {
|
|
461
|
-
const rawArgs = splitCssArgs(linearMatch[1]);
|
|
462
|
-
if (rawArgs.length === 0) return null;
|
|
463
|
-
let angle = 180;
|
|
464
|
-
let stopStartIndex = 0;
|
|
465
|
-
const first = rawArgs[0].trim().toLowerCase();
|
|
466
|
-
if (first.endsWith("deg") || first.endsWith("turn") || first.endsWith("rad") || first.startsWith("to ")) {
|
|
467
|
-
angle = parseCssAngle(first);
|
|
468
|
-
stopStartIndex = 1;
|
|
469
|
-
}
|
|
470
|
-
const stopStrings = rawArgs.slice(stopStartIndex);
|
|
471
|
-
if (stopStrings.length === 0) return null;
|
|
472
|
-
const stops = parseStopStrings(stopStrings);
|
|
473
|
-
if (stops.length === 0) return null;
|
|
474
|
-
return {
|
|
475
|
-
type: "linear",
|
|
476
|
-
angle,
|
|
477
|
-
stops
|
|
478
|
-
};
|
|
479
|
-
}
|
|
480
|
-
const radialMatch = trimmed.match(/^radial-gradient\s*\((.*)\)$/is);
|
|
481
|
-
if (radialMatch) {
|
|
482
|
-
const rawArgs = splitCssArgs(radialMatch[1]);
|
|
483
|
-
if (rawArgs.length === 0) return null;
|
|
484
|
-
let stopStartIndex = 0;
|
|
485
|
-
const first = rawArgs[0].trim().toLowerCase();
|
|
486
|
-
if (first.startsWith("circle") || first.startsWith("ellipse") || first.includes("at ")) {
|
|
487
|
-
stopStartIndex = 1;
|
|
488
|
-
}
|
|
489
|
-
const stopStrings = rawArgs.slice(stopStartIndex);
|
|
490
|
-
if (stopStrings.length === 0) return null;
|
|
491
|
-
const stops = parseStopStrings(stopStrings);
|
|
492
|
-
if (stops.length === 0) return null;
|
|
493
|
-
return {
|
|
494
|
-
type: "radial",
|
|
495
|
-
cx: 0.5,
|
|
496
|
-
cy: 0.5,
|
|
497
|
-
r: 0.5,
|
|
498
|
-
stops
|
|
499
|
-
};
|
|
500
|
-
}
|
|
501
|
-
return null;
|
|
502
|
-
}
|
|
503
|
-
function parseStopStrings(stopStrings) {
|
|
504
|
-
const count = stopStrings.length;
|
|
505
|
-
return stopStrings.map((str, idx) => {
|
|
506
|
-
const parts = str.trim().split(/\s+(?=[0-9%])/);
|
|
507
|
-
const color = parts[0];
|
|
508
|
-
let offset = count === 1 ? 0 : idx / (count - 1);
|
|
509
|
-
if (parts.length > 1) {
|
|
510
|
-
const posStr = parts[1].trim();
|
|
511
|
-
if (posStr.endsWith("%")) {
|
|
512
|
-
offset = parseFloat(posStr) / 100;
|
|
513
|
-
} else {
|
|
514
|
-
const val = parseFloat(posStr);
|
|
515
|
-
if (Number.isFinite(val)) offset = val;
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
return {
|
|
519
|
-
offset: Math.min(1, Math.max(0, offset)),
|
|
520
|
-
color
|
|
521
|
-
};
|
|
522
|
-
});
|
|
523
|
-
}
|
|
524
|
-
function resolveCanvasGradient(value) {
|
|
525
|
-
if (!value) return null;
|
|
526
|
-
if (isCanvasGradient(value)) return value;
|
|
527
|
-
if (typeof value === "string") {
|
|
528
|
-
const lower = value.trim().toLowerCase();
|
|
529
|
-
if (CANVAS_GRADIENT_PRESETS[lower]) {
|
|
530
|
-
return CANVAS_GRADIENT_PRESETS[lower];
|
|
531
|
-
}
|
|
532
|
-
if (lower.startsWith("linear-gradient") || lower.startsWith("radial-gradient")) {
|
|
533
|
-
return parseCssGradient(value);
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
return null;
|
|
537
|
-
}
|
|
538
|
-
function angleToSvgLinearCoords(angleDeg = 180) {
|
|
539
|
-
const rad = (90 - angleDeg) * Math.PI / 180;
|
|
540
|
-
const dx = Math.cos(rad);
|
|
541
|
-
const dy = -Math.sin(rad);
|
|
542
|
-
const half = 0.5;
|
|
543
|
-
return {
|
|
544
|
-
x1: Math.round((half - dx * half) * 1e3) / 1e3,
|
|
545
|
-
y1: Math.round((half - dy * half) * 1e3) / 1e3,
|
|
546
|
-
x2: Math.round((half + dx * half) * 1e3) / 1e3,
|
|
547
|
-
y2: Math.round((half + dy * half) * 1e3) / 1e3
|
|
548
|
-
};
|
|
549
|
-
}
|
|
550
|
-
function gradientToSvgDef(gradient, id) {
|
|
551
|
-
const stops = (_nullishCoalesce(gradient.stops, () => ( []))).map((s) => ({
|
|
552
|
-
offset: `${Math.round(s.offset * 1e3) / 10}%`,
|
|
553
|
-
stopColor: s.color,
|
|
554
|
-
stopOpacity: s.opacity
|
|
555
|
-
}));
|
|
556
|
-
if (gradient.type === "radial") {
|
|
557
|
-
return {
|
|
558
|
-
id,
|
|
559
|
-
type: "radial",
|
|
560
|
-
attrs: {
|
|
561
|
-
cx: gradient.cx !== void 0 ? `${gradient.cx * 100}%` : "50%",
|
|
562
|
-
cy: gradient.cy !== void 0 ? `${gradient.cy * 100}%` : "50%",
|
|
563
|
-
r: gradient.r !== void 0 ? `${gradient.r * 100}%` : "50%"
|
|
564
|
-
},
|
|
565
|
-
stops
|
|
566
|
-
};
|
|
567
|
-
}
|
|
568
|
-
const coords = angleToSvgLinearCoords(_nullishCoalesce(gradient.angle, () => ( 180)));
|
|
569
|
-
return {
|
|
570
|
-
id,
|
|
571
|
-
type: "linear",
|
|
572
|
-
attrs: {
|
|
573
|
-
x1: `${coords.x1 * 100}%`,
|
|
574
|
-
y1: `${coords.y1 * 100}%`,
|
|
575
|
-
x2: `${coords.x2 * 100}%`,
|
|
576
|
-
y2: `${coords.y2 * 100}%`
|
|
577
|
-
},
|
|
578
|
-
stops
|
|
579
|
-
};
|
|
580
|
-
}
|
|
581
|
-
|
|
582
582
|
// src/canvas/shapeGeometry.ts
|
|
583
583
|
var SHAPE_KINDS = ["rect", "ellipse", "polygon", "star", "path"];
|
|
584
584
|
function isShapeDescription(value) {
|
|
@@ -3889,5 +3889,5 @@ function offsetPath(input, distance, options = {}) {
|
|
|
3889
3889
|
|
|
3890
3890
|
|
|
3891
3891
|
|
|
3892
|
-
exports.
|
|
3893
|
-
//# sourceMappingURL=chunk-
|
|
3892
|
+
exports.PIXERATE_BRAND_GRADIENT = PIXERATE_BRAND_GRADIENT; exports.CANVAS_GRADIENT_PRESETS = CANVAS_GRADIENT_PRESETS; exports.isCanvasGradient = isCanvasGradient; exports.parseCssGradient = parseCssGradient; exports.resolveCanvasGradient = resolveCanvasGradient; exports.angleToSvgLinearCoords = angleToSvgLinearCoords; exports.gradientToSvgDef = gradientToSvgDef; exports.cubicPointAt = cubicPointAt; exports.fitCubicWithTangents = fitCubicWithTangents; exports.fitCubicRun = fitCubicRun; exports.fitCubics = fitCubics; exports.isStraightCubic = isStraightCubic; exports.cubicsToPathData = cubicsToPathData; exports.fitPathData = fitPathData; exports.fitFreehandPath = fitFreehandPath; exports.SHAPE_KINDS = SHAPE_KINDS; exports.isShapeDescription = isShapeDescription; exports.parseSvgPath = parseSvgPath; exports.flattenSvgPath = flattenSvgPath; exports.getShapeSvg = getShapeSvg; exports.getShapeRenderData = getShapeRenderData; exports.shapeToPolygon = shapeToPolygon; exports.formatNumber = formatNumber2; exports.simplifyRing = simplifyRing; exports.polygonToSvgPath = polygonToSvgPath; exports.dist = dist2; exports.segmentPoint = segmentPoint; exports.segmentDerivative = segmentDerivative; exports.segmentTangent = segmentTangent; exports.segmentCurvature = segmentCurvature; exports.splitSegment = splitSegment; exports.subSegment = subSegment; exports.segmentExtrema = segmentExtrema; exports.segmentBounds = segmentBounds; exports.segmentLength = segmentLength; exports.segmentParamAtLength = segmentParamAtLength; exports.segmentNearest = segmentNearest; exports.arcToCubics = arcToCubics; exports.toBezierPath = toBezierPath; exports.pathToContours = pathToContours; exports.contoursToPath = contoursToPath; exports.bezierPathToSvg = bezierPathToSvg; exports.transformBezierPath = transformBezierPath; exports.countPathSegments = countPathSegments; exports.closeContour = closeContour; exports.bezierPathBounds = bezierPathBounds; exports.bezierPathSignedArea = bezierPathSignedArea; exports.contourSignedArea = contourSignedArea; exports.bezierPathLength = bezierPathLength; exports.bezierPathPointAtLength = bezierPathPointAtLength; exports.trimSegments = trimSegments; exports.solveMonotone = solveMonotone; exports.windingNumber = windingNumber; exports.pointInBezierPath = pointInBezierPath; exports.distanceToBezierPath = distanceToBezierPath; exports.flattenChain = flattenChain; exports.ringSignedArea = ringSignedArea; exports.polygonArea = polygonArea; exports.multiPolygonArea = multiPolygonArea; exports.multiPolygonBounds = multiPolygonBounds; exports.pointInRings = pointInRings; exports.pointInMultiPolygon = pointInMultiPolygon; exports.polygonBoolean = polygonBoolean; exports.unionPolygons = unionPolygons; exports.intersectPolygons = intersectPolygons; exports.subtractPolygons = subtractPolygons; exports.xorPolygons = xorPolygons; exports.dividePolygons = dividePolygons; exports.PathOpsError = PathOpsError; exports.segmentIntersections = segmentIntersections; exports.pathBoolean = pathBoolean; exports.unitePaths = unitePaths; exports.intersectPaths = intersectPaths; exports.subtractPaths = subtractPaths; exports.excludePaths = excludePaths; exports.dividePaths = dividePaths; exports.normalizeBezierPath = normalizeBezierPath; exports.bezierPathArea = bezierPathArea; exports.planarSplit = planarSplit; exports.pathBooleanSelect = pathBooleanSelect; exports.dashContours = dashContours; exports.strokeOutlineRings = strokeOutlineRings; exports.outlineStroke = outlineStroke; exports.offsetPath = offsetPath;
|
|
3893
|
+
//# sourceMappingURL=chunk-XGD3FSNC.cjs.map
|