@kongyo2/cards-css 0.2.1 → 0.3.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/src/palette.ts ADDED
@@ -0,0 +1,195 @@
1
+ import type { PaletteOptions, PalettePreset } from "./types.js";
2
+
3
+ /** Built-in foil colour schemes, keyed by {@link PalettePreset}. */
4
+ export const PALETTES: Record<PalettePreset, PaletteOptions> = {
5
+ rainbow: {
6
+ sunpillars: [
7
+ "hsl(2, 100%, 73%)",
8
+ "hsl(53, 100%, 69%)",
9
+ "hsl(93, 100%, 69%)",
10
+ "hsl(176, 100%, 76%)",
11
+ "hsl(228, 100%, 74%)",
12
+ "hsl(283, 100%, 73%)",
13
+ ],
14
+ spectrum: ["#f80e35", "#eedf10", "#21e985", "#0dbde9", "#c929f1"],
15
+ cosmos: [
16
+ "hsl(53, 65%, 60%)",
17
+ "hsl(93, 56%, 50%)",
18
+ "hsl(176, 54%, 49%)",
19
+ "hsl(228, 59%, 55%)",
20
+ "hsl(283, 60%, 55%)",
21
+ "hsl(326, 59%, 51%)",
22
+ ],
23
+ },
24
+ gold: {
25
+ sunpillars: [
26
+ "hsl(45, 100%, 80%)",
27
+ "hsl(38, 100%, 68%)",
28
+ "hsl(50, 100%, 78%)",
29
+ "hsl(33, 95%, 62%)",
30
+ "hsl(48, 100%, 85%)",
31
+ "hsl(40, 100%, 70%)",
32
+ ],
33
+ spectrum: ["#8c5a12", "#ffd24a", "#fff0b0", "#e0962a", "#6b3f06"],
34
+ cosmos: [
35
+ "hsl(45, 80%, 65%)",
36
+ "hsl(40, 75%, 58%)",
37
+ "hsl(36, 70%, 52%)",
38
+ "hsl(50, 85%, 70%)",
39
+ "hsl(33, 65%, 48%)",
40
+ "hsl(28, 70%, 55%)",
41
+ ],
42
+ edge: "hsl(45, 100%, 78%)",
43
+ glow: "hsl(45, 100%, 80%)",
44
+ },
45
+ aurora: {
46
+ sunpillars: [
47
+ "hsl(150, 90%, 72%)",
48
+ "hsl(170, 85%, 68%)",
49
+ "hsl(190, 90%, 72%)",
50
+ "hsl(260, 85%, 78%)",
51
+ "hsl(140, 80%, 70%)",
52
+ "hsl(200, 90%, 74%)",
53
+ ],
54
+ spectrum: ["#10b981", "#34d399", "#a7f3d0", "#22d3ee", "#8b5cf6"],
55
+ cosmos: [
56
+ "hsl(160, 60%, 55%)",
57
+ "hsl(180, 55%, 50%)",
58
+ "hsl(200, 60%, 55%)",
59
+ "hsl(260, 55%, 58%)",
60
+ "hsl(150, 55%, 52%)",
61
+ "hsl(290, 50%, 55%)",
62
+ ],
63
+ edge: "hsl(160, 90%, 80%)",
64
+ glow: "hsl(170, 100%, 85%)",
65
+ },
66
+ ruby: {
67
+ sunpillars: [
68
+ "hsl(350, 100%, 75%)",
69
+ "hsl(330, 100%, 72%)",
70
+ "hsl(10, 100%, 72%)",
71
+ "hsl(300, 90%, 72%)",
72
+ "hsl(355, 100%, 80%)",
73
+ "hsl(20, 100%, 70%)",
74
+ ],
75
+ spectrum: ["#e11d48", "#fb7185", "#fecdd3", "#f43f5e", "#9f1239"],
76
+ cosmos: [
77
+ "hsl(350, 65%, 58%)",
78
+ "hsl(330, 60%, 55%)",
79
+ "hsl(10, 65%, 58%)",
80
+ "hsl(300, 55%, 55%)",
81
+ "hsl(355, 60%, 52%)",
82
+ "hsl(20, 60%, 55%)",
83
+ ],
84
+ edge: "hsl(350, 100%, 82%)",
85
+ glow: "hsl(345, 100%, 85%)",
86
+ },
87
+ sapphire: {
88
+ sunpillars: [
89
+ "hsl(210, 100%, 75%)",
90
+ "hsl(190, 100%, 72%)",
91
+ "hsl(230, 100%, 76%)",
92
+ "hsl(170, 90%, 70%)",
93
+ "hsl(250, 90%, 78%)",
94
+ "hsl(200, 100%, 74%)",
95
+ ],
96
+ spectrum: ["#1d4ed8", "#3b82f6", "#bfdbfe", "#06b6d4", "#4338ca"],
97
+ cosmos: [
98
+ "hsl(210, 65%, 58%)",
99
+ "hsl(190, 60%, 55%)",
100
+ "hsl(230, 60%, 58%)",
101
+ "hsl(170, 55%, 52%)",
102
+ "hsl(250, 55%, 58%)",
103
+ "hsl(200, 60%, 55%)",
104
+ ],
105
+ edge: "hsl(205, 100%, 80%)",
106
+ glow: "hsl(200, 100%, 85%)",
107
+ },
108
+ mono: {
109
+ sunpillars: [
110
+ "hsl(0, 0%, 92%)",
111
+ "hsl(0, 0%, 82%)",
112
+ "hsl(0, 0%, 96%)",
113
+ "hsl(0, 0%, 78%)",
114
+ "hsl(0, 0%, 88%)",
115
+ "hsl(0, 0%, 84%)",
116
+ ],
117
+ spectrum: ["#9ca3af", "#e5e7eb", "#ffffff", "#d1d5db", "#6b7280"],
118
+ cosmos: [
119
+ "hsl(0, 0%, 75%)",
120
+ "hsl(0, 0%, 68%)",
121
+ "hsl(0, 0%, 82%)",
122
+ "hsl(0, 0%, 62%)",
123
+ "hsl(0, 0%, 78%)",
124
+ "hsl(0, 0%, 70%)",
125
+ ],
126
+ edge: "hsl(0, 0%, 90%)",
127
+ glow: "hsl(0, 0%, 92%)",
128
+ },
129
+ };
130
+
131
+ /** Merge a palette's `preset` base with its explicit overrides into a flat scheme. */
132
+ export const resolvePalette = (palette: PaletteOptions): PaletteOptions => {
133
+ const base = palette.preset ? PALETTES[palette.preset] : undefined;
134
+ const merged: PaletteOptions = { ...base, ...palette };
135
+ delete merged.preset;
136
+ return merged;
137
+ };
138
+
139
+ const SPECTRUM_VARS = ["--red", "--yellow", "--green", "--blue", "--violet"] as const;
140
+
141
+ /** Every CSS custom property the palette can own — used to clear stale values when swapping palettes. */
142
+ export const PALETTE_VARIABLES: string[] = [
143
+ "--sunpillar-1",
144
+ "--sunpillar-2",
145
+ "--sunpillar-3",
146
+ "--sunpillar-4",
147
+ "--sunpillar-5",
148
+ "--sunpillar-6",
149
+ ...SPECTRUM_VARS,
150
+ "--cosmos-clr-1",
151
+ "--cosmos-clr-2",
152
+ "--cosmos-clr-3",
153
+ "--cosmos-clr-4",
154
+ "--cosmos-clr-5",
155
+ "--cosmos-clr-6",
156
+ "--card-edge",
157
+ "--card-back",
158
+ "--card-glow",
159
+ ];
160
+
161
+ const cycleInto = (vars: Record<string, string>, prefix: string, count: number, colors: string[]): void => {
162
+ if (colors.length === 0) {
163
+ return;
164
+ }
165
+ for (let i = 0; i < count; i += 1) {
166
+ vars[`${prefix}${i + 1}`] = colors[i % colors.length] as string;
167
+ }
168
+ };
169
+
170
+ /** Convert a (resolved or raw) palette into the CSS custom properties it drives. */
171
+ export const paletteToCssVariables = (palette: PaletteOptions): Record<string, string> => {
172
+ const resolved = resolvePalette(palette);
173
+ const vars: Record<string, string> = {};
174
+ if (resolved.sunpillars) {
175
+ cycleInto(vars, "--sunpillar-", 6, resolved.sunpillars);
176
+ }
177
+ if (resolved.spectrum && resolved.spectrum.length > 0) {
178
+ SPECTRUM_VARS.forEach((name, i) => {
179
+ vars[name] = resolved.spectrum![i % resolved.spectrum!.length] as string;
180
+ });
181
+ }
182
+ if (resolved.cosmos) {
183
+ cycleInto(vars, "--cosmos-clr-", 6, resolved.cosmos);
184
+ }
185
+ if (resolved.edge) {
186
+ vars["--card-edge"] = resolved.edge;
187
+ }
188
+ if (resolved.back) {
189
+ vars["--card-back"] = resolved.back;
190
+ }
191
+ if (resolved.glow) {
192
+ vars["--card-glow"] = resolved.glow;
193
+ }
194
+ return vars;
195
+ };
package/src/spring.ts CHANGED
@@ -39,6 +39,10 @@ interface AxisDynamics {
39
39
  precision: number;
40
40
  }
