@ansh-ui/core 0.2.0 → 0.3.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/behaviours.cjs +20 -15
- package/dist/behaviours.d.cts +2 -2
- package/dist/behaviours.d.ts +2 -2
- package/dist/behaviours.js +3 -2
- package/dist/{chunk-56NNBIAO.js → chunk-2DOA43UB.js} +1047 -18
- package/dist/chunk-2DOA43UB.js.map +1 -0
- package/dist/{chunk-7MYTSAPR.js → chunk-37GPMMMT.js} +3 -3
- package/dist/{chunk-7MYTSAPR.js.map → chunk-37GPMMMT.js.map} +1 -1
- package/dist/{chunk-23GSSIMK.cjs → chunk-4ORYTFY3.cjs} +3 -3
- package/dist/{chunk-23GSSIMK.cjs.map → chunk-4ORYTFY3.cjs.map} +1 -1
- package/dist/{chunk-MMO7KO53.cjs → chunk-FNR4B3KY.cjs} +3 -3
- package/dist/{chunk-MMO7KO53.cjs.map → chunk-FNR4B3KY.cjs.map} +1 -1
- package/dist/{chunk-BOQQHICI.js → chunk-GQH5ZHPB.js} +3 -3
- package/dist/{chunk-BOQQHICI.js.map → chunk-GQH5ZHPB.js.map} +1 -1
- package/dist/{chunk-R7UJ7MWP.cjs → chunk-OSNUN5JJ.cjs} +1070 -34
- package/dist/chunk-OSNUN5JJ.cjs.map +1 -0
- package/dist/{chunk-GHBRGMSO.cjs → chunk-PZF3YXVE.cjs} +6 -6
- package/dist/{chunk-GHBRGMSO.cjs.map → chunk-PZF3YXVE.cjs.map} +1 -1
- package/dist/{chunk-UJBXY6QC.cjs → chunk-SSAWZIO2.cjs} +150 -28
- package/dist/chunk-SSAWZIO2.cjs.map +1 -0
- package/dist/{chunk-C6XPQO2O.js → chunk-WLOGUD3G.js} +126 -5
- package/dist/{chunk-C6XPQO2O.js.map → chunk-WLOGUD3G.js.map} +1 -1
- package/dist/{chunk-KTUBCQC3.js → chunk-YHSCAGCI.js} +3 -3
- package/dist/{chunk-KTUBCQC3.js.map → chunk-YHSCAGCI.js.map} +1 -1
- package/dist/color.cjs +39 -39
- package/dist/color.d.cts +5 -4
- package/dist/color.d.ts +5 -4
- package/dist/color.js +3 -3
- package/dist/effects.cjs +53 -25
- package/dist/effects.d.cts +4 -4
- package/dist/effects.d.ts +4 -4
- package/dist/effects.js +4 -4
- package/dist/{index-CQEEPu-D.d.ts → index-DN0bQII7.d.ts} +47 -2
- package/dist/{index-DHOfsEIn.d.cts → index-DmJ3i1Tr.d.cts} +330 -4
- package/dist/{index-Dl8GCsya.d.cts → index-Dv3gw7Mb.d.cts} +47 -2
- package/dist/{index-CCdpefMp.d.ts → index-SO8zHlVo.d.ts} +330 -4
- package/dist/index.cjs +186 -154
- package/dist/index.d.cts +10 -9
- package/dist/index.d.ts +10 -9
- package/dist/index.js +9 -9
- package/dist/math.d.cts +3 -2
- package/dist/math.d.ts +3 -2
- package/dist/noise.d.cts +2 -1
- package/dist/noise.d.ts +2 -1
- package/dist/{palette-6HkVltYU.d.ts → palette-Dcomsp9R.d.cts} +2 -1
- package/dist/{palette-6HkVltYU.d.cts → palette-Dcomsp9R.d.ts} +2 -1
- package/dist/{random--4mSc5Lp.d.cts → random-YnhdaiIx.d.cts} +2 -1
- package/dist/{random--4mSc5Lp.d.ts → random-YnhdaiIx.d.ts} +2 -1
- package/dist/{reduced-motion-D0LUgZle.d.cts → reduced-motion-DaeXwgzb.d.cts} +2 -1
- package/dist/{reduced-motion-D0LUgZle.d.ts → reduced-motion-DaeXwgzb.d.ts} +2 -1
- package/package.json +1 -1
- package/dist/chunk-56NNBIAO.js.map +0 -1
- package/dist/chunk-R7UJ7MWP.cjs.map +0 -1
- package/dist/chunk-UJBXY6QC.cjs.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunk4ORYTFY3_cjs = require('./chunk-4ORYTFY3.cjs');
|
|
4
4
|
var chunkLGA3N3YJ_cjs = require('./chunk-LGA3N3YJ.cjs');
|
|
5
5
|
var chunkILKUL7GD_cjs = require('./chunk-ILKUL7GD.cjs');
|
|
6
6
|
|
|
@@ -8,7 +8,7 @@ var chunkILKUL7GD_cjs = require('./chunk-ILKUL7GD.cjs');
|
|
|
8
8
|
function contrastRatio(foreground, background) {
|
|
9
9
|
const bg = chunkLGA3N3YJ_cjs.parseColor(background);
|
|
10
10
|
const fgRaw = chunkLGA3N3YJ_cjs.parseColor(foreground);
|
|
11
|
-
const fg = fgRaw.a < 1 ?
|
|
11
|
+
const fg = fgRaw.a < 1 ? chunk4ORYTFY3_cjs.composite(bg, fgRaw) : fgRaw;
|
|
12
12
|
const l1 = chunkLGA3N3YJ_cjs.relativeLuminance(fg);
|
|
13
13
|
const l2 = chunkLGA3N3YJ_cjs.relativeLuminance(bg);
|
|
14
14
|
const lighter = Math.max(l1, l2);
|
|
@@ -43,7 +43,7 @@ function ensureContrast(foreground, background, target = 4.5) {
|
|
|
43
43
|
const limit = direction > 0 ? 1 - lch.l : lch.l;
|
|
44
44
|
for (let i = 1; i <= STEPS; i++) {
|
|
45
45
|
const l = chunkILKUL7GD_cjs.clamp(lch.l + direction * (limit * (i / STEPS)), 0, 1);
|
|
46
|
-
const candidate =
|
|
46
|
+
const candidate = chunk4ORYTFY3_cjs.oklchToRgbMapped({ l, c: lch.c, h: lch.h, alpha: fg.a });
|
|
47
47
|
const ratio = contrastRatio(candidate, bg);
|
|
48
48
|
if (ratio > bestRatio) {
|
|
49
49
|
bestRatio = ratio;
|
|
@@ -54,7 +54,7 @@ function ensureContrast(foreground, background, target = 4.5) {
|
|
|
54
54
|
for (let i = 1; i <= 8; i++) {
|
|
55
55
|
const c = lch.c * (1 - i / 8);
|
|
56
56
|
const l = direction > 0 ? 1 : 0;
|
|
57
|
-
const candidate =
|
|
57
|
+
const candidate = chunk4ORYTFY3_cjs.oklchToRgbMapped({ l, c, h: lch.h, alpha: fg.a });
|
|
58
58
|
const ratio = contrastRatio(candidate, bg);
|
|
59
59
|
if (ratio > bestRatio) {
|
|
60
60
|
bestRatio = ratio;
|
|
@@ -87,5 +87,5 @@ exports.perceivedLightness = perceivedLightness;
|
|
|
87
87
|
exports.pickReadable = pickReadable;
|
|
88
88
|
exports.requiredRatio = requiredRatio;
|
|
89
89
|
exports.worstContrast = worstContrast;
|
|
90
|
-
//# sourceMappingURL=chunk-
|
|
91
|
-
//# sourceMappingURL=chunk-
|
|
90
|
+
//# sourceMappingURL=chunk-PZF3YXVE.cjs.map
|
|
91
|
+
//# sourceMappingURL=chunk-PZF3YXVE.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/color/contrast.ts"],"names":["parseColor","composite","relativeLuminance","rgbToOklch","clamp","oklchToRgbMapped"],"mappings":"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","file":"chunk-GHBRGMSO.cjs","sourcesContent":["import { clamp } from '../math/scalar'\nimport { relativeLuminance, rgbToOklch } from './convert'\nimport { oklchToRgbMapped } from './gamut'\nimport { parseColor } from './parse'\nimport { composite } from './interpolate'\nimport type { ColorInput, Rgb } from './types'\n\n/**\n * Contrast and legibility.\n *\n * Animated backgrounds are the single most common way a design ends up failing WCAG: the text\n * was legible against the mockup's midpoint and illegible against the animation's brightest\n * frame. These helpers let components check contrast against the *extremes* of their own\n * palette and adapt, rather than hoping.\n */\n\nexport type WcagLevel = 'AA' | 'AAA'\nexport type TextSize = 'normal' | 'large'\n\n/**\n * WCAG 2.x contrast ratio, from 1 (identical) to 21 (black on white).\n *\n * Semi-transparent colours are composited over `background` first, because a ratio computed\n * from a colour's own alpha is meaningless — what matters is what the eye actually receives.\n */\nexport function contrastRatio(foreground: ColorInput, background: ColorInput): number {\n const bg = parseColor(background)\n const fgRaw = parseColor(foreground)\n const fg = fgRaw.a < 1 ? composite(bg, fgRaw) : fgRaw\n\n const l1 = relativeLuminance(fg)\n const l2 = relativeLuminance(bg)\n const lighter = Math.max(l1, l2)\n const darker = Math.min(l1, l2)\n return (lighter + 0.05) / (darker + 0.05)\n}\n\n/** Minimum ratio required by WCAG 2.2 for the given level and text size. */\nexport function requiredRatio(level: WcagLevel, size: TextSize): number {\n if (level === 'AAA') return size === 'large' ? 4.5 : 7\n return size === 'large' ? 3 : 4.5\n}\n\nexport interface ContrastResult {\n ratio: number\n passes: boolean\n required: number\n level: WcagLevel\n size: TextSize\n}\n\n/** Check a foreground/background pair against a WCAG threshold. */\nexport function checkContrast(\n foreground: ColorInput,\n background: ColorInput,\n level: WcagLevel = 'AA',\n size: TextSize = 'normal',\n): ContrastResult {\n const ratio = contrastRatio(foreground, background)\n const required = requiredRatio(level, size)\n return { ratio, passes: ratio >= required, required, level, size }\n}\n\n/**\n * Pick whichever of `light`/`dark` reads better on `background`.\n *\n * This is the function to reach for when a component renders text over a user-supplied\n * colour, which is most of them.\n */\nexport function pickReadable(\n background: ColorInput,\n light: ColorInput = '#ffffff',\n dark: ColorInput = '#0b0b0f',\n): Rgb {\n const lightRatio = contrastRatio(light, background)\n const darkRatio = contrastRatio(dark, background)\n return parseColor(lightRatio >= darkRatio ? light : dark)\n}\n\n/**\n * Adjust a colour's lightness until it meets a contrast target against `background`.\n *\n * Works in OKLCH so hue and chroma survive the adjustment — the brand colour stays\n * recognisably itself, it just gets light or dark enough to read. Searches in whichever\n * direction has more headroom, and returns the best achievable colour if the target is\n * unreachable (a mid-grey background cannot support 7:1 with a saturated hue at any lightness).\n */\nexport function ensureContrast(\n foreground: ColorInput,\n background: ColorInput,\n target = 4.5,\n): { color: Rgb; ratio: number; achieved: boolean } {\n const fg = parseColor(foreground)\n const bg = parseColor(background)\n\n const initial = contrastRatio(fg, bg)\n if (initial >= target) return { color: fg, ratio: initial, achieved: true }\n\n const lch = rgbToOklch(fg)\n const bgLuminance = relativeLuminance(bg)\n // Move away from the background: darken against a light background, lighten against a dark one.\n const direction = bgLuminance > 0.35 ? -1 : 1\n\n let best = fg\n let bestRatio = initial\n\n // 24 steps across the available lightness range lands within ~4% of optimal, which is\n // finer than the eye can distinguish and costs 24 cheap conversions.\n const STEPS = 24\n const limit = direction > 0 ? 1 - lch.l : lch.l\n\n for (let i = 1; i <= STEPS; i++) {\n const l = clamp(lch.l + direction * (limit * (i / STEPS)), 0, 1)\n const candidate = oklchToRgbMapped({ l, c: lch.c, h: lch.h, alpha: fg.a })\n const ratio = contrastRatio(candidate, bg)\n if (ratio > bestRatio) {\n bestRatio = ratio\n best = candidate\n if (ratio >= target) return { color: candidate, ratio, achieved: true }\n }\n }\n\n // Last resort: drop chroma too. Desaturating buys real lightness range at the extremes.\n for (let i = 1; i <= 8; i++) {\n const c = lch.c * (1 - i / 8)\n const l = direction > 0 ? 1 : 0\n const candidate = oklchToRgbMapped({ l, c, h: lch.h, alpha: fg.a })\n const ratio = contrastRatio(candidate, bg)\n if (ratio > bestRatio) {\n bestRatio = ratio\n best = candidate\n if (ratio >= target) return { color: candidate, ratio, achieved: true }\n }\n }\n\n return { color: best, ratio: bestRatio, achieved: bestRatio >= target }\n}\n\n/**\n * Worst-case contrast of a foreground against every colour in a set.\n *\n * An animated gradient background cycles through many colours; text must be legible against\n * all of them. Components call this with their resolved palette and surface a dev warning when\n * it fails, which turns an invisible accessibility bug into a console message during development.\n */\nexport function worstContrast(\n foreground: ColorInput,\n backgrounds: readonly ColorInput[],\n): { ratio: number; against: Rgb | null } {\n let worst = Infinity\n let against: Rgb | null = null\n for (const bg of backgrounds) {\n const ratio = contrastRatio(foreground, bg)\n if (ratio < worst) {\n worst = ratio\n against = parseColor(bg)\n }\n }\n return { ratio: Number.isFinite(worst) ? worst : 21, against }\n}\n\n/**\n * APCA-style perceptual lightness, used for ordering colours by visual weight.\n *\n * Not a WCAG 3 implementation — that specification is still in flux and we won't ship a\n * moving target as if it were stable. This is OKLab's `L`, which is a better predictor of\n * perceived lightness than WCAG's relative luminance and is entirely sufficient for the\n * internal job of sorting a palette light-to-dark.\n */\nexport function perceivedLightness(color: ColorInput): number {\n return rgbToOklch(parseColor(color)).l\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/color/contrast.ts"],"names":["parseColor","composite","relativeLuminance","rgbToOklch","clamp","oklchToRgbMapped"],"mappings":"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","file":"chunk-PZF3YXVE.cjs","sourcesContent":["import { clamp } from '../math/scalar'\nimport { relativeLuminance, rgbToOklch } from './convert'\nimport { oklchToRgbMapped } from './gamut'\nimport { parseColor } from './parse'\nimport { composite } from './interpolate'\nimport type { ColorInput, Rgb } from './types'\n\n/**\n * Contrast and legibility.\n *\n * Animated backgrounds are the single most common way a design ends up failing WCAG: the text\n * was legible against the mockup's midpoint and illegible against the animation's brightest\n * frame. These helpers let components check contrast against the *extremes* of their own\n * palette and adapt, rather than hoping.\n */\n\nexport type WcagLevel = 'AA' | 'AAA'\nexport type TextSize = 'normal' | 'large'\n\n/**\n * WCAG 2.x contrast ratio, from 1 (identical) to 21 (black on white).\n *\n * Semi-transparent colours are composited over `background` first, because a ratio computed\n * from a colour's own alpha is meaningless — what matters is what the eye actually receives.\n */\nexport function contrastRatio(foreground: ColorInput, background: ColorInput): number {\n const bg = parseColor(background)\n const fgRaw = parseColor(foreground)\n const fg = fgRaw.a < 1 ? composite(bg, fgRaw) : fgRaw\n\n const l1 = relativeLuminance(fg)\n const l2 = relativeLuminance(bg)\n const lighter = Math.max(l1, l2)\n const darker = Math.min(l1, l2)\n return (lighter + 0.05) / (darker + 0.05)\n}\n\n/** Minimum ratio required by WCAG 2.2 for the given level and text size. */\nexport function requiredRatio(level: WcagLevel, size: TextSize): number {\n if (level === 'AAA') return size === 'large' ? 4.5 : 7\n return size === 'large' ? 3 : 4.5\n}\n\nexport interface ContrastResult {\n ratio: number\n passes: boolean\n required: number\n level: WcagLevel\n size: TextSize\n}\n\n/** Check a foreground/background pair against a WCAG threshold. */\nexport function checkContrast(\n foreground: ColorInput,\n background: ColorInput,\n level: WcagLevel = 'AA',\n size: TextSize = 'normal',\n): ContrastResult {\n const ratio = contrastRatio(foreground, background)\n const required = requiredRatio(level, size)\n return { ratio, passes: ratio >= required, required, level, size }\n}\n\n/**\n * Pick whichever of `light`/`dark` reads better on `background`.\n *\n * This is the function to reach for when a component renders text over a user-supplied\n * colour, which is most of them.\n */\nexport function pickReadable(\n background: ColorInput,\n light: ColorInput = '#ffffff',\n dark: ColorInput = '#0b0b0f',\n): Rgb {\n const lightRatio = contrastRatio(light, background)\n const darkRatio = contrastRatio(dark, background)\n return parseColor(lightRatio >= darkRatio ? light : dark)\n}\n\n/**\n * Adjust a colour's lightness until it meets a contrast target against `background`.\n *\n * Works in OKLCH so hue and chroma survive the adjustment — the brand colour stays\n * recognisably itself, it just gets light or dark enough to read. Searches in whichever\n * direction has more headroom, and returns the best achievable colour if the target is\n * unreachable (a mid-grey background cannot support 7:1 with a saturated hue at any lightness).\n */\nexport function ensureContrast(\n foreground: ColorInput,\n background: ColorInput,\n target = 4.5,\n): { color: Rgb; ratio: number; achieved: boolean } {\n const fg = parseColor(foreground)\n const bg = parseColor(background)\n\n const initial = contrastRatio(fg, bg)\n if (initial >= target) return { color: fg, ratio: initial, achieved: true }\n\n const lch = rgbToOklch(fg)\n const bgLuminance = relativeLuminance(bg)\n // Move away from the background: darken against a light background, lighten against a dark one.\n const direction = bgLuminance > 0.35 ? -1 : 1\n\n let best = fg\n let bestRatio = initial\n\n // 24 steps across the available lightness range lands within ~4% of optimal, which is\n // finer than the eye can distinguish and costs 24 cheap conversions.\n const STEPS = 24\n const limit = direction > 0 ? 1 - lch.l : lch.l\n\n for (let i = 1; i <= STEPS; i++) {\n const l = clamp(lch.l + direction * (limit * (i / STEPS)), 0, 1)\n const candidate = oklchToRgbMapped({ l, c: lch.c, h: lch.h, alpha: fg.a })\n const ratio = contrastRatio(candidate, bg)\n if (ratio > bestRatio) {\n bestRatio = ratio\n best = candidate\n if (ratio >= target) return { color: candidate, ratio, achieved: true }\n }\n }\n\n // Last resort: drop chroma too. Desaturating buys real lightness range at the extremes.\n for (let i = 1; i <= 8; i++) {\n const c = lch.c * (1 - i / 8)\n const l = direction > 0 ? 1 : 0\n const candidate = oklchToRgbMapped({ l, c, h: lch.h, alpha: fg.a })\n const ratio = contrastRatio(candidate, bg)\n if (ratio > bestRatio) {\n bestRatio = ratio\n best = candidate\n if (ratio >= target) return { color: candidate, ratio, achieved: true }\n }\n }\n\n return { color: best, ratio: bestRatio, achieved: bestRatio >= target }\n}\n\n/**\n * Worst-case contrast of a foreground against every colour in a set.\n *\n * An animated gradient background cycles through many colours; text must be legible against\n * all of them. Components call this with their resolved palette and surface a dev warning when\n * it fails, which turns an invisible accessibility bug into a console message during development.\n */\nexport function worstContrast(\n foreground: ColorInput,\n backgrounds: readonly ColorInput[],\n): { ratio: number; against: Rgb | null } {\n let worst = Infinity\n let against: Rgb | null = null\n for (const bg of backgrounds) {\n const ratio = contrastRatio(foreground, bg)\n if (ratio < worst) {\n worst = ratio\n against = parseColor(bg)\n }\n }\n return { ratio: Number.isFinite(worst) ? worst : 21, against }\n}\n\n/**\n * APCA-style perceptual lightness, used for ordering colours by visual weight.\n *\n * Not a WCAG 3 implementation — that specification is still in flux and we won't ship a\n * moving target as if it were stable. This is OKLab's `L`, which is a better predictor of\n * perceived lightness than WCAG's relative luminance and is entirely sufficient for the\n * internal job of sorting a palette light-to-dark.\n */\nexport function perceivedLightness(color: ColorInput): number {\n return rgbToOklch(parseColor(color)).l\n}\n"]}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkFNR4B3KY_cjs = require('./chunk-FNR4B3KY.cjs');
|
|
4
4
|
var chunkLGA3N3YJ_cjs = require('./chunk-LGA3N3YJ.cjs');
|
|
5
5
|
var chunkGJRIHN76_cjs = require('./chunk-GJRIHN76.cjs');
|
|
6
|
+
var chunkFNR35HTL_cjs = require('./chunk-FNR35HTL.cjs');
|
|
6
7
|
var chunkILKUL7GD_cjs = require('./chunk-ILKUL7GD.cjs');
|
|
7
8
|
|
|
8
9
|
// src/behaviours/types.ts
|
|
9
10
|
function mountBehaviour(definition, element, userOptions = {}) {
|
|
10
|
-
|
|
11
|
+
chunkFNR4B3KY_cjs.getRegistry().requireCapability(definition.capability ?? "behaviour:core");
|
|
11
12
|
let options = { ...definition.defaults, ...stripUndefined(userOptions) };
|
|
12
13
|
let instance = definition.setup(element, options);
|
|
13
14
|
let destroyed = false;
|
|
@@ -33,7 +34,7 @@ function mountBehaviour(definition, element, userOptions = {}) {
|
|
|
33
34
|
};
|
|
34
35
|
}
|
|
35
36
|
function defineBehaviour(definition) {
|
|
36
|
-
const registry =
|
|
37
|
+
const registry = chunkFNR4B3KY_cjs.getRegistry();
|
|
37
38
|
if (!registry.has("behaviour", definition.name)) {
|
|
38
39
|
registry.register("behaviour", definition.name, definition);
|
|
39
40
|
}
|
|
@@ -85,7 +86,7 @@ var magnetic = defineBehaviour({
|
|
|
85
86
|
let opts = options;
|
|
86
87
|
const target = opts.target ? element.querySelector(opts.target) ?? element : element;
|
|
87
88
|
const restoreStyles = captureStyles(target, ["transform", "willChange"]);
|
|
88
|
-
const pointer =
|
|
89
|
+
const pointer = chunkFNR4B3KY_cjs.trackPointer(element, { trackOutside: true, smoothing: 1e-3 });
|
|
89
90
|
let x = 0;
|
|
90
91
|
let y = 0;
|
|
91
92
|
let vx = 0;
|
|
@@ -94,9 +95,9 @@ var magnetic = defineBehaviour({
|
|
|
94
95
|
let scaleVelocity = 0;
|
|
95
96
|
let rotation = 0;
|
|
96
97
|
let rotationVelocity = 0;
|
|
97
|
-
let motion =
|
|
98
|
+
let motion = chunkFNR4B3KY_cjs.resolveMotion(opts.reducedMotion);
|
|
98
99
|
target.style.willChange = "transform";
|
|
99
|
-
const ticker =
|
|
100
|
+
const ticker = chunkFNR4B3KY_cjs.getTicker();
|
|
100
101
|
const stop = ticker.add(
|
|
101
102
|
({ delta }) => {
|
|
102
103
|
if (opts.disabled || !motion.animate) return;
|
|
@@ -153,7 +154,7 @@ var magnetic = defineBehaviour({
|
|
|
153
154
|
return {
|
|
154
155
|
update(next) {
|
|
155
156
|
opts = { ...opts, ...next };
|
|
156
|
-
motion =
|
|
157
|
+
motion = chunkFNR4B3KY_cjs.resolveMotion(opts.reducedMotion);
|
|
157
158
|
if (opts.disabled || !motion.animate) {
|
|
158
159
|
x = y = vx = vy = 0;
|
|
159
160
|
scaleValue = 1;
|
|
@@ -192,14 +193,14 @@ var tilt = defineBehaviour({
|
|
|
192
193
|
setup(element, options) {
|
|
193
194
|
let opts = options;
|
|
194
195
|
const restoreStyles = captureStyles(element, ["transform", "transformStyle", "willChange"]);
|
|
195
|
-
const pointer =
|
|
196
|
+
const pointer = chunkFNR4B3KY_cjs.trackPointer(element, { smoothing: 2e-3 });
|
|
196
197
|
let rotateX = 0;
|
|
197
198
|
let rotateY = 0;
|
|
198
199
|
let velocityX = 0;
|
|
199
200
|
let velocityY = 0;
|
|
200
201
|
let presence = 0;
|
|
201
202
|
let presenceVelocity = 0;
|
|
202
|
-
let motion =
|
|
203
|
+
let motion = chunkFNR4B3KY_cjs.resolveMotion(opts.reducedMotion);
|
|
203
204
|
element.style.willChange = "transform";
|
|
204
205
|
element.style.transformStyle = "preserve-3d";
|
|
205
206
|
let glareElement = null;
|
|
@@ -233,7 +234,7 @@ var tilt = defineBehaviour({
|
|
|
233
234
|
glareElement = null;
|
|
234
235
|
}
|
|
235
236
|
ensureGlare();
|
|
236
|
-
const ticker =
|
|
237
|
+
const ticker = chunkFNR4B3KY_cjs.getTicker();
|
|
237
238
|
const stop = ticker.add(
|
|
238
239
|
({ delta }) => {
|
|
239
240
|
if (opts.disabled || !motion.animate) return;
|
|
@@ -279,7 +280,7 @@ var tilt = defineBehaviour({
|
|
|
279
280
|
update(next) {
|
|
280
281
|
const previousGlare = opts.glare;
|
|
281
282
|
opts = { ...opts, ...next };
|
|
282
|
-
motion =
|
|
283
|
+
motion = chunkFNR4B3KY_cjs.resolveMotion(opts.reducedMotion);
|
|
283
284
|
if (opts.glare !== previousGlare) ensureGlare();
|
|
284
285
|
if (opts.disabled || !motion.animate) {
|
|
285
286
|
rotateX = rotateY = velocityX = velocityY = 0;
|
|
@@ -344,7 +345,7 @@ var marquee = defineBehaviour({
|
|
|
344
345
|
let offset = 0;
|
|
345
346
|
let currentSpeed = 0;
|
|
346
347
|
let hovering = false;
|
|
347
|
-
let motion =
|
|
348
|
+
let motion = chunkFNR4B3KY_cjs.resolveMotion(opts.reducedMotion);
|
|
348
349
|
function rebuild() {
|
|
349
350
|
for (const clone of clones) clone.remove();
|
|
350
351
|
clones = [];
|
|
@@ -373,8 +374,8 @@ var marquee = defineBehaviour({
|
|
|
373
374
|
element.style.setProperty("mask-image", mask);
|
|
374
375
|
element.style.setProperty("-webkit-mask-image", mask);
|
|
375
376
|
}
|
|
376
|
-
const stopResize =
|
|
377
|
-
const stopTrackResize =
|
|
377
|
+
const stopResize = chunkFNR4B3KY_cjs.observeResize(element, rebuild);
|
|
378
|
+
const stopTrackResize = chunkFNR4B3KY_cjs.observeResize(track, rebuild);
|
|
378
379
|
const onEnter = () => {
|
|
379
380
|
hovering = true;
|
|
380
381
|
};
|
|
@@ -385,7 +386,7 @@ var marquee = defineBehaviour({
|
|
|
385
386
|
element.addEventListener("pointerleave", onLeave, { passive: true });
|
|
386
387
|
applyEdgeFade();
|
|
387
388
|
rebuild();
|
|
388
|
-
const ticker =
|
|
389
|
+
const ticker = chunkFNR4B3KY_cjs.getTicker();
|
|
389
390
|
const stop = ticker.add(
|
|
390
391
|
({ delta }) => {
|
|
391
392
|
if (opts.disabled || !motion.animate || cycleSize <= 0) return;
|
|
@@ -407,7 +408,7 @@ var marquee = defineBehaviour({
|
|
|
407
408
|
const previousGap = opts.gap;
|
|
408
409
|
const previousFade = opts.fadeEdges;
|
|
409
410
|
opts = { ...opts, ...next };
|
|
410
|
-
motion =
|
|
411
|
+
motion = chunkFNR4B3KY_cjs.resolveMotion(opts.reducedMotion);
|
|
411
412
|
if (opts.gap !== previousGap) {
|
|
412
413
|
track.style.gap = opts.gap ? `${opts.gap}px` : "";
|
|
413
414
|
rebuild();
|
|
@@ -795,7 +796,7 @@ var scrollReveal = defineBehaviour({
|
|
|
795
796
|
target.time = 0;
|
|
796
797
|
applyProgress(target, 0);
|
|
797
798
|
}
|
|
798
|
-
const ticker =
|
|
799
|
+
const ticker = chunkFNR4B3KY_cjs.getTicker();
|
|
799
800
|
function startTicker() {
|
|
800
801
|
if (stopTicker) return;
|
|
801
802
|
stopTicker = ticker.add(
|
|
@@ -830,12 +831,12 @@ var scrollReveal = defineBehaviour({
|
|
|
830
831
|
);
|
|
831
832
|
}
|
|
832
833
|
collectTargets();
|
|
833
|
-
const skipAnimation = opts.disabled ||
|
|
834
|
+
const skipAnimation = opts.disabled || chunkFNR4B3KY_cjs.prefersReducedMotion() && opts.reducedMotion !== "none";
|
|
834
835
|
if (!skipAnimation) {
|
|
835
836
|
for (const target of targets) hide(target);
|
|
836
837
|
}
|
|
837
838
|
const stopObserver = skipAnimation ? () => {
|
|
838
|
-
} :
|
|
839
|
+
} : chunkFNR4B3KY_cjs.observeIntersection(
|
|
839
840
|
element,
|
|
840
841
|
(entry) => {
|
|
841
842
|
if (entry.isIntersecting) {
|
|
@@ -904,7 +905,7 @@ var parallax = defineBehaviour({
|
|
|
904
905
|
let containerSize = 0;
|
|
905
906
|
let needsMeasure = true;
|
|
906
907
|
let currentTranslate = 0;
|
|
907
|
-
let motion =
|
|
908
|
+
let motion = chunkFNR4B3KY_cjs.resolveMotion(opts.reducedMotion);
|
|
908
909
|
element.style.willChange = "transform";
|
|
909
910
|
function measure() {
|
|
910
911
|
const rect = element.getBoundingClientRect();
|
|
@@ -925,10 +926,10 @@ var parallax = defineBehaviour({
|
|
|
925
926
|
needsMeasure = true;
|
|
926
927
|
};
|
|
927
928
|
window.addEventListener("resize", invalidate, { passive: true });
|
|
928
|
-
const stopResize =
|
|
929
|
+
const stopResize = chunkFNR4B3KY_cjs.observeResize(element, invalidate);
|
|
929
930
|
let scroll = 0;
|
|
930
931
|
let progress = 0;
|
|
931
|
-
const ticker =
|
|
932
|
+
const ticker = chunkFNR4B3KY_cjs.getTicker();
|
|
932
933
|
const stopRead = ticker.add(
|
|
933
934
|
() => {
|
|
934
935
|
if (opts.disabled || !motion.animate) return;
|
|
@@ -981,7 +982,7 @@ var parallax = defineBehaviour({
|
|
|
981
982
|
return {
|
|
982
983
|
update(next) {
|
|
983
984
|
opts = { ...opts, ...next };
|
|
984
|
-
motion =
|
|
985
|
+
motion = chunkFNR4B3KY_cjs.resolveMotion(opts.reducedMotion);
|
|
985
986
|
needsMeasure = true;
|
|
986
987
|
if (opts.disabled || !motion.animate) {
|
|
987
988
|
element.style.transform = "";
|
|
@@ -1039,7 +1040,7 @@ var ripple = defineBehaviour({
|
|
|
1039
1040
|
element.appendChild(layer);
|
|
1040
1041
|
const active = [];
|
|
1041
1042
|
let stopTicker = null;
|
|
1042
|
-
const ticker =
|
|
1043
|
+
const ticker = chunkFNR4B3KY_cjs.getTicker();
|
|
1043
1044
|
function resolveColor() {
|
|
1044
1045
|
const raw = opts.color;
|
|
1045
1046
|
if (raw === "currentColor") {
|
|
@@ -1097,7 +1098,7 @@ var ripple = defineBehaviour({
|
|
|
1097
1098
|
if (stopTicker) return;
|
|
1098
1099
|
stopTicker = ticker.add(
|
|
1099
1100
|
({ delta }) => {
|
|
1100
|
-
const scale =
|
|
1101
|
+
const scale = chunkFNR4B3KY_cjs.prefersReducedMotion() && opts.reducedMotion === "slow" ? 0.4 : 1;
|
|
1101
1102
|
const duration = Math.max(0.01, opts.duration * scale);
|
|
1102
1103
|
const fade = Math.max(0, opts.fadeDuration * scale);
|
|
1103
1104
|
const total = duration + fade;
|
|
@@ -1156,6 +1157,125 @@ var ripple = defineBehaviour({
|
|
|
1156
1157
|
}
|
|
1157
1158
|
});
|
|
1158
1159
|
|
|
1160
|
+
// src/behaviours/text-scramble.ts
|
|
1161
|
+
var DEFAULTS8 = {
|
|
1162
|
+
intensity: 1,
|
|
1163
|
+
// `static` rather than `slow`: the churn is high-frequency flicker in the reader's focal area,
|
|
1164
|
+
// which is exactly the kind of motion the preference exists to suppress. Reduced-motion users
|
|
1165
|
+
// get the finished text immediately.
|
|
1166
|
+
reducedMotion: "static",
|
|
1167
|
+
disabled: false,
|
|
1168
|
+
chars: "!<>-_\\/[]{}\u2014=+*^?#________",
|
|
1169
|
+
duration: 0.55,
|
|
1170
|
+
stagger: 0.035,
|
|
1171
|
+
cycleSpeed: 26,
|
|
1172
|
+
trigger: "view",
|
|
1173
|
+
repeat: false,
|
|
1174
|
+
threshold: 0.3,
|
|
1175
|
+
seed: 1
|
|
1176
|
+
};
|
|
1177
|
+
var textScramble = defineBehaviour({
|
|
1178
|
+
name: "text-scramble",
|
|
1179
|
+
defaults: DEFAULTS8,
|
|
1180
|
+
setup(element, options) {
|
|
1181
|
+
let opts = options;
|
|
1182
|
+
const original = element.textContent ?? "";
|
|
1183
|
+
const length = original.length;
|
|
1184
|
+
const pool = opts.chars.length > 0 ? opts.chars : DEFAULTS8.chars;
|
|
1185
|
+
const rng = chunkFNR35HTL_cjs.createRng(opts.seed);
|
|
1186
|
+
const current = Array.from(original);
|
|
1187
|
+
const lastTick = new Int32Array(Math.max(1, length));
|
|
1188
|
+
let elapsed = 0;
|
|
1189
|
+
let running = false;
|
|
1190
|
+
let hasRun = false;
|
|
1191
|
+
let stopFrame = null;
|
|
1192
|
+
const isWhitespace = (character) => character.trim() === "";
|
|
1193
|
+
const totalDuration = () => Math.max(0, length - 1) * opts.stagger + opts.duration;
|
|
1194
|
+
function writeFinal() {
|
|
1195
|
+
element.textContent = original;
|
|
1196
|
+
}
|
|
1197
|
+
function stopFrames() {
|
|
1198
|
+
stopFrame?.();
|
|
1199
|
+
stopFrame = null;
|
|
1200
|
+
running = false;
|
|
1201
|
+
}
|
|
1202
|
+
function run() {
|
|
1203
|
+
if (opts.disabled) return;
|
|
1204
|
+
if (hasRun && !opts.repeat) return;
|
|
1205
|
+
const motion = chunkFNR4B3KY_cjs.resolveMotion(opts.reducedMotion);
|
|
1206
|
+
if (!motion.animate) {
|
|
1207
|
+
hasRun = true;
|
|
1208
|
+
writeFinal();
|
|
1209
|
+
return;
|
|
1210
|
+
}
|
|
1211
|
+
hasRun = true;
|
|
1212
|
+
elapsed = 0;
|
|
1213
|
+
lastTick.fill(-1);
|
|
1214
|
+
running = true;
|
|
1215
|
+
if (stopFrame) return;
|
|
1216
|
+
const ticker = chunkFNR4B3KY_cjs.getTicker();
|
|
1217
|
+
stopFrame = ticker.add(
|
|
1218
|
+
({ delta }) => {
|
|
1219
|
+
if (!running || opts.disabled) return;
|
|
1220
|
+
elapsed += delta * motion.timeScale * opts.intensity;
|
|
1221
|
+
const total = totalDuration();
|
|
1222
|
+
if (elapsed >= total) {
|
|
1223
|
+
writeFinal();
|
|
1224
|
+
stopFrames();
|
|
1225
|
+
return;
|
|
1226
|
+
}
|
|
1227
|
+
const tick = Math.floor(elapsed * opts.cycleSpeed);
|
|
1228
|
+
for (let i = 0; i < length; i++) {
|
|
1229
|
+
const character = original[i];
|
|
1230
|
+
if (isWhitespace(character)) continue;
|
|
1231
|
+
if (elapsed >= i * opts.stagger + opts.duration) {
|
|
1232
|
+
current[i] = character;
|
|
1233
|
+
continue;
|
|
1234
|
+
}
|
|
1235
|
+
if (lastTick[i] !== tick) {
|
|
1236
|
+
lastTick[i] = tick;
|
|
1237
|
+
current[i] = pool[rng.int(0, pool.length - 1)];
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
element.textContent = current.join("");
|
|
1241
|
+
},
|
|
1242
|
+
{ phase: "write" }
|
|
1243
|
+
);
|
|
1244
|
+
}
|
|
1245
|
+
let stopObserver = null;
|
|
1246
|
+
let detachHover = null;
|
|
1247
|
+
if (chunkFNR4B3KY_cjs.prefersReducedMotion() && opts.reducedMotion === "static") ; else if (opts.trigger === "mount") {
|
|
1248
|
+
run();
|
|
1249
|
+
} else if (opts.trigger === "hover") {
|
|
1250
|
+
const onEnter = () => run();
|
|
1251
|
+
element.addEventListener("pointerenter", onEnter);
|
|
1252
|
+
detachHover = () => element.removeEventListener("pointerenter", onEnter);
|
|
1253
|
+
} else {
|
|
1254
|
+
stopObserver = chunkFNR4B3KY_cjs.observeIntersection(
|
|
1255
|
+
element,
|
|
1256
|
+
(entry) => {
|
|
1257
|
+
if (entry.isIntersecting) run();
|
|
1258
|
+
else if (opts.repeat) hasRun = false;
|
|
1259
|
+
},
|
|
1260
|
+
{ threshold: opts.threshold }
|
|
1261
|
+
);
|
|
1262
|
+
}
|
|
1263
|
+
return {
|
|
1264
|
+
update(next) {
|
|
1265
|
+
opts = { ...opts, ...next };
|
|
1266
|
+
},
|
|
1267
|
+
destroy() {
|
|
1268
|
+
stopFrames();
|
|
1269
|
+
stopObserver?.();
|
|
1270
|
+
detachHover?.();
|
|
1271
|
+
stopObserver = null;
|
|
1272
|
+
detachHover = null;
|
|
1273
|
+
writeFinal();
|
|
1274
|
+
}
|
|
1275
|
+
};
|
|
1276
|
+
}
|
|
1277
|
+
});
|
|
1278
|
+
|
|
1159
1279
|
// src/behaviours/index.ts
|
|
1160
1280
|
var behaviours = {
|
|
1161
1281
|
magnetic,
|
|
@@ -1164,7 +1284,8 @@ var behaviours = {
|
|
|
1164
1284
|
"split-text": splitText,
|
|
1165
1285
|
"scroll-reveal": scrollReveal,
|
|
1166
1286
|
parallax,
|
|
1167
|
-
ripple
|
|
1287
|
+
ripple,
|
|
1288
|
+
"text-scramble": textScramble
|
|
1168
1289
|
};
|
|
1169
1290
|
|
|
1170
1291
|
exports.behaviours = behaviours;
|
|
@@ -1181,6 +1302,7 @@ exports.split = split;
|
|
|
1181
1302
|
exports.splitText = splitText;
|
|
1182
1303
|
exports.stagger = stagger;
|
|
1183
1304
|
exports.staggerDuration = staggerDuration;
|
|
1305
|
+
exports.textScramble = textScramble;
|
|
1184
1306
|
exports.tilt = tilt;
|
|
1185
|
-
//# sourceMappingURL=chunk-
|
|
1186
|
-
//# sourceMappingURL=chunk-
|
|
1307
|
+
//# sourceMappingURL=chunk-SSAWZIO2.cjs.map
|
|
1308
|
+
//# sourceMappingURL=chunk-SSAWZIO2.cjs.map
|