@pixerate/editor 0.264.1 → 0.266.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/dist/agent/index.cjs +4 -3
- package/dist/agent/index.js +3 -2
- package/dist/animation-editor/index.cjs +60 -61
- package/dist/animation-editor/index.js +4 -5
- package/dist/brushes/index.cjs +73 -60
- package/dist/brushes/index.d.cts +1 -0
- package/dist/brushes/index.d.ts +1 -0
- package/dist/brushes/index.js +17 -4
- package/dist/brushes/preview.d.cts +59 -0
- package/dist/brushes/preview.d.ts +59 -0
- package/dist/brushes/tools.d.cts +12 -5
- package/dist/brushes/tools.d.ts +12 -5
- package/dist/{brushstrokeRender-3MOI7PH4.js → brushstrokeRender-4UB6NRJW.js} +11 -4
- package/dist/{brushstrokeRender-SMMPIJF2.cjs → brushstrokeRender-JQ2XQRUD.cjs} +22 -15
- package/dist/canvas/brushstroke.d.cts +6 -1
- package/dist/canvas/brushstroke.d.ts +6 -1
- package/dist/canvas/index.cjs +18 -18
- package/dist/canvas/index.js +4 -4
- package/dist/{chunk-TMDDMJCR.js → chunk-472INMWH.js} +4 -2
- package/dist/chunk-55ALHYJY.js +289 -0
- package/dist/{chunk-F3KKR6DD.cjs → chunk-5OE4ZZ6V.cjs} +30 -30
- package/dist/{chunk-BY5EBP26.cjs → chunk-677777GH.cjs} +3 -3
- package/dist/{chunk-NHA26O5X.cjs → chunk-7KNW3WXZ.cjs} +14 -12
- package/dist/{chunk-G5ADO47G.cjs → chunk-7NQOGWLM.cjs} +3 -2
- package/dist/{chunk-WWI6FLH2.js → chunk-7PW6VCNW.js} +2 -2
- package/dist/{chunk-CECCP2V7.js → chunk-BLR4KWYQ.js} +1 -1
- package/dist/chunk-DEBIFWY6.cjs +77 -0
- package/dist/{chunk-KXNZNOEF.cjs → chunk-DGXTEPCU.cjs} +94 -94
- package/dist/{chunk-3CI7FRMK.js → chunk-DVPQFMH6.js} +13 -1
- package/dist/chunk-E2Z4UARJ.cjs +289 -0
- package/dist/chunk-HAEB3MZD.js +664 -0
- package/dist/{chunk-EE7SAYBF.js → chunk-J4SGJCPW.js} +3 -3
- package/dist/{chunk-A2IS7EHE.cjs → chunk-JBZRVLXV.cjs} +14 -2
- package/dist/chunk-KIJIONZF.cjs +664 -0
- package/dist/{chunk-V7MJ4HIN.cjs → chunk-NOP4Y5AB.cjs} +23 -23
- package/dist/{chunk-FQC5TDB6.cjs → chunk-O53MOGXG.cjs} +35 -35
- package/dist/{chunk-LPFQHVCO.js → chunk-PXXXRCME.js} +1 -284
- package/dist/{chunk-4OJC4MCD.js → chunk-Q6RVVJW6.js} +1 -1
- package/dist/{chunk-T7QSEKDY.cjs → chunk-QJVOJUTD.cjs} +4 -287
- package/dist/{chunk-HAUDEVMC.js → chunk-WY23AUCA.js} +2 -2
- package/dist/{chunk-JEML4FSA.js → chunk-XDNWQMHY.js} +3 -2
- package/dist/{chunk-ROBSFJ6F.js → chunk-Z2Z2OHRM.js} +1 -1
- package/dist/{chunk-USJX5SW4.cjs → chunk-ZHRVCW3M.cjs} +12 -12
- package/dist/chunk-ZS7LB2MV.js +77 -0
- package/dist/commands/index.cjs +26 -656
- package/dist/commands/index.js +18 -648
- package/dist/image-editor/index.cjs +788 -790
- package/dist/image-editor/index.js +6 -8
- package/dist/paint-editor/index.cjs +88 -84
- package/dist/paint-editor/index.js +12 -8
- package/dist/vector/contract.d.cts +52 -0
- package/dist/vector/contract.d.ts +52 -0
- package/dist/vector/index.cjs +1168 -971
- package/dist/vector/index.d.cts +1 -0
- package/dist/vector/index.d.ts +1 -0
- package/dist/vector/index.js +204 -7
- package/package.json +1 -1
- package/skills/pixerate-brushes/SKILL.md +7 -2
- package/dist/chunk-FJBQTZS4.js +0 -17
- package/dist/chunk-LRTR4ASZ.cjs +0 -17
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
var PLATFORMS = ["mac", "windows", "linux"];
|
|
3
3
|
function detectPlatform() {
|
|
4
4
|
const nav = typeof navigator !== "undefined" ? navigator : void 0;
|
|
5
|
-
const text = `${_nullishCoalesce(_optionalChain([nav, 'optionalAccess',
|
|
6
|
-
if (/Mac|iPod|iPhone|iPad/.test(_optionalChain([nav, 'optionalAccess',
|
|
5
|
+
const text = `${_nullishCoalesce(_optionalChain([nav, 'optionalAccess', _ => _.platform]), () => ( ""))} ${_nullishCoalesce(_optionalChain([nav, 'optionalAccess', _2 => _2.userAgent]), () => ( ""))}`;
|
|
6
|
+
if (/Mac|iPod|iPhone|iPad/.test(_optionalChain([nav, 'optionalAccess', _3 => _3.platform]) || _optionalChain([nav, 'optionalAccess', _4 => _4.userAgent]) || "")) return "mac";
|
|
7
7
|
if (/Win/.test(text)) return "windows";
|
|
8
8
|
return "linux";
|
|
9
9
|
}
|
|
@@ -222,7 +222,7 @@ function isEditableEventTarget(event) {
|
|
|
222
222
|
if (!target) target = typeof document !== "undefined" ? document.activeElement : null;
|
|
223
223
|
if (!target || typeof target.tagName !== "string") return false;
|
|
224
224
|
const tag = target.tagName.toUpperCase();
|
|
225
|
-
return !!(tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT" || target.isContentEditable || _optionalChain([target, 'access',
|
|
225
|
+
return !!(tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT" || target.isContentEditable || _optionalChain([target, 'access', _5 => _5.getAttribute, 'optionalCall', _6 => _6("contenteditable")]) === "true" || _optionalChain([target, 'access', _7 => _7.closest, 'optionalCall', _8 => _8('[contenteditable="true"]')]) || _optionalChain([target, 'access', _9 => _9.closest, 'optionalCall', _10 => _10(".ProseMirror")]));
|
|
226
226
|
}
|
|
227
227
|
|
|
228
228
|
// src/commands/shortcuts.ts
|
|
@@ -392,289 +392,6 @@ function eitherKey(chord) {
|
|
|
392
392
|
return [(chord.mod || chord.ctrl || chord.meta) && "Mod", chord.alt && "Alt", chord.shift && "Shift", chord.key].filter(Boolean).join("+");
|
|
393
393
|
}
|
|
394
394
|
|
|
395
|
-
// src/canvas/arrangeShortcuts.ts
|
|
396
|
-
var DEFAULT_ARRANGE_SHORTCUTS = [
|
|
397
|
-
{ action: "alignLeft", code: "KeyA", alt: true, label: "Alt+A" },
|
|
398
|
-
{ action: "alignCenter", code: "KeyH", alt: true, label: "Alt+H" },
|
|
399
|
-
{ action: "alignRight", code: "KeyD", alt: true, label: "Alt+D" },
|
|
400
|
-
{ action: "alignTop", code: "KeyW", alt: true, label: "Alt+W" },
|
|
401
|
-
{ action: "alignMiddle", code: "KeyV", alt: true, label: "Alt+V" },
|
|
402
|
-
{ action: "alignBottom", code: "KeyS", alt: true, label: "Alt+S" },
|
|
403
|
-
{ action: "distributeHorizontal", code: "KeyH", alt: true, shift: true, label: "Alt+Shift+H" },
|
|
404
|
-
{ action: "distributeVertical", code: "KeyV", alt: true, shift: true, label: "Alt+Shift+V" },
|
|
405
|
-
{ action: "lock", code: "KeyL", mod: true, label: "Mod+L" },
|
|
406
|
-
{ action: "unlock", code: "KeyL", mod: true, alt: true, label: "Mod+Alt+L" },
|
|
407
|
-
{ action: "bringForward", code: "BracketRight", mod: true, label: "Mod+]" },
|
|
408
|
-
{ action: "sendBackward", code: "BracketLeft", mod: true, label: "Mod+[" },
|
|
409
|
-
{ action: "bringToFront", code: "BracketRight", mod: true, alt: true, label: "Mod+Alt+]" },
|
|
410
|
-
{ action: "sendToBack", code: "BracketLeft", mod: true, alt: true, label: "Mod+Alt+[" },
|
|
411
|
-
{ action: "nextScene", code: "PageDown", label: "PageDown" },
|
|
412
|
-
{ action: "previousScene", code: "PageUp", label: "PageUp" }
|
|
413
|
-
];
|
|
414
|
-
var maps = /* @__PURE__ */ new WeakMap();
|
|
415
|
-
function arrangeShortcutMap(bindings) {
|
|
416
|
-
let map = maps.get(bindings);
|
|
417
|
-
if (!map) {
|
|
418
|
-
map = new ShortcutMap(
|
|
419
|
-
bindings.map((b) => ({
|
|
420
|
-
command: b.action,
|
|
421
|
-
chord: { key: b.code, mod: b.mod, alt: b.alt, shift: b.shift }
|
|
422
|
-
})),
|
|
423
|
-
{ modifierMode: "either" }
|
|
424
|
-
);
|
|
425
|
-
maps.set(bindings, map);
|
|
426
|
-
}
|
|
427
|
-
return map;
|
|
428
|
-
}
|
|
429
|
-
function matchArrangeShortcut(event, bindings = DEFAULT_ARRANGE_SHORTCUTS) {
|
|
430
|
-
return _nullishCoalesce(_optionalChain([arrangeShortcutMap, 'call', _12 => _12(bindings), 'access', _13 => _13.resolve, 'call', _14 => _14(event), 'optionalAccess', _15 => _15.command]), () => ( null));
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
// src/canvas/gestures.ts
|
|
434
|
-
function gestureRandom(seed) {
|
|
435
|
-
let a = seed >>> 0;
|
|
436
|
-
return () => {
|
|
437
|
-
a = a + 1831565813 >>> 0;
|
|
438
|
-
let t = a;
|
|
439
|
-
t = Math.imul(t ^ t >>> 15, t | 1);
|
|
440
|
-
t ^= t + Math.imul(t ^ t >>> 7, t | 61);
|
|
441
|
-
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
442
|
-
};
|
|
443
|
-
}
|
|
444
|
-
function gestureSeed(value) {
|
|
445
|
-
const text = _nullishCoalesce(JSON.stringify(value), () => ( ""));
|
|
446
|
-
let h = 2166136261;
|
|
447
|
-
for (let i = 0; i < text.length; i++) {
|
|
448
|
-
h ^= text.charCodeAt(i);
|
|
449
|
-
h = Math.imul(h, 16777619);
|
|
450
|
-
}
|
|
451
|
-
return h >>> 0;
|
|
452
|
-
}
|
|
453
|
-
function gestureUnion(rects) {
|
|
454
|
-
if (!rects.length) throw new Error("Pass at least one rect.");
|
|
455
|
-
const x = Math.min(...rects.map((r) => r.x));
|
|
456
|
-
const y = Math.min(...rects.map((r) => r.y));
|
|
457
|
-
const right = Math.max(...rects.map((r) => r.x + r.width));
|
|
458
|
-
const bottom = Math.max(...rects.map((r) => r.y + r.height));
|
|
459
|
-
return { x, y, width: right - x, height: bottom - y };
|
|
460
|
-
}
|
|
461
|
-
var clamp = (v, lo, hi) => Math.min(hi, Math.max(lo, v));
|
|
462
|
-
var centre = (r) => [r.x + r.width / 2, r.y + r.height / 2];
|
|
463
|
-
function smoothNoise(rand, octaves = 3) {
|
|
464
|
-
const waves = Array.from({ length: octaves }, (_, i) => ({ f: (i + 1) * (0.6 + rand() * 0.8), phase: rand() * Math.PI * 2, amp: 1 / (i + 1) }));
|
|
465
|
-
const total = waves.reduce((sum, w) => sum + w.amp, 0);
|
|
466
|
-
return (t) => waves.reduce((sum, w) => sum + w.amp * Math.sin(2 * Math.PI * w.f * t + w.phase), 0) / total;
|
|
467
|
-
}
|
|
468
|
-
function handPressure(rand) {
|
|
469
|
-
const r = (lo, hi) => Math.round((lo + rand() * (hi - lo)) * 100) / 100;
|
|
470
|
-
return [r(0.35, 0.55), r(0.8, 0.95), r(0.9, 1), r(0.75, 0.95), r(0.4, 0.65)];
|
|
471
|
-
}
|
|
472
|
-
var round = (p) => [Math.round(p[0] * 100) / 100, Math.round(p[1] * 100) / 100];
|
|
473
|
-
function wobblyLine(a, b, rand, amp, bow = 0) {
|
|
474
|
-
const dx = b[0] - a[0];
|
|
475
|
-
const dy = b[1] - a[1];
|
|
476
|
-
const len = Math.hypot(dx, dy);
|
|
477
|
-
if (len === 0) return [a];
|
|
478
|
-
const nx = -dy / len;
|
|
479
|
-
const ny = dx / len;
|
|
480
|
-
const noise = smoothNoise(rand);
|
|
481
|
-
const n = clamp(Math.ceil(len / 4), 8, 200);
|
|
482
|
-
return Array.from({ length: n + 1 }, (_, i) => {
|
|
483
|
-
const t = i / n;
|
|
484
|
-
const off = bow * 4 * t * (1 - t) + amp * noise(t) * Math.sqrt(Math.sin(Math.PI * t));
|
|
485
|
-
return [a[0] + dx * t + nx * off, a[1] + dy * t + ny * off];
|
|
486
|
-
});
|
|
487
|
-
}
|
|
488
|
-
function circleGesture(rect, seed, options = {}) {
|
|
489
|
-
const rand = gestureRandom(seed);
|
|
490
|
-
const pad = Math.max(0, _nullishCoalesce(options.padding, () => ( 8)));
|
|
491
|
-
const [cx, cy] = centre(rect);
|
|
492
|
-
const tilt = (rand() - 0.5) * 0.08;
|
|
493
|
-
const c = Math.abs(Math.cos(tilt));
|
|
494
|
-
const s = Math.abs(Math.sin(tilt));
|
|
495
|
-
const a = (rect.width / 2 * c + rect.height / 2 * s) * Math.SQRT2 + pad;
|
|
496
|
-
const b = (rect.width / 2 * s + rect.height / 2 * c) * Math.SQRT2 + pad;
|
|
497
|
-
const dir = rand() < 0.7 ? -1 : 1;
|
|
498
|
-
const start = -Math.PI * 0.75 + (rand() - 0.5) * 0.6;
|
|
499
|
-
const sweep = Math.PI * 2 + Math.PI * (0.1 + rand() * 0.12);
|
|
500
|
-
const jitter = 0.03 + rand() * 0.03;
|
|
501
|
-
const drift = 0.04 + rand() * 0.05;
|
|
502
|
-
const noise = smoothNoise(rand, 4);
|
|
503
|
-
const perimeter = Math.PI * (3 * (a + b) - Math.sqrt((3 * a + b) * (a + 3 * b)));
|
|
504
|
-
const n = clamp(Math.ceil(perimeter * (sweep / (Math.PI * 2)) / 5), 48, 360);
|
|
505
|
-
const points = Array.from({ length: n + 1 }, (_, i) => {
|
|
506
|
-
const t = i / n;
|
|
507
|
-
const angle = start + dir * sweep * t;
|
|
508
|
-
const grow = 1 + jitter * (0.5 + 0.5 * noise(t)) + drift * t * t;
|
|
509
|
-
const ex = a * grow * Math.cos(angle);
|
|
510
|
-
const ey = b * grow * Math.sin(angle);
|
|
511
|
-
return round([cx + ex * Math.cos(tilt) - ey * Math.sin(tilt), cy + ex * Math.sin(tilt) + ey * Math.cos(tilt)]);
|
|
512
|
-
});
|
|
513
|
-
return { points, pressure: handPressure(rand) };
|
|
514
|
-
}
|
|
515
|
-
function underlineGesture(rect, seed, options = {}) {
|
|
516
|
-
const rand = gestureRandom(seed);
|
|
517
|
-
const offset = Math.max(0, _nullishCoalesce(options.offset, () => ( 4)));
|
|
518
|
-
const amp = options.wave ? clamp(rect.width * 0.02, 2, 4) : 0;
|
|
519
|
-
const shake = Math.min(1.5, offset * 0.4);
|
|
520
|
-
const base = rect.y + rect.height + offset + amp + shake;
|
|
521
|
-
const slope = Math.min(6, rect.width * 0.03);
|
|
522
|
-
const x0 = rect.x - rect.width * (0.01 + rand() * 0.04);
|
|
523
|
-
const x1 = rect.x + rect.width * (0.96 + rand() * 0.08);
|
|
524
|
-
const line = wobblyLine([x0, base + rand() * slope], [x1, base + rand() * slope], rand, shake, (rand() - 0.5) * 2 * shake);
|
|
525
|
-
const wavelength = clamp(rect.width / 8, 12, 28);
|
|
526
|
-
const phase = rand() * Math.PI * 2;
|
|
527
|
-
const points = amp ? line.map(([x, y]) => [x, y + amp * Math.sin(2 * Math.PI * (x - x0) / wavelength + phase)]) : line;
|
|
528
|
-
return { points: points.map(round), pressure: handPressure(rand) };
|
|
529
|
-
}
|
|
530
|
-
function gestureEdgePoint(rect, toward, gap = 0) {
|
|
531
|
-
const [cx, cy] = centre(rect);
|
|
532
|
-
const dx = toward[0] - cx;
|
|
533
|
-
const dy = toward[1] - cy;
|
|
534
|
-
const len = Math.hypot(dx, dy);
|
|
535
|
-
if (len === 0) return [cx, cy];
|
|
536
|
-
const t = Math.min(dx ? rect.width / 2 / Math.abs(dx) : Infinity, dy ? rect.height / 2 / Math.abs(dy) : Infinity);
|
|
537
|
-
return [cx + dx * t + dx / len * gap, cy + dy * t + dy / len * gap];
|
|
538
|
-
}
|
|
539
|
-
var isRect = (end) => !Array.isArray(end);
|
|
540
|
-
function arrowGesture(from, to, seed, options = {}) {
|
|
541
|
-
const rand = gestureRandom(seed);
|
|
542
|
-
const gap = Math.max(0, _nullishCoalesce(options.gap, () => ( 6)));
|
|
543
|
-
const fromCentre = isRect(from) ? centre(from) : from;
|
|
544
|
-
const toCentre = isRect(to) ? centre(to) : to;
|
|
545
|
-
const start = isRect(from) ? gestureEdgePoint(from, toCentre, gap) : from;
|
|
546
|
-
const tip = isRect(to) ? gestureEdgePoint(to, fromCentre, gap) : to;
|
|
547
|
-
const dx = tip[0] - start[0];
|
|
548
|
-
const dy = tip[1] - start[1];
|
|
549
|
-
const len = Math.hypot(dx, dy);
|
|
550
|
-
if (len < 4) throw new Error("The arrow's ends are too close together (or overlap): pass ends at least a few canvas units apart.");
|
|
551
|
-
const curve = clamp(_nullishCoalesce(options.curve, () => ( (0.08 + rand() * 0.08) * (rand() < 0.5 ? -1 : 1))), -1, 1);
|
|
552
|
-
const nx = -dy / len;
|
|
553
|
-
const ny = dx / len;
|
|
554
|
-
const control = [(start[0] + tip[0]) / 2 + nx * curve * len, (start[1] + tip[1]) / 2 + ny * curve * len];
|
|
555
|
-
const noise = smoothNoise(rand);
|
|
556
|
-
const amp = Math.min(2, len * 0.01);
|
|
557
|
-
const n = clamp(Math.ceil(len / 4), 12, 200);
|
|
558
|
-
const shaft = Array.from({ length: n + 1 }, (_, i) => {
|
|
559
|
-
const t = i / n;
|
|
560
|
-
const u = 1 - t;
|
|
561
|
-
const x = u * u * start[0] + 2 * u * t * control[0] + t * t * tip[0];
|
|
562
|
-
const y = u * u * start[1] + 2 * u * t * control[1] + t * t * tip[1];
|
|
563
|
-
const off = amp * noise(t) * Math.sqrt(Math.sin(Math.PI * t));
|
|
564
|
-
return [x + nx * off, y + ny * off];
|
|
565
|
-
});
|
|
566
|
-
const tx = tip[0] - control[0];
|
|
567
|
-
const ty = tip[1] - control[1];
|
|
568
|
-
const tl = Math.hypot(tx, ty) || 1;
|
|
569
|
-
const head = clamp(len * 0.15, 8, 22);
|
|
570
|
-
const barb = (angle2, length) => {
|
|
571
|
-
const c = Math.cos(angle2);
|
|
572
|
-
const s = Math.sin(angle2);
|
|
573
|
-
const bx = -(tx / tl) * c + ty / tl * s;
|
|
574
|
-
const by = -(ty / tl) * c - tx / tl * s;
|
|
575
|
-
return [1 / 3, 2 / 3, 1].map((f) => [tip[0] + bx * length * f, tip[1] + by * length * f]);
|
|
576
|
-
};
|
|
577
|
-
const clear = (pts) => !isRect(to) || pts.every(([x, y]) => x <= to.x || x >= to.x + to.width || y <= to.y || y >= to.y + to.height);
|
|
578
|
-
const fit = (angle2) => {
|
|
579
|
-
const length = head * (0.85 + rand() * 0.3);
|
|
580
|
-
for (let k = 1; k > 0.05; k -= 0.15) {
|
|
581
|
-
const pts = barb(angle2 * k, length);
|
|
582
|
-
if (clear(pts)) return pts;
|
|
583
|
-
}
|
|
584
|
-
return barb(0, length);
|
|
585
|
-
};
|
|
586
|
-
const angle = () => (25 + rand() * 8) * Math.PI / 180;
|
|
587
|
-
const first = fit(angle());
|
|
588
|
-
const second = fit(-angle());
|
|
589
|
-
const points = [...shaft, ...first, ...first.slice(0, -1).reverse(), tip, ...second];
|
|
590
|
-
return { points: points.map(round), pressure: handPressure(rand) };
|
|
591
|
-
}
|
|
592
|
-
function bracketGesture(rect, side, seed, options = {}) {
|
|
593
|
-
const rand = gestureRandom(seed);
|
|
594
|
-
const pad = Math.max(0, _nullishCoalesce(options.padding, () => ( 8)));
|
|
595
|
-
const vertical = side === "left" || side === "right";
|
|
596
|
-
const span = vertical ? rect.height : rect.width;
|
|
597
|
-
const depth = Math.max(1, _nullishCoalesce(options.depth, () => ( clamp(span * 0.08, 6, 20))));
|
|
598
|
-
const from = vertical ? rect.y : rect.x;
|
|
599
|
-
const edge = side === "left" ? rect.x - pad : side === "right" ? rect.x + rect.width + pad : side === "top" ? rect.y - pad : rect.y + rect.height + pad;
|
|
600
|
-
const out = side === "left" || side === "top" ? -1 : 1;
|
|
601
|
-
const at = (s, d) => vertical ? [edge + out * d, from + s * span] : [from + s * span, edge + out * d];
|
|
602
|
-
const noise = smoothNoise(rand);
|
|
603
|
-
const shake = Math.min(1, depth * 0.06);
|
|
604
|
-
const n = clamp(Math.ceil(span / 4), 24, 240);
|
|
605
|
-
let points;
|
|
606
|
-
if (options.shape === "square") {
|
|
607
|
-
const arm = depth * (0.8 + rand() * 0.2);
|
|
608
|
-
const spine = Array.from({ length: n + 1 }, (_, i) => at(i / n, depth + shake * (1 + noise(i / n))));
|
|
609
|
-
points = [at(0, depth - arm), at(0, depth * 0.5), ...spine, at(1, depth * 0.5), at(1, depth - arm * (0.85 + rand() * 0.15))];
|
|
610
|
-
} else {
|
|
611
|
-
const e = clamp(depth / Math.max(span, 1), 0.04, 0.2);
|
|
612
|
-
const brace = (s) => {
|
|
613
|
-
const u = s <= 0.5 ? s : 1 - s;
|
|
614
|
-
if (u < e) return depth / 2 * Math.sin(Math.PI / 2 * u / e);
|
|
615
|
-
if (u < 0.5 - e) return depth / 2;
|
|
616
|
-
return depth / 2 + depth / 2 * (1 - Math.cos(Math.PI / 2 * (u - (0.5 - e)) / e));
|
|
617
|
-
};
|
|
618
|
-
points = Array.from({ length: n + 1 }, (_, i) => {
|
|
619
|
-
const s = i / n;
|
|
620
|
-
return at(s, brace(s) + shake * (1 + noise(s)) * Math.sin(Math.PI * s));
|
|
621
|
-
});
|
|
622
|
-
}
|
|
623
|
-
return { points: points.map(round), pressure: handPressure(rand) };
|
|
624
|
-
}
|
|
625
|
-
function strikeGesture(rect, seed) {
|
|
626
|
-
const rand = gestureRandom(seed);
|
|
627
|
-
const [, cy] = centre(rect);
|
|
628
|
-
const slope = rect.height * 0.08;
|
|
629
|
-
const x0 = rect.x - rect.width * (0.01 + rand() * 0.03);
|
|
630
|
-
const x1 = rect.x + rect.width * (1.01 + rand() * 0.03);
|
|
631
|
-
const y0 = cy + (rand() - 0.5) * rect.height * 0.1 + slope * (rand() - 0.5);
|
|
632
|
-
const y1 = cy + (rand() - 0.5) * rect.height * 0.1 + slope * (rand() - 0.5);
|
|
633
|
-
const points = wobblyLine([x0, y0], [x1, y1], rand, Math.min(1.5, rect.height * 0.05));
|
|
634
|
-
return { points: points.map(round), pressure: handPressure(rand) };
|
|
635
|
-
}
|
|
636
|
-
function crossGesture(rect, seed) {
|
|
637
|
-
const rand = gestureRandom(seed);
|
|
638
|
-
const over = () => 0.02 + rand() * 0.04;
|
|
639
|
-
const left = () => rect.x - rect.width * over();
|
|
640
|
-
const right = () => rect.x + rect.width * (1 + over());
|
|
641
|
-
const top = () => rect.y - rect.height * over();
|
|
642
|
-
const bottom = () => rect.y + rect.height * (1 + over());
|
|
643
|
-
const amp = Math.min(1.5, Math.min(rect.width, rect.height) * 0.03);
|
|
644
|
-
const first = wobblyLine([left(), top()], [right(), bottom()], rand, amp);
|
|
645
|
-
const second = wobblyLine([right(), top()], [left(), bottom()], rand, amp);
|
|
646
|
-
const mid1 = Math.floor(first.length / 2);
|
|
647
|
-
const mid2 = Math.floor(second.length / 2);
|
|
648
|
-
const points = [...first, ...first.slice(mid1, -1).reverse(), ...second.slice(1, mid2 + 1).reverse(), ...second];
|
|
649
|
-
return { points: points.map(round), pressure: handPressure(rand) };
|
|
650
|
-
}
|
|
651
|
-
function checkGesture(at, seed, options = {}) {
|
|
652
|
-
const rand = gestureRandom(seed);
|
|
653
|
-
const [cx, cy] = isRect(at) ? centre(at) : at;
|
|
654
|
-
const s = Math.max(4, _nullishCoalesce(options.size, () => ( (isRect(at) ? clamp(Math.min(at.width, at.height) * 0.6, 12, 48) : 20))));
|
|
655
|
-
const turn = (rand() - 0.5) * 12 * Math.PI / 180;
|
|
656
|
-
const place = ([x, y]) => [cx + s * (x * Math.cos(turn) - y * Math.sin(turn)), cy + s * (x * Math.sin(turn) + y * Math.cos(turn))];
|
|
657
|
-
const p0 = [-0.42 + rand() * 0.08, -0.05 + rand() * 0.08];
|
|
658
|
-
const p1 = [-0.12 + rand() * 0.06, 0.38 + rand() * 0.06];
|
|
659
|
-
const p2 = [0.48 + rand() * 0.06, -0.5 + rand() * 0.06];
|
|
660
|
-
const short = wobblyLine(place(p0), place(p1), rand, 0, -s * 0.03);
|
|
661
|
-
const long = wobblyLine(place(p1), place(p2), rand, Math.min(1, s * 0.02), s * 0.06);
|
|
662
|
-
return { points: [...short, ...long.slice(1)].map(round), pressure: [0.5, 0.95, 0.9, 0.7, 0.35] };
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
395
|
|
|
679
396
|
|
|
680
397
|
|
|
@@ -692,4 +409,4 @@ function checkGesture(at, seed, options = {}) {
|
|
|
692
409
|
|
|
693
410
|
|
|
694
411
|
|
|
695
|
-
exports.PLATFORMS = PLATFORMS; exports.detectPlatform = detectPlatform; exports.keyToCode = keyToCode; exports.codeToKeyText = codeToKeyText; exports.parseChord = parseChord; exports.chordToString = chordToString; exports.normalizeChord = normalizeChord; exports.effectiveChord = effectiveChord; exports.effectiveChordKey = effectiveChordKey; exports.formatShortcut = formatShortcut; exports.eventCode = eventCode; exports.shortcutCode = shortcutCode; exports.codeFromKey = codeFromKey; exports.isEditableEventTarget = isEditableEventTarget; exports.toShortcutBindings = toShortcutBindings; exports.ShortcutMap = ShortcutMap;
|
|
412
|
+
exports.PLATFORMS = PLATFORMS; exports.detectPlatform = detectPlatform; exports.keyToCode = keyToCode; exports.codeToKeyText = codeToKeyText; exports.parseChord = parseChord; exports.chordToString = chordToString; exports.normalizeChord = normalizeChord; exports.effectiveChord = effectiveChord; exports.effectiveChordKey = effectiveChordKey; exports.formatShortcut = formatShortcut; exports.eventCode = eventCode; exports.shortcutCode = shortcutCode; exports.codeFromKey = codeFromKey; exports.isEditableEventTarget = isEditableEventTarget; exports.toShortcutBindings = toShortcutBindings; exports.ShortcutMap = ShortcutMap;
|
|
@@ -108,7 +108,7 @@ import {
|
|
|
108
108
|
transformTextRect,
|
|
109
109
|
translateMatrix,
|
|
110
110
|
warpPresetMesh
|
|
111
|
-
} from "./chunk-
|
|
111
|
+
} from "./chunk-7PW6VCNW.js";
|
|
112
112
|
import {
|
|
113
113
|
bezierPathBounds,
|
|
114
114
|
outlineStroke,
|
|
@@ -119,7 +119,7 @@ import {
|
|
|
119
119
|
} from "./chunk-WEIK3UYB.js";
|
|
120
120
|
import {
|
|
121
121
|
parseCssColor
|
|
122
|
-
} from "./chunk-
|
|
122
|
+
} from "./chunk-DVPQFMH6.js";
|
|
123
123
|
import {
|
|
124
124
|
MAX_BRUSH_SIZE
|
|
125
125
|
} from "./chunk-GCVFEPJG.js";
|
|
@@ -74,7 +74,7 @@ function profileAlongPolyline(points, values, count = 32) {
|
|
|
74
74
|
var round3 = (v) => Math.round(v * 1e3) / 1e3;
|
|
75
75
|
var loading = null;
|
|
76
76
|
function loadCanvasBrushstrokeRenderer() {
|
|
77
|
-
loading ??= import("./brushstrokeRender-
|
|
77
|
+
loading ??= import("./brushstrokeRender-4UB6NRJW.js").catch((error) => {
|
|
78
78
|
loading = null;
|
|
79
79
|
throw error;
|
|
80
80
|
});
|
|
@@ -117,7 +117,8 @@ async function renderCanvasBrushSwatch(brush, options = {}, spec) {
|
|
|
117
117
|
return (await loadCanvasBrushstrokeRenderer()).brushSwatchNow(brush, options, spec);
|
|
118
118
|
}
|
|
119
119
|
var renderCanvasBrushPreview = async (brush, { width, height, color }) => {
|
|
120
|
-
const
|
|
120
|
+
const { light: _light, ...plain } = brush;
|
|
121
|
+
const url = await renderCanvasBrushSwatch(brush.id, { width, height, color, scale: 1 }, plain);
|
|
121
122
|
return { data: url.replace(/^data:image\/png;base64,/, ""), mimeType: "image/png" };
|
|
122
123
|
};
|
|
123
124
|
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
var
|
|
10
|
+
var _chunk677777GHcjs = require('./chunk-677777GH.cjs');
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
var _chunkCVFAAZXEcjs = require('./chunk-CVFAAZXE.cjs');
|
|
@@ -51,7 +51,7 @@ var _chunkGF2RBSDMcjs = require('./chunk-GF2RBSDM.cjs');
|
|
|
51
51
|
var _chunkNM3G4VQTcjs = require('./chunk-NM3G4VQT.cjs');
|
|
52
52
|
|
|
53
53
|
|
|
54
|
-
var
|
|
54
|
+
var _chunkJBZRVLXVcjs = require('./chunk-JBZRVLXV.cjs');
|
|
55
55
|
|
|
56
56
|
|
|
57
57
|
|
|
@@ -2536,11 +2536,11 @@ function vectorExtrudeFaces(path, params) {
|
|
|
2536
2536
|
|
|
2537
2537
|
// src/vector/brushstroke.ts
|
|
2538
2538
|
var VECTOR_BRUSHSTROKE_SCALE = 2;
|
|
2539
|
-
var PRESETS =
|
|
2539
|
+
var PRESETS = _chunk677777GHcjs.listPresets.call(void 0, _chunk677777GHcjs.VECTOR_PROFILE).map((spec) => _chunk677777GHcjs.BUILTIN_BRUSHES.find((b) => b.id === spec.id));
|
|
2540
2540
|
function admitted(spec) {
|
|
2541
2541
|
try {
|
|
2542
|
-
const brush =
|
|
2543
|
-
return
|
|
2542
|
+
const brush = _chunk677777GHcjs.normalizeBrushSpec.call(void 0, spec);
|
|
2543
|
+
return _chunk677777GHcjs.checkBrush.call(void 0, brush, _chunk677777GHcjs.VECTOR_PROFILE).ok && _chunkPXDIAYB6cjs.isBrushstrokeBrush.call(void 0, _chunk677777GHcjs.resolveBrush.call(void 0, brush)) ? brush : null;
|
|
2544
2544
|
} catch (e4) {
|
|
2545
2545
|
return null;
|
|
2546
2546
|
}
|
|
@@ -2549,7 +2549,7 @@ function vectorBrushstrokeBrushes(user = []) {
|
|
|
2549
2549
|
const out = [...PRESETS];
|
|
2550
2550
|
for (const raw of user) {
|
|
2551
2551
|
const brush = admitted(raw);
|
|
2552
|
-
if (brush && !out.some((b) => b.id === brush.id)) out.push(
|
|
2552
|
+
if (brush && !out.some((b) => b.id === brush.id)) out.push(_chunk677777GHcjs.resolveBrush.call(void 0, brush));
|
|
2553
2553
|
}
|
|
2554
2554
|
return out;
|
|
2555
2555
|
}
|
|
@@ -2559,7 +2559,7 @@ function vectorBrushstrokeBrush(id) {
|
|
|
2559
2559
|
function vectorBrushstrokeBrushOf(brush) {
|
|
2560
2560
|
if (brush.spec) {
|
|
2561
2561
|
const saved = admitted(brush.spec);
|
|
2562
|
-
return saved && saved.id === brush.brushId ?
|
|
2562
|
+
return saved && saved.id === brush.brushId ? _chunk677777GHcjs.resolveBrush.call(void 0, saved) : null;
|
|
2563
2563
|
}
|
|
2564
2564
|
return vectorBrushstrokeBrush(brush.brushId);
|
|
2565
2565
|
}
|
|
@@ -2567,15 +2567,15 @@ function vectorBrushstrokeBrushError(id, user = []) {
|
|
|
2567
2567
|
if (vectorBrushstrokeBrush(id)) return null;
|
|
2568
2568
|
const saved = user.find((b) => b.id === id);
|
|
2569
2569
|
const ids = vectorBrushstrokeBrushes(user).map((b) => b.id);
|
|
2570
|
-
const reasons = (b) =>
|
|
2570
|
+
const reasons = (b) => _chunk677777GHcjs.checkBrush.call(void 0, b, _chunk677777GHcjs.VECTOR_PROFILE).issues.filter((i) => i.severity === "error").map((i) => `${i.reason} ${i.fix}`).join(" ") || "it is not a dry dab brush.";
|
|
2571
2571
|
if (saved) return admitted(saved) ? null : `Brush "${id}" (${saved.name}) can't paint a brushstroke: ${reasons(saved)} Use one of: ${ids.join(", ")}.`;
|
|
2572
|
-
const preset =
|
|
2572
|
+
const preset = _chunk677777GHcjs.BRUSH_PRESETS.find((b) => b.id === id);
|
|
2573
2573
|
if (preset) return `Brush "${id}" (${preset.name}) can't paint a brushstroke: ${reasons(preset)} Use one of: ${ids.join(", ")}.`;
|
|
2574
|
-
return `Unknown brush "${id}". ${
|
|
2574
|
+
return `Unknown brush "${id}". ${_chunk677777GHcjs.closest.call(void 0, id, ids)}Use one of: ${ids.join(", ")} (vector.listBrushes lists them).`;
|
|
2575
2575
|
}
|
|
2576
2576
|
function vectorBrushstrokeDefaultColour(id, user = [], scheme = "light") {
|
|
2577
|
-
const brush = _nullishCoalesce(
|
|
2578
|
-
return brush ?
|
|
2577
|
+
const brush = _nullishCoalesce(_chunk677777GHcjs.BRUSH_PRESETS.find((b) => b.id === id), () => ( user.find((b) => b.id === id)));
|
|
2578
|
+
return brush ? _chunkJBZRVLXVcjs.brushColourHex.call(void 0, _optionalChain([brush, 'access', _55 => _55.colour, 'optionalAccess', _56 => _56.default]), scheme) : null;
|
|
2579
2579
|
}
|
|
2580
2580
|
function sanitizeVectorBrushstroke(value, user = []) {
|
|
2581
2581
|
if (!value || typeof value !== "object") return null;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PAINT_PROFILE
|
|
3
|
+
} from "./chunk-J4SGJCPW.js";
|
|
4
|
+
import {
|
|
5
|
+
brushColourHex
|
|
6
|
+
} from "./chunk-DVPQFMH6.js";
|
|
7
|
+
import {
|
|
8
|
+
isDualColor
|
|
9
|
+
} from "./chunk-VR6OGHU5.js";
|
|
10
|
+
import {
|
|
11
|
+
formatHex,
|
|
12
|
+
toSrgbGamut
|
|
13
|
+
} from "./chunk-JC2SHA4A.js";
|
|
14
|
+
import {
|
|
15
|
+
contrastRatio,
|
|
16
|
+
oklabToOklch,
|
|
17
|
+
oklabToRgb,
|
|
18
|
+
oklchToOklab,
|
|
19
|
+
parseColor,
|
|
20
|
+
relativeLuminance,
|
|
21
|
+
rgbToOklab
|
|
22
|
+
} from "./chunk-MHLU6GRJ.js";
|
|
23
|
+
|
|
24
|
+
// src/brushes/preview.ts
|
|
25
|
+
var BRUSH_PREVIEW_DARK_PAPER = "#141414";
|
|
26
|
+
var BRUSH_PREVIEW_MIN_CONTRAST = 3;
|
|
27
|
+
var BRUSH_PREVIEW_FALLBACKS = {
|
|
28
|
+
dry: { light: "#3f3f46", dark: "#e4e4e7" },
|
|
29
|
+
ink: { light: "#1e293b", dark: "#e2e8f0" },
|
|
30
|
+
paint: { light: "#1d4ed8", dark: "#93c5fd" },
|
|
31
|
+
spray: { light: "#0f766e", dark: "#5eead4" },
|
|
32
|
+
other: { light: "#334155", dark: "#cbd5e1" },
|
|
33
|
+
tools: { light: "#475569", dark: "#cbd5e1" }
|
|
34
|
+
};
|
|
35
|
+
function brushPreviewsOnDark(brush) {
|
|
36
|
+
return (brush.light?.amount ?? 0) > 0 && brush.tip?.blend !== "multiply";
|
|
37
|
+
}
|
|
38
|
+
var hexOf = (c) => brushColourHex(c, "light") ?? "#ffffff";
|
|
39
|
+
function brushPreviewStrength(brush) {
|
|
40
|
+
const opacity = brush.tip.opacity ?? 1;
|
|
41
|
+
const flow = brush.tip.flow ?? 1;
|
|
42
|
+
const grain = brush.behaviour?.grain ?? 0;
|
|
43
|
+
return Math.max(0.25, Math.min(1, 0.85 * opacity * (0.6 + 0.4 * flow) * (1 - 0.3 * grain)));
|
|
44
|
+
}
|
|
45
|
+
var over = (fg, bg, alpha) => ({ r: fg.r * alpha + bg.r * (1 - alpha), g: fg.g * alpha + bg.g * (1 - alpha), b: fg.b * alpha + bg.b * (1 - alpha), a: 1 });
|
|
46
|
+
function brushPreviewColours(brush, options = {}) {
|
|
47
|
+
const profile = options.profile ?? PAINT_PROFILE;
|
|
48
|
+
let background = profile.light === "full" && brushPreviewsOnDark(brush) ? BRUSH_PREVIEW_DARK_PAPER : hexOf(options.paper ?? "#ffffff");
|
|
49
|
+
if (!options.keepPaper && brush.tip.blend === "multiply" && relativeLuminance(parseColor(background)) < 0.18) background = "#ffffff";
|
|
50
|
+
const bg = parseColor(background);
|
|
51
|
+
const scheme = relativeLuminance(bg) < 0.18 ? "dark" : "light";
|
|
52
|
+
const own = brush.kind === "mark" ? brush.colour?.default : void 0;
|
|
53
|
+
const ownHex = typeof own === "string" || isDualColor(own) ? brushColourHex(own, scheme) : null;
|
|
54
|
+
if (ownHex && brush.tip.blend === "multiply" && (brush.light?.amount ?? 0) > 0 && scheme === "light") return { background, color: ownHex, scheme };
|
|
55
|
+
const group = brush.kind === "tool" ? "tools" : brush.medium ?? "other";
|
|
56
|
+
const color = ownHex ?? brushColourHex(BRUSH_PREVIEW_FALLBACKS[group] ?? BRUSH_PREVIEW_FALLBACKS.other, scheme);
|
|
57
|
+
const alpha = brushPreviewStrength(brush);
|
|
58
|
+
const reads = (c) => contrastRatio(over(c, bg, alpha), bg) >= BRUSH_PREVIEW_MIN_CONTRAST;
|
|
59
|
+
const fg = parseColor(color);
|
|
60
|
+
if (reads(fg)) return { background, color, scheme };
|
|
61
|
+
const lch = oklabToOklch(rgbToOklab(fg));
|
|
62
|
+
const step = scheme === "dark" ? 0.01 : -0.01;
|
|
63
|
+
for (let l = lch.l + step; l >= 0 && l <= 1; l += step) {
|
|
64
|
+
const hex = formatHex(toSrgbGamut(oklabToRgb(oklchToOklab({ ...lch, l }))));
|
|
65
|
+
if (reads(parseColor(hex))) return { background, color: hex, scheme };
|
|
66
|
+
}
|
|
67
|
+
return { background, color: scheme === "dark" ? "#ffffff" : "#000000", scheme };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export {
|
|
71
|
+
BRUSH_PREVIEW_DARK_PAPER,
|
|
72
|
+
BRUSH_PREVIEW_MIN_CONTRAST,
|
|
73
|
+
BRUSH_PREVIEW_FALLBACKS,
|
|
74
|
+
brushPreviewsOnDark,
|
|
75
|
+
brushPreviewStrength,
|
|
76
|
+
brushPreviewColours
|
|
77
|
+
};
|