@weasel-js/paint 1.9.4 → 1.10.1
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/README.md +4 -4
- package/dist/index.d.ts +360 -169
- package/dist/index.js +504 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,3 +1,80 @@
|
|
|
1
|
+
// src/commandPaint.ts
|
|
2
|
+
function isSolidPaint(paint) {
|
|
3
|
+
return paint != null && (paint.kind === void 0 || paint.kind === "solid");
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
// src/paintKey.ts
|
|
7
|
+
function canonical(value) {
|
|
8
|
+
if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
|
|
9
|
+
if (typeof value !== "object" || value === null) return JSON.stringify(value) ?? "null";
|
|
10
|
+
const fields = Object.keys(value).sort().filter((k) => value[k] !== void 0).map((k) => `${JSON.stringify(k)}:${canonical(value[k])}`);
|
|
11
|
+
return `{${fields.join(",")}}`;
|
|
12
|
+
}
|
|
13
|
+
var structuralKeys = /* @__PURE__ */ new WeakMap();
|
|
14
|
+
var strokeShapeKeys = /* @__PURE__ */ new WeakMap();
|
|
15
|
+
function paintKey(paint) {
|
|
16
|
+
if (paint == null) return "none";
|
|
17
|
+
if (isSolidPaint(paint)) return `solid:${paint.color}:${paint.opacity ?? 1}`;
|
|
18
|
+
let key = structuralKeys.get(paint);
|
|
19
|
+
if (key === void 0) {
|
|
20
|
+
key = canonical(paint);
|
|
21
|
+
structuralKeys.set(paint, key);
|
|
22
|
+
}
|
|
23
|
+
return key;
|
|
24
|
+
}
|
|
25
|
+
function fillHasInk(fill) {
|
|
26
|
+
return fill?.paint !== void 0;
|
|
27
|
+
}
|
|
28
|
+
function strokeHasInk(stroke) {
|
|
29
|
+
if (stroke?.paint === void 0) return false;
|
|
30
|
+
const width = stroke.width ?? 1;
|
|
31
|
+
return (typeof width === "number" ? width : width.px) > 0;
|
|
32
|
+
}
|
|
33
|
+
function strokeKey(stroke) {
|
|
34
|
+
if (!strokeHasInk(stroke)) return "none";
|
|
35
|
+
let shape = strokeShapeKeys.get(stroke);
|
|
36
|
+
if (shape === void 0) {
|
|
37
|
+
const { paint: _paint, width, join, cap, miterLimit, align, dash, ...rest } = stroke;
|
|
38
|
+
shape = canonical({
|
|
39
|
+
...rest,
|
|
40
|
+
width: width ?? 1,
|
|
41
|
+
join: join ?? "miter",
|
|
42
|
+
cap: cap ?? "butt",
|
|
43
|
+
miterLimit: miterLimit ?? 4,
|
|
44
|
+
align: align ?? "center",
|
|
45
|
+
dash: dash ?? []
|
|
46
|
+
});
|
|
47
|
+
strokeShapeKeys.set(stroke, shape);
|
|
48
|
+
}
|
|
49
|
+
return `${shape}|${paintKey(stroke.paint)}`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// src/patternPaint.ts
|
|
53
|
+
var TILE_KINDS = ["hatch", "crosshatch", "dots", "chunks"];
|
|
54
|
+
var TILE_KIND_SET = new Set(TILE_KINDS);
|
|
55
|
+
function isTileKind(kind) {
|
|
56
|
+
return kind !== void 0 && TILE_KIND_SET.has(kind);
|
|
57
|
+
}
|
|
58
|
+
function isTilePaint(paint) {
|
|
59
|
+
return isTileKind(paint.kind);
|
|
60
|
+
}
|
|
61
|
+
function isPatternPaint(paint) {
|
|
62
|
+
return paint.kind === "texture" || isTileKind(paint.kind);
|
|
63
|
+
}
|
|
64
|
+
function patternPlacementOf(paint) {
|
|
65
|
+
const { units, origin, transform, opacity } = paint;
|
|
66
|
+
return {
|
|
67
|
+
...units !== void 0 ? { units } : {},
|
|
68
|
+
...origin !== void 0 ? { origin } : {},
|
|
69
|
+
...transform !== void 0 ? { transform } : {},
|
|
70
|
+
...opacity !== void 0 ? { opacity } : {}
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function tileSpecOf(paint) {
|
|
74
|
+
const { units: _units, origin: _origin, transform: _transform, opacity: _opacity, ...spec } = paint;
|
|
75
|
+
return spec;
|
|
76
|
+
}
|
|
77
|
+
|
|
1
78
|
// src/patternTransform.ts
|
|
2
79
|
function composePatternTransform(parts) {
|
|
3
80
|
const { rotation = 0, scaleX = 1, scaleY = 1, skewX = 0 } = parts;
|
|
@@ -356,6 +433,420 @@ function contrastLineColor(background, strength) {
|
|
|
356
433
|
return `#${hex22(r)}${hex22(g)}${hex22(b)}`;
|
|
357
434
|
}
|
|
358
435
|
|
|
436
|
+
// src/color.ts
|
|
437
|
+
function parseColor(input) {
|
|
438
|
+
const cached = CACHE.get(input);
|
|
439
|
+
if (cached !== void 0) return cached;
|
|
440
|
+
const result = parseColorUncached(input);
|
|
441
|
+
if (CACHE.size >= CACHE_MAX) CACHE.clear();
|
|
442
|
+
CACHE.set(input, result);
|
|
443
|
+
return result;
|
|
444
|
+
}
|
|
445
|
+
var CACHE = /* @__PURE__ */ new Map();
|
|
446
|
+
var CACHE_MAX = 1024;
|
|
447
|
+
function parseColorUncached(input) {
|
|
448
|
+
const s = input.trim();
|
|
449
|
+
if (s.startsWith("#")) return parseHex(s);
|
|
450
|
+
const lower = s.toLowerCase();
|
|
451
|
+
const named = NAMED_COLORS[lower];
|
|
452
|
+
if (named !== void 0) return named;
|
|
453
|
+
if (lower.startsWith("rgb")) {
|
|
454
|
+
const parsed = parseRgbFunction(lower);
|
|
455
|
+
if (parsed) return parsed;
|
|
456
|
+
}
|
|
457
|
+
if (lower.startsWith("hsl")) {
|
|
458
|
+
const parsed = parseHslFunction(lower);
|
|
459
|
+
if (parsed) return parsed;
|
|
460
|
+
}
|
|
461
|
+
throw new Error(`parseColor: unrecognized color "${input}"`);
|
|
462
|
+
}
|
|
463
|
+
var RESOLVE_COLOR_CACHE_CAP = 1024;
|
|
464
|
+
var resolveColorCache = /* @__PURE__ */ new Map();
|
|
465
|
+
function resolveColor(input) {
|
|
466
|
+
const hit = resolveColorCache.get(input);
|
|
467
|
+
if (hit) return hit;
|
|
468
|
+
if (resolveColorCache.size >= RESOLVE_COLOR_CACHE_CAP) {
|
|
469
|
+
resolveColorCache.clear();
|
|
470
|
+
}
|
|
471
|
+
const parsed = parseColor(input);
|
|
472
|
+
const frozen = parsed;
|
|
473
|
+
resolveColorCache.set(input, frozen);
|
|
474
|
+
return frozen;
|
|
475
|
+
}
|
|
476
|
+
function parseColorToRgba255(input) {
|
|
477
|
+
const [r, g, b, a] = parseColor(input);
|
|
478
|
+
return [
|
|
479
|
+
Math.round(r * 255),
|
|
480
|
+
Math.round(g * 255),
|
|
481
|
+
Math.round(b * 255),
|
|
482
|
+
Math.round(a * 255)
|
|
483
|
+
];
|
|
484
|
+
}
|
|
485
|
+
function normalizeHex(input) {
|
|
486
|
+
const trimmed = input.trim();
|
|
487
|
+
const hashed = trimmed.startsWith("#") ? trimmed : `#${trimmed}`;
|
|
488
|
+
const bytes = parseHexBytes(hashed);
|
|
489
|
+
if (!bytes) throw new Error(`normalizeHex: invalid hex "${input}"`);
|
|
490
|
+
const digits = bytes.map((n) => n.toString(16).padStart(2, "0")).join("");
|
|
491
|
+
const namesAlpha = hashed.length === 5 || hashed.length === 9;
|
|
492
|
+
return `#${namesAlpha ? digits : digits.slice(0, 6)}`;
|
|
493
|
+
}
|
|
494
|
+
function hexToRgba(input) {
|
|
495
|
+
return parseHex(normalizeHex(input));
|
|
496
|
+
}
|
|
497
|
+
function rgbaToHex(rgba) {
|
|
498
|
+
const [r, g, b] = rgba;
|
|
499
|
+
const a = rgba.length === 4 ? rgba[3] : 1;
|
|
500
|
+
const f = (n) => Math.max(0, Math.min(255, Math.round(n * 255))).toString(16).padStart(2, "0");
|
|
501
|
+
const base = `#${f(r)}${f(g)}${f(b)}`;
|
|
502
|
+
return a >= 1 ? base : `${base}${f(a)}`;
|
|
503
|
+
}
|
|
504
|
+
function parseHex(s) {
|
|
505
|
+
const bytes = parseHexBytes(s);
|
|
506
|
+
if (!bytes) throw new Error(`parseColor: invalid hex "${s}"`);
|
|
507
|
+
return [bytes[0] / 255, bytes[1] / 255, bytes[2] / 255, bytes[3] / 255];
|
|
508
|
+
}
|
|
509
|
+
function unwrapFn(s, name) {
|
|
510
|
+
if (!s.startsWith(name + "(") || !s.endsWith(")")) return null;
|
|
511
|
+
return s.slice(name.length + 1, -1).trim();
|
|
512
|
+
}
|
|
513
|
+
function splitChannels(body) {
|
|
514
|
+
if (body.includes(",")) {
|
|
515
|
+
const parts2 = body.split(",").map((p) => p.trim());
|
|
516
|
+
if (parts2.length !== 3 && parts2.length !== 4) return null;
|
|
517
|
+
return {
|
|
518
|
+
rgb: [parts2[0], parts2[1], parts2[2]],
|
|
519
|
+
alpha: parts2.length === 4 ? parts2[3] : null
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
const slash = body.indexOf("/");
|
|
523
|
+
const head = (slash === -1 ? body : body.slice(0, slash)).trim();
|
|
524
|
+
const alpha = slash === -1 ? null : body.slice(slash + 1).trim();
|
|
525
|
+
const parts = head.split(/\s+/);
|
|
526
|
+
if (parts.length !== 3) return null;
|
|
527
|
+
if (alpha !== null && alpha === "") return null;
|
|
528
|
+
return { rgb: [parts[0], parts[1], parts[2]], alpha };
|
|
529
|
+
}
|
|
530
|
+
function parseChannel(tok, max) {
|
|
531
|
+
if (tok.endsWith("%")) {
|
|
532
|
+
const n2 = Number(tok.slice(0, -1));
|
|
533
|
+
if (!Number.isFinite(n2)) return null;
|
|
534
|
+
return clamp012(n2 / 100);
|
|
535
|
+
}
|
|
536
|
+
const n = Number(tok);
|
|
537
|
+
if (!Number.isFinite(n)) return null;
|
|
538
|
+
return clamp012(n / max);
|
|
539
|
+
}
|
|
540
|
+
function parseAlpha(tok) {
|
|
541
|
+
if (tok === null) return 1;
|
|
542
|
+
if (tok.endsWith("%")) {
|
|
543
|
+
const n2 = Number(tok.slice(0, -1));
|
|
544
|
+
return Number.isFinite(n2) ? clamp012(n2 / 100) : 1;
|
|
545
|
+
}
|
|
546
|
+
const n = Number(tok);
|
|
547
|
+
return Number.isFinite(n) ? clamp012(n) : 1;
|
|
548
|
+
}
|
|
549
|
+
function parseRgbFunction(s) {
|
|
550
|
+
const body = unwrapFn(s, "rgba") ?? unwrapFn(s, "rgb");
|
|
551
|
+
if (body === null) return null;
|
|
552
|
+
const channels = splitChannels(body);
|
|
553
|
+
if (!channels) return null;
|
|
554
|
+
const r = parseChannel(channels.rgb[0], 255);
|
|
555
|
+
const g = parseChannel(channels.rgb[1], 255);
|
|
556
|
+
const b = parseChannel(channels.rgb[2], 255);
|
|
557
|
+
if (r === null || g === null || b === null) return null;
|
|
558
|
+
return [r, g, b, parseAlpha(channels.alpha)];
|
|
559
|
+
}
|
|
560
|
+
function parseHslFunction(s) {
|
|
561
|
+
const body = unwrapFn(s, "hsla") ?? unwrapFn(s, "hsl");
|
|
562
|
+
if (body === null) return null;
|
|
563
|
+
const channels = splitChannels(body);
|
|
564
|
+
if (!channels) return null;
|
|
565
|
+
const h = parseHue(channels.rgb[0]);
|
|
566
|
+
const sat = parsePercentOrNumber(channels.rgb[1]);
|
|
567
|
+
const lit = parsePercentOrNumber(channels.rgb[2]);
|
|
568
|
+
if (h === null || sat === null || lit === null) return null;
|
|
569
|
+
const [r, g, b] = hslToSrgb(h, sat, lit);
|
|
570
|
+
return [r, g, b, parseAlpha(channels.alpha)];
|
|
571
|
+
}
|
|
572
|
+
function parseHue(tok) {
|
|
573
|
+
let n;
|
|
574
|
+
if (tok.endsWith("deg")) n = Number(tok.slice(0, -3));
|
|
575
|
+
else if (tok.endsWith("grad")) n = Number(tok.slice(0, -4)) * 0.9;
|
|
576
|
+
else if (tok.endsWith("rad")) n = Number(tok.slice(0, -3)) * (180 / Math.PI);
|
|
577
|
+
else if (tok.endsWith("turn")) n = Number(tok.slice(0, -4)) * 360;
|
|
578
|
+
else n = Number(tok);
|
|
579
|
+
if (!Number.isFinite(n)) return null;
|
|
580
|
+
return (n % 360 + 360) % 360;
|
|
581
|
+
}
|
|
582
|
+
function parsePercentOrNumber(tok) {
|
|
583
|
+
if (tok.endsWith("%")) {
|
|
584
|
+
const n2 = Number(tok.slice(0, -1));
|
|
585
|
+
return Number.isFinite(n2) ? clamp012(n2 / 100) : null;
|
|
586
|
+
}
|
|
587
|
+
const n = Number(tok);
|
|
588
|
+
return Number.isFinite(n) ? clamp012(n) : null;
|
|
589
|
+
}
|
|
590
|
+
function clamp012(n) {
|
|
591
|
+
return n < 0 ? 0 : n > 1 ? 1 : n;
|
|
592
|
+
}
|
|
593
|
+
var NAMED_COLORS = (() => {
|
|
594
|
+
const hex = {
|
|
595
|
+
aliceblue: 15792383,
|
|
596
|
+
antiquewhite: 16444375,
|
|
597
|
+
aqua: 65535,
|
|
598
|
+
aquamarine: 8388564,
|
|
599
|
+
azure: 15794175,
|
|
600
|
+
beige: 16119260,
|
|
601
|
+
bisque: 16770244,
|
|
602
|
+
black: 0,
|
|
603
|
+
blanchedalmond: 16772045,
|
|
604
|
+
blue: 255,
|
|
605
|
+
blueviolet: 9055202,
|
|
606
|
+
brown: 10824234,
|
|
607
|
+
burlywood: 14596231,
|
|
608
|
+
cadetblue: 6266528,
|
|
609
|
+
chartreuse: 8388352,
|
|
610
|
+
chocolate: 13789470,
|
|
611
|
+
coral: 16744272,
|
|
612
|
+
cornflowerblue: 6591981,
|
|
613
|
+
cornsilk: 16775388,
|
|
614
|
+
crimson: 14423100,
|
|
615
|
+
cyan: 65535,
|
|
616
|
+
darkblue: 139,
|
|
617
|
+
darkcyan: 35723,
|
|
618
|
+
darkgoldenrod: 12092939,
|
|
619
|
+
darkgray: 11119017,
|
|
620
|
+
darkgreen: 25600,
|
|
621
|
+
darkgrey: 11119017,
|
|
622
|
+
darkkhaki: 12433259,
|
|
623
|
+
darkmagenta: 9109643,
|
|
624
|
+
darkolivegreen: 5597999,
|
|
625
|
+
darkorange: 16747520,
|
|
626
|
+
darkorchid: 10040012,
|
|
627
|
+
darkred: 9109504,
|
|
628
|
+
darksalmon: 15308410,
|
|
629
|
+
darkseagreen: 9419919,
|
|
630
|
+
darkslateblue: 4734347,
|
|
631
|
+
darkslategray: 3100495,
|
|
632
|
+
darkslategrey: 3100495,
|
|
633
|
+
darkturquoise: 52945,
|
|
634
|
+
darkviolet: 9699539,
|
|
635
|
+
deeppink: 16716947,
|
|
636
|
+
deepskyblue: 49151,
|
|
637
|
+
dimgray: 6908265,
|
|
638
|
+
dimgrey: 6908265,
|
|
639
|
+
dodgerblue: 2003199,
|
|
640
|
+
firebrick: 11674146,
|
|
641
|
+
floralwhite: 16775920,
|
|
642
|
+
forestgreen: 2263842,
|
|
643
|
+
fuchsia: 16711935,
|
|
644
|
+
gainsboro: 14474460,
|
|
645
|
+
ghostwhite: 16316671,
|
|
646
|
+
gold: 16766720,
|
|
647
|
+
goldenrod: 14329120,
|
|
648
|
+
gray: 8421504,
|
|
649
|
+
green: 32768,
|
|
650
|
+
greenyellow: 11403055,
|
|
651
|
+
grey: 8421504,
|
|
652
|
+
honeydew: 15794160,
|
|
653
|
+
hotpink: 16738740,
|
|
654
|
+
indianred: 13458524,
|
|
655
|
+
indigo: 4915330,
|
|
656
|
+
ivory: 16777200,
|
|
657
|
+
khaki: 15787660,
|
|
658
|
+
lavender: 15132410,
|
|
659
|
+
lavenderblush: 16773365,
|
|
660
|
+
lawngreen: 8190976,
|
|
661
|
+
lemonchiffon: 16775885,
|
|
662
|
+
lightblue: 11393254,
|
|
663
|
+
lightcoral: 15761536,
|
|
664
|
+
lightcyan: 14745599,
|
|
665
|
+
lightgoldenrodyellow: 16448210,
|
|
666
|
+
lightgray: 13882323,
|
|
667
|
+
lightgreen: 9498256,
|
|
668
|
+
lightgrey: 13882323,
|
|
669
|
+
lightpink: 16758465,
|
|
670
|
+
lightsalmon: 16752762,
|
|
671
|
+
lightseagreen: 2142890,
|
|
672
|
+
lightskyblue: 8900346,
|
|
673
|
+
lightslategray: 7833753,
|
|
674
|
+
lightslategrey: 7833753,
|
|
675
|
+
lightsteelblue: 11584734,
|
|
676
|
+
lightyellow: 16777184,
|
|
677
|
+
lime: 65280,
|
|
678
|
+
limegreen: 3329330,
|
|
679
|
+
linen: 16445670,
|
|
680
|
+
magenta: 16711935,
|
|
681
|
+
maroon: 8388608,
|
|
682
|
+
mediumaquamarine: 6737322,
|
|
683
|
+
mediumblue: 205,
|
|
684
|
+
mediumorchid: 12211667,
|
|
685
|
+
mediumpurple: 9662683,
|
|
686
|
+
mediumseagreen: 3978097,
|
|
687
|
+
mediumslateblue: 8087790,
|
|
688
|
+
mediumspringgreen: 64154,
|
|
689
|
+
mediumturquoise: 4772300,
|
|
690
|
+
mediumvioletred: 13047173,
|
|
691
|
+
midnightblue: 1644912,
|
|
692
|
+
mintcream: 16121850,
|
|
693
|
+
mistyrose: 16770273,
|
|
694
|
+
moccasin: 16770229,
|
|
695
|
+
navajowhite: 16768685,
|
|
696
|
+
navy: 128,
|
|
697
|
+
oldlace: 16643558,
|
|
698
|
+
olive: 8421376,
|
|
699
|
+
olivedrab: 7048739,
|
|
700
|
+
orange: 16753920,
|
|
701
|
+
orangered: 16729344,
|
|
702
|
+
orchid: 14315734,
|
|
703
|
+
palegoldenrod: 15657130,
|
|
704
|
+
palegreen: 10025880,
|
|
705
|
+
paleturquoise: 11529966,
|
|
706
|
+
palevioletred: 14381203,
|
|
707
|
+
papayawhip: 16773077,
|
|
708
|
+
peachpuff: 16767673,
|
|
709
|
+
peru: 13468991,
|
|
710
|
+
pink: 16761035,
|
|
711
|
+
plum: 14524637,
|
|
712
|
+
powderblue: 11591910,
|
|
713
|
+
purple: 8388736,
|
|
714
|
+
rebeccapurple: 6697881,
|
|
715
|
+
red: 16711680,
|
|
716
|
+
rosybrown: 12357519,
|
|
717
|
+
royalblue: 4286945,
|
|
718
|
+
saddlebrown: 9127187,
|
|
719
|
+
salmon: 16416882,
|
|
720
|
+
sandybrown: 16032864,
|
|
721
|
+
seagreen: 3050327,
|
|
722
|
+
seashell: 16774638,
|
|
723
|
+
sienna: 10506797,
|
|
724
|
+
silver: 12632256,
|
|
725
|
+
skyblue: 8900331,
|
|
726
|
+
slateblue: 6970061,
|
|
727
|
+
slategray: 7372944,
|
|
728
|
+
slategrey: 7372944,
|
|
729
|
+
snow: 16775930,
|
|
730
|
+
springgreen: 65407,
|
|
731
|
+
steelblue: 4620980,
|
|
732
|
+
tan: 13808780,
|
|
733
|
+
teal: 32896,
|
|
734
|
+
thistle: 14204888,
|
|
735
|
+
tomato: 16737095,
|
|
736
|
+
turquoise: 4251856,
|
|
737
|
+
violet: 15631086,
|
|
738
|
+
wheat: 16113331,
|
|
739
|
+
white: 16777215,
|
|
740
|
+
whitesmoke: 16119285,
|
|
741
|
+
yellow: 16776960,
|
|
742
|
+
yellowgreen: 10145074
|
|
743
|
+
};
|
|
744
|
+
const out = {
|
|
745
|
+
transparent: [0, 0, 0, 0]
|
|
746
|
+
};
|
|
747
|
+
for (const name in hex) {
|
|
748
|
+
const n = hex[name];
|
|
749
|
+
out[name] = [(n >> 16 & 255) / 255, (n >> 8 & 255) / 255, (n & 255) / 255, 1];
|
|
750
|
+
}
|
|
751
|
+
return out;
|
|
752
|
+
})();
|
|
753
|
+
|
|
754
|
+
// src/gradient.ts
|
|
755
|
+
function isGradientPaint(fill) {
|
|
756
|
+
if (fill == null) return false;
|
|
757
|
+
return fill.kind === "linear-gradient" || fill.kind === "radial-gradient" || fill.kind === "conic-gradient";
|
|
758
|
+
}
|
|
759
|
+
function resolveGradientStops(stops) {
|
|
760
|
+
return [...stops].sort((a, b) => a.offset - b.offset).map((s) => ({ offset: s.offset, rgba: resolveColor(s.color) }));
|
|
761
|
+
}
|
|
762
|
+
function sampleResolvedStops(stops, t, space = "rgb") {
|
|
763
|
+
if (stops.length === 0) return TRANSPARENT;
|
|
764
|
+
const first = stops[0];
|
|
765
|
+
const last = stops[stops.length - 1];
|
|
766
|
+
if (t <= first.offset) return first.rgba;
|
|
767
|
+
if (t >= last.offset) return last.rgba;
|
|
768
|
+
for (let i = 0; i < stops.length - 1; i++) {
|
|
769
|
+
const lo = stops[i];
|
|
770
|
+
const hi = stops[i + 1];
|
|
771
|
+
if (t < lo.offset || t > hi.offset) continue;
|
|
772
|
+
const span = hi.offset - lo.offset;
|
|
773
|
+
if (span <= 0) return hi.rgba;
|
|
774
|
+
const f = (t - lo.offset) / span;
|
|
775
|
+
const [r, g, b, a] = lerpColorArray(lo.rgba, hi.rgba, f, space);
|
|
776
|
+
return [r, g, b, a];
|
|
777
|
+
}
|
|
778
|
+
return last.rgba;
|
|
779
|
+
}
|
|
780
|
+
var TRANSPARENT = [0, 0, 0, 0];
|
|
781
|
+
function sampleGradientStops(stops, t, space = "rgb") {
|
|
782
|
+
if (stops.length === 0) return "rgba(0,0,0,0)";
|
|
783
|
+
return rgbaToHex(sampleResolvedStops(resolveGradientStops(stops), t, space));
|
|
784
|
+
}
|
|
785
|
+
function withGradientKind(fill, kind) {
|
|
786
|
+
if (fill.kind === kind) return fill;
|
|
787
|
+
const common = {
|
|
788
|
+
stops: fill.stops,
|
|
789
|
+
units: fill.units,
|
|
790
|
+
interpolate: fill.interpolate,
|
|
791
|
+
opacity: fill.opacity
|
|
792
|
+
};
|
|
793
|
+
const { center, radius, angle } = gradientGeometry(fill);
|
|
794
|
+
if (kind === "linear-gradient") {
|
|
795
|
+
const dx = Math.cos(angle) * radius;
|
|
796
|
+
const dy = Math.sin(angle) * radius;
|
|
797
|
+
return {
|
|
798
|
+
kind: "linear-gradient",
|
|
799
|
+
from: { x: center.x - dx, y: center.y - dy },
|
|
800
|
+
to: { x: center.x + dx, y: center.y + dy },
|
|
801
|
+
...common
|
|
802
|
+
};
|
|
803
|
+
}
|
|
804
|
+
if (kind === "radial-gradient") {
|
|
805
|
+
return { kind: "radial-gradient", center, radius, ...common };
|
|
806
|
+
}
|
|
807
|
+
return { kind: "conic-gradient", center, angle, ...common };
|
|
808
|
+
}
|
|
809
|
+
function gradientGeometry(fill) {
|
|
810
|
+
if (fill.kind === "linear-gradient") {
|
|
811
|
+
const dx = fill.to.x - fill.from.x;
|
|
812
|
+
const dy = fill.to.y - fill.from.y;
|
|
813
|
+
return {
|
|
814
|
+
center: { x: (fill.from.x + fill.to.x) / 2, y: (fill.from.y + fill.to.y) / 2 },
|
|
815
|
+
radius: Math.hypot(dx, dy) / 2,
|
|
816
|
+
angle: Math.atan2(dy, dx)
|
|
817
|
+
};
|
|
818
|
+
}
|
|
819
|
+
if (fill.kind === "radial-gradient") {
|
|
820
|
+
return { center: fill.center, radius: fill.radius, angle: 0 };
|
|
821
|
+
}
|
|
822
|
+
return { center: fill.center, radius: conicArmRadius(fill.units), angle: fill.angle };
|
|
823
|
+
}
|
|
824
|
+
function conicArmRadius(units) {
|
|
825
|
+
return units === "bounds" ? 0.5 : 50;
|
|
826
|
+
}
|
|
827
|
+
function gradientForBounds(kind, bounds, stops, units) {
|
|
828
|
+
const center = { x: bounds.x + bounds.width / 2, y: bounds.y + bounds.height / 2 };
|
|
829
|
+
if (kind === "linear-gradient") {
|
|
830
|
+
return {
|
|
831
|
+
kind: "linear-gradient",
|
|
832
|
+
from: { x: bounds.x, y: center.y },
|
|
833
|
+
to: { x: bounds.x + bounds.width, y: center.y },
|
|
834
|
+
stops,
|
|
835
|
+
units
|
|
836
|
+
};
|
|
837
|
+
}
|
|
838
|
+
if (kind === "radial-gradient") {
|
|
839
|
+
return {
|
|
840
|
+
kind: "radial-gradient",
|
|
841
|
+
center,
|
|
842
|
+
radius: Math.max(bounds.width, bounds.height) / 2,
|
|
843
|
+
stops,
|
|
844
|
+
units
|
|
845
|
+
};
|
|
846
|
+
}
|
|
847
|
+
return { kind: "conic-gradient", center, angle: 0, stops, units };
|
|
848
|
+
}
|
|
849
|
+
|
|
359
850
|
// src/palette.ts
|
|
360
851
|
function nth(items, n) {
|
|
361
852
|
if (!Number.isInteger(n) || n < 0) return void 0;
|
|
@@ -420,6 +911,18 @@ function colorLiteralToHex(color) {
|
|
|
420
911
|
const a = color.alpha ?? 1;
|
|
421
912
|
return `#${rgb.map(hex23).join("")}${a < 1 ? hex23(a * 255) : ""}`;
|
|
422
913
|
}
|
|
914
|
+
function colorLiteralToCss(color) {
|
|
915
|
+
if (color.coords.length < 3) return null;
|
|
916
|
+
const hex = colorLiteralToHex(color);
|
|
917
|
+
if (hex) return hex;
|
|
918
|
+
const a = color.alpha ?? 1;
|
|
919
|
+
return `color(${color.space} ${color.coords.join(" ")}${a < 1 ? ` / ${a}` : ""})`;
|
|
920
|
+
}
|
|
921
|
+
function cssColorLiteral(css) {
|
|
922
|
+
const [r, g, b, a] = parseColor(css);
|
|
923
|
+
const coords = [r, g, b];
|
|
924
|
+
return a < 1 ? { space: "srgb", coords, alpha: a } : { space: "srgb", coords };
|
|
925
|
+
}
|
|
423
926
|
function hexToColorLiteral(hex) {
|
|
424
927
|
const bytes = hex.length === 7 || hex.length === 9 ? parseHexBytes(hex) : null;
|
|
425
928
|
if (!bytes) return null;
|
|
@@ -428,6 +931,6 @@ function hexToColorLiteral(hex) {
|
|
|
428
931
|
return hex.length === 9 ? { space: "srgb", coords, alpha: a } : { space: "srgb", coords };
|
|
429
932
|
}
|
|
430
933
|
|
|
431
|
-
export { STROKE_DASH_RATIOS, alignedStrokeRect, colorLiteralToHex, composePatternTransform, contrastLineColor, dashForStrokeStyle, decomposePatternTransform, hexToColorLiteral, hexToOklchDeg, hexToRgbBytes, hslToSrgb, interpolateSrgb, lerpColorArray, lerpOklab, lerpOklch, linearSrgbToOklab, linearToSrgb, mixOklab, oklabToLinearSrgb, oklabToOklch, oklabToSrgbU8, oklchDegToHex, oklchToOklab, parseHexBytes, resolvePaletteColor, resolvePaletteColors, resolveScreenLength, srgbFloatToOklab, srgbToHsl, srgbToLinear, srgbU8ToOklab, strokeDashStyleOf };
|
|
934
|
+
export { STROKE_DASH_RATIOS, TILE_KINDS, alignedStrokeRect, colorLiteralToCss, colorLiteralToHex, composePatternTransform, contrastLineColor, cssColorLiteral, dashForStrokeStyle, decomposePatternTransform, fillHasInk, gradientForBounds, gradientGeometry, hexToColorLiteral, hexToOklchDeg, hexToRgbBytes, hexToRgba, hslToSrgb, interpolateSrgb, isGradientPaint, isPatternPaint, isSolidPaint, isTileKind, isTilePaint, lerpColorArray, lerpOklab, lerpOklch, linearSrgbToOklab, linearToSrgb, mixOklab, normalizeHex, oklabToLinearSrgb, oklabToOklch, oklabToSrgbU8, oklchDegToHex, oklchToOklab, paintKey, parseColor, parseColorToRgba255, parseHexBytes, patternPlacementOf, resolveColor, resolveGradientStops, resolvePaletteColor, resolvePaletteColors, resolveScreenLength, rgbaToHex, sampleGradientStops, sampleResolvedStops, srgbFloatToOklab, srgbToHsl, srgbToLinear, srgbU8ToOklab, strokeDashStyleOf, strokeHasInk, strokeKey, tileSpecOf, withGradientKind };
|
|
432
935
|
//# sourceMappingURL=index.js.map
|
|
433
936
|
//# sourceMappingURL=index.js.map
|