41
41
 
42
+ const MAX_FRAME_DELTA = 2;
43
+
44
+ const clampFrameDelta = (dt: number): number => Math.max(0, Math.min(dt, MAX_FRAME_DELTA));
45
+
42
46
  const tickScalar = (
43
47
  ctx: FrameContext,
44
48
  axis: AxisDynamics,
@@ -100,7 +104,8 @@ export class Spring<T extends SpringValue> {
100
104
  private cancelTask = false;
101
105
  private task: TaskHandle | null = null;
102
106
  private lastTime = 0;
103
- private currentToken: object | null = null;
107
+ private settlePromise: Promise<void> | null = null;
108
+ private settleResolve: (() => void) | null = null;
104
109
  private readonly subscribers = new Subscribers<T>(() => this.value);
105
110
 
106
111
  constructor(value: T, opts: SpringOpts = {}) {
@@ -127,7 +132,6 @@ export class Spring<T extends SpringValue> {
127
132
 
128
133
  set(newValue: T, opts: SpringSetOpts = {}): Promise<void> {
129
134
  this.targetValue = newValue;
130
- const token = (this.currentToken = {});
131
135
 
132
136
  if (opts.hard || (this.stiffness >= 1 && this.damping >= 1)) {
133
137
  this.cancelTask = true;
@@ -139,6 +143,7 @@ export class Spring<T extends SpringValue> {
139
143
  this.lastValue = newValue;
140
144
  this.value = newValue;
141
145
  this.notify();
146
+ this.resolveSettle();
142
147
  return Promise.resolve();
143
148
  }
144
149
 
@@ -148,11 +153,10 @@ export class Spring<T extends SpringValue> {
148
153
  this.invMass = 0;
149
154
  }
150
155
 
151
- let handle = this.task;
152
- if (!handle) {
156
+ if (!this.task) {
153
157
  this.lastTime = now();
154
158
  this.cancelTask = false;
155
- handle = loop((time) => {
159
+ this.task = loop((time) => {
156
160
  if (this.cancelTask) {
157
161
  this.cancelTask = false;
158
162
  this.task = null;
@@ -166,7 +170,7 @@ export class Spring<T extends SpringValue> {
166
170
  precision: this.precision,
167
171
  axes: this.axes,
168
172
  settled: true,
169
- dt: ((time - this.lastTime) * 60) / 1000,
173
+ dt: clampFrameDelta(((time - this.lastTime) * 60) / 1000),
170
174
  };
171
175
  const next = tick(ctx, this.lastValue, this.value, this.targetValue);
172
176
  this.lastTime = time;
@@ -175,21 +179,32 @@ export class Spring<T extends SpringValue> {
175
179
  this.notify();
176
180
  if (ctx.settled) {
177
181
  this.task = null;
182
+ this.resolveSettle();
178
183
  }
179
184
  return !ctx.settled;
180
185
  });
181
- this.task = handle;
182
186
  }
183
187
 
184
- return new Promise<void>((fulfil) => {
185
- void handle.promise.then(() => (token === this.currentToken ? fulfil() : undefined));
186
- });
188
+ if (!this.settlePromise) {
189
+ this.settlePromise = new Promise<void>((resolve) => {
190
+ this.settleResolve = resolve;
191
+ });
192
+ }
193
+ return this.settlePromise;
194
+ }
195
+
196
+ private resolveSettle(): void {
197
+ const resolve = this.settleResolve;
198
+ this.settlePromise = null;
199
+ this.settleResolve = null;
200
+ resolve?.();
187
201
  }
188
202
 
189
203
  destroy(): void {
190
204
  this.cancelTask = true;
191
205
  this.task?.abort();
192
206
  this.task = null;
207
+ this.resolveSettle();
193
208
  this.subscribers.clear();
194
209
  }
195
210
  }
@@ -123,7 +123,7 @@
123
123
  .holo-card__translater,
124
124
  .holo-card__rotator {
125
125
  display: grid;
126
- perspective: 600px;
126
+ perspective: var(--card-perspective, 600px);
127
127
  will-change: transform, box-shadow;
128
128
  transform-origin: center;
129
129
  transform-style: preserve-3d;
@@ -270,14 +270,21 @@ button.holo-card__rotator {
270
270
  .holo-card__glare {
271
271
  transform: translateZ(1.41px);
272
272
  overflow: hidden;
273
- background-image: radial-gradient(
274
- farthest-corner circle at var(--pointer-x) var(--pointer-y),
275
- hsla(0, 0%, 100%, 0.8) 10%,
276
- hsla(0, 0%, 100%, 0.65) 20%,
277
- hsla(0, 0%, 0%, 0.5) 90%
273
+ background-image: var(
274
+ --glare-image,
275
+ radial-gradient(
276
+ farthest-corner circle at var(--pointer-x) var(--pointer-y),
277
+ hsla(0, 0%, 100%, 0.8) 10%,
278
+ hsla(0, 0%, 100%, 0.65) 20%,
279
+ hsla(0, 0%, 0%, 0.5) 90%
280
+ )
278
281
  );
279
282
  opacity: calc(var(--card-opacity) * var(--hc-glare-opacity));
280
- mix-blend-mode: overlay;
283
+ mix-blend-mode: var(--glare-blend, overlay);
284
+ }
285
+
286
+ .holo-card--custom-glare .holo-card__glare::after {
287
+ display: none !important;
281
288
  }
282
289
 
283
290
  .holo-card--masked .holo-card__shine,
@@ -349,3 +356,36 @@ button.holo-card__rotator {
349
356
  .holo-card__overlay--interactive * {
350
357
  pointer-events: auto;
351
358
  }
359
+
360
+ .holo-card--depth .holo-card__shine {
361
+ transform: translateZ(calc(1px + var(--hc-depth, 0px)));
362
+ }
363
+
364
+ .holo-card--depth .holo-card__glare {
365
+ transform: translateZ(calc(1.41px + var(--hc-depth, 0px)));
366
+ }
367
+
368
+ .holo-card--depth .holo-card__overlay {
369
+ transform: translateZ(calc(2px + var(--hc-depth, 0px)));
370
+ }
371
+
372
+ .holo-card--depth .holo-card__layer {
373
+ transform: translate3d(
374
+ calc(var(--pointer-dx) * var(--layer-parallax) * 1px),
375
+ calc(var(--pointer-dy) * var(--layer-parallax) * 1px),
376
+ calc(0.02px + var(--layer-parallax) * var(--hc-depth-layer-scale, 1) * 1px)
377
+ );
378
+ }
379
+
380
+ .holo-card--depth .holo-card__translater::before {
381
+ content: "";
382
+ position: absolute;
383
+ inset: 0;
384
+ z-index: -1;
385
+ border-radius: var(--card-radius);
386
+ background: transparent;
387
+ transform: translateZ(-1px);
388
+ pointer-events: none;
389
+ box-shadow: calc(var(--tilt-x, 0) * -0.6px) calc(var(--hc-depth, 0px) * 0.5 + var(--tilt-y, 0) * 0.6px)
390
+ calc(var(--hc-depth, 0px) * 1.2 + 14px) calc(var(--hc-depth, 0px) * 0.2) rgba(0, 0, 0, var(--hc-depth-shadow, 0));
391
+ }
@@ -1,6 +1,13 @@
1
1
  .holo-card[data-effect="cosmos"] {
2
2
  --space: 4%;
3
3
  --angle: 82deg;
4
+
5
+ --cosmos-clr-1: hsl(53, 65%, 60%);
6
+ --cosmos-clr-2: hsl(93, 56%, 50%);
7
+ --cosmos-clr-3: hsl(176, 54%, 49%);
8
+ --cosmos-clr-4: hsl(228, 59%, 55%);
9
+ --cosmos-clr-5: hsl(283, 60%, 55%);
10
+ --cosmos-clr-6: hsl(326, 59%, 51%);
4
11
  }
5
12
 
6
13
  .holo-card[data-effect="cosmos"] .holo-card__shine {
@@ -8,18 +15,18 @@
8
15
  var(--hc-cosmos-bottom),
9
16
  repeating-linear-gradient(
10
17
  var(--angle),
11
- hsl(53, 65%, 60%) calc(var(--space) * 1),
12
- hsl(93, 56%, 50%) calc(var(--space) * 2),
13
- hsl(176, 54%, 49%) calc(var(--space) * 3),
14
- hsl(228, 59%, 55%) calc(var(--space) * 4),
15
- hsl(283, 60%, 55%) calc(var(--space) * 5),
16
- hsl(326, 59%, 51%) calc(var(--space) * 6),
17
- hsl(326, 59%, 51%) calc(var(--space) * 7),
18
- hsl(283, 60%, 55%) calc(var(--space) * 8),
19
- hsl(228, 59%, 55%) calc(var(--space) * 9),
20
- hsl(176, 54%, 49%) calc(var(--space) * 10),
21
- hsl(93, 56%, 50%) calc(var(--space) * 11),
22
- hsl(53, 65%, 60%) calc(var(--space) * 12)
18
+ var(--cosmos-clr-1) calc(var(--space) * 1),
19
+ var(--cosmos-clr-2) calc(var(--space) * 2),
20
+ var(--cosmos-clr-3) calc(var(--space) * 3),
21
+ var(--cosmos-clr-4) calc(var(--space) * 4),
22
+ var(--cosmos-clr-5) calc(var(--space) * 5),
23
+ var(--cosmos-clr-6) calc(var(--space) * 6),
24
+ var(--cosmos-clr-6) calc(var(--space) * 7),
25
+ var(--cosmos-clr-5) calc(var(--space) * 8),
26
+ var(--cosmos-clr-4) calc(var(--space) * 9),
27
+ var(--cosmos-clr-3) calc(var(--space) * 10),
28
+ var(--cosmos-clr-2) calc(var(--space) * 11),
29
+ var(--cosmos-clr-1) calc(var(--space) * 12)
23
30
  ),
24
31
  radial-gradient(
25
32
  farthest-corner circle at var(--pointer-x) var(--pointer-y),
@@ -52,18 +59,18 @@
52
59
  var(--hc-cosmos-middle),
53
60
  repeating-linear-gradient(
54
61
  var(--angle),
55
- hsl(53, 65%, 60%) calc(var(--space) * 1),
56
- hsl(93, 56%, 50%) calc(var(--space) * 2),
57
- hsl(176, 54%, 49%) calc(var(--space) * 3),
58
- hsl(228, 59%, 55%) calc(var(--space) * 4),
59
- hsl(283, 60%, 55%) calc(var(--space) * 5),
60
- hsl(326, 59%, 51%) calc(var(--space) * 6),
61
- hsl(326, 59%, 51%) calc(var(--space) * 7),
62
- hsl(283, 60%, 55%) calc(var(--space) * 8),
63
- hsl(228, 59%, 55%) calc(var(--space) * 9),
64
- hsl(176, 54%, 49%) calc(var(--space) * 10),
65
- hsl(93, 56%, 50%) calc(var(--space) * 11),
66
- hsl(53, 65%, 60%) calc(var(--space) * 12)
62
+ var(--cosmos-clr-1) calc(var(--space) * 1),
63
+ var(--cosmos-clr-2) calc(var(--space) * 2),
64
+ var(--cosmos-clr-3) calc(var(--space) * 3),
65
+ var(--cosmos-clr-4) calc(var(--space) * 4),
66
+ var(--cosmos-clr-5) calc(var(--space) * 5),
67
+ var(--cosmos-clr-6) calc(var(--space) * 6),
68
+ var(--cosmos-clr-6) calc(var(--space) * 7),
69
+ var(--cosmos-clr-5) calc(var(--space) * 8),
70
+ var(--cosmos-clr-4) calc(var(--space) * 9),
71
+ var(--cosmos-clr-3) calc(var(--space) * 10),
72
+ var(--cosmos-clr-2) calc(var(--space) * 11),
73
+ var(--cosmos-clr-1) calc(var(--space) * 12)
67
74
  );
68
75
 
69
76
  background-blend-mode: lighten, multiply;
@@ -90,18 +97,18 @@
90
97
  var(--hc-cosmos-top),
91
98
  repeating-linear-gradient(
92
99
  var(--angle),
93
- hsl(53, 65%, 60%) calc(var(--space) * 1),
94
- hsl(93, 56%, 50%) calc(var(--space) * 2),
95
- hsl(176, 54%, 49%) calc(var(--space) * 3),
96
- hsl(228, 59%, 55%) calc(var(--space) * 4),
97
- hsl(283, 60%, 55%) calc(var(--space) * 5),
98
- hsl(326, 59%, 51%) calc(var(--space) * 6),
99
- hsl(326, 59%, 51%) calc(var(--space) * 7),
100
- hsl(283, 60%, 55%) calc(var(--space) * 8),
101
- hsl(228, 59%, 55%) calc(var(--space) * 9),
102
- hsl(176, 54%, 49%) calc(var(--space) * 10),
103
- hsl(93, 56%, 50%) calc(var(--space) * 11),
104
- hsl(53, 65%, 60%) calc(var(--space) * 12)
100
+ var(--cosmos-clr-1) calc(var(--space) * 1),
101
+ var(--cosmos-clr-2) calc(var(--space) * 2),
102
+ var(--cosmos-clr-3) calc(var(--space) * 3),
103
+ var(--cosmos-clr-4) calc(var(--space) * 4),
104
+ var(--cosmos-clr-5) calc(var(--space) * 5),
105
+ var(--cosmos-clr-6) calc(var(--space) * 6),
106
+ var(--cosmos-clr-6) calc(var(--space) * 7),
107
+ var(--cosmos-clr-5) calc(var(--space) * 8),
108
+ var(--cosmos-clr-4) calc(var(--space) * 9),
109
+ var(--cosmos-clr-3) calc(var(--space) * 10),
110
+ var(--cosmos-clr-2) calc(var(--space) * 11),
111
+ var(--cosmos-clr-1) calc(var(--space) * 12)
105
112
  );
106
113
 
107
114
  background-blend-mode: multiply, multiply;
@@ -121,13 +128,16 @@
121
128
  }
122
129
 
123
130
  .holo-card[data-effect="cosmos"] .holo-card__glare {
124
- background-image: radial-gradient(
125
- farthest-corner circle at var(--pointer-x) var(--pointer-y),
126
- hsla(204, 100%, 95%, 0.8) 5%,
127
- hsla(250, 15%, 20%, 1) 150%
131
+ background-image: var(
132
+ --glare-image,
133
+ radial-gradient(
134
+ farthest-corner circle at var(--pointer-x) var(--pointer-y),
135
+ hsla(204, 100%, 95%, 0.8) 5%,
136
+ hsla(250, 15%, 20%, 1) 150%
137
+ )
128
138
  );
129
139
  filter: brightness(0.75) contrast(2) saturate(2);
130
- mix-blend-mode: overlay;
140
+ mix-blend-mode: var(--glare-blend, overlay);
131
141
  opacity: calc(var(--card-opacity) * (0.25 + var(--pointer-from-center)) * var(--hc-glare-opacity));
132
142
  }
133
143
 
@@ -66,21 +66,27 @@
66
66
  }
67
67
 
68
68
  .holo-card[data-effect="glitter"]:not(.holo-card--masked) .holo-card__glare {
69
- background-image: radial-gradient(
70
- farthest-corner circle at var(--pointer-x) var(--pointer-y),
71
- hsla(0, 0%, 100%, 1) 10%,
72
- hsla(0, 0%, 100%, 0.85) 20%,
73
- hsla(0, 0%, 0%, 0.35) 90%
69
+ background-image: var(
70
+ --glare-image,
71
+ radial-gradient(
72
+ farthest-corner circle at var(--pointer-x) var(--pointer-y),
73
+ hsla(0, 0%, 100%, 1) 10%,
74
+ hsla(0, 0%, 100%, 0.85) 20%,
75
+ hsla(0, 0%, 0%, 0.35) 90%
76
+ )
74
77
  );
75
- mix-blend-mode: multiply;
78
+ mix-blend-mode: var(--glare-blend, multiply);
76
79
  }
77
80
 
78
81
  .holo-card--masked[data-effect="glitter"] .holo-card__glare {
79
- background-image: radial-gradient(
80
- farthest-corner circle at var(--pointer-x) var(--pointer-y),
81
- hsla(50, 20%, 90%, 0.45) 0%,
82
- hsla(150, 20%, 30%, 0.45) 45%,
83
- hsla(0, 0%, 0%, 0.9) 120%
82
+ background-image: var(
83
+ --glare-image,
84
+ radial-gradient(
85
+ farthest-corner circle at var(--pointer-x) var(--pointer-y),
86
+ hsla(50, 20%, 90%, 0.45) 0%,
87
+ hsla(150, 20%, 30%, 0.45) 45%,
88
+ hsla(0, 0%, 0%, 0.9) 120%
89
+ )
84
90
  );
85
91
  filter: brightness(0.9) contrast(2);
86
92
  }
@@ -110,7 +110,7 @@
110
110
  .holo-card[data-effect="holo"] .holo-card__glare {
111
111
  opacity: calc(var(--card-opacity) * 0.8 * var(--hc-glare-opacity));
112
112
  filter: brightness(0.8) contrast(1.5);
113
- mix-blend-mode: overlay;
113
+ mix-blend-mode: var(--glare-blend, overlay);
114
114
  }
115
115
 
116
116
  .holo-card[data-effect="holo"] .holo-card__glare::after {
@@ -27,11 +27,14 @@
27
27
  .holo-card[data-effect="reverse"] .holo-card__glare {
28
28
  opacity: calc(var(--card-opacity) * var(--hc-glare-opacity));
29
29
 
30
- background-image: radial-gradient(
31
- farthest-corner circle at var(--pointer-x) var(--pointer-y),
32
- hsla(0, 0%, 100%, 0.8) 10%,
33
- hsla(0, 0%, 100%, 0.5) 20%,
34
- hsla(0, 0%, 0%, 0.75) 90%
30
+ background-image: var(
31
+ --glare-image,
32
+ radial-gradient(
33
+ farthest-corner circle at var(--pointer-x) var(--pointer-y),
34
+ hsla(0, 0%, 100%, 0.8) 10%,
35
+ hsla(0, 0%, 100%, 0.5) 20%,
36
+ hsla(0, 0%, 0%, 0.75) 90%
37
+ )
35
38
  );
36
39
 
37
40
  filter: brightness(0.7) contrast(1.5);
package/src/ticker.ts CHANGED
@@ -5,13 +5,9 @@ const raf: (cb: (time: number) => void) => void =
5
5
  ? (cb) => requestAnimationFrame(cb)
6
6
  : (cb) => setTimeout(() => cb(now()), 1000 / 60);
7
7
 
8
- interface Task {
9
- c: (time: number) => boolean;
10
- f: () => void;
11
- }
8
+ type Task = (time: number) => boolean;
12
9
 
13
10
  export interface TaskHandle {
14
- promise: Promise<void>;
15
11
  abort: () => void;
16
12
  }
17
13
 
@@ -19,9 +15,8 @@ const tasks = new Set<Task>();
19
15
 
20
16
  const runTasks = (time: number): void => {
21
17
  tasks.forEach((task) => {
22
- if (!task.c(time)) {
18
+ if (!task(time)) {
23
19
  tasks.delete(task);
24
- task.f();
25
20
  }
26
21
  });
27
22
  if (tasks.size !== 0) {
@@ -29,18 +24,14 @@ const runTasks = (time: number): void => {
29
24
  }
30
25
  };
31
26
 
32
- export const loop = (callback: (time: number) => boolean): TaskHandle => {
33
- let task: Task;
27
+ export const loop = (callback: Task): TaskHandle => {
34
28
  if (tasks.size === 0) {
35
29
  raf(runTasks);
36
30
  }
31
+ tasks.add(callback);
37
32
  return {
38
- promise: new Promise<void>((fulfil) => {
39
- task = { c: callback, f: fulfil };
40
- tasks.add(task);
41
- }),
42
33
  abort: () => {
43
- tasks.delete(task);
34
+ tasks.delete(callback);
44
35
  },
45
36
  };
46
37
  };