use-scroll-animate 4.6.0 → 4.8.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/CHANGELOG.md +18 -0
- package/README.md +1 -1
- package/README_ja.md +1 -1
- package/README_zh.md +1 -1
- package/dist/chunks/{index-tags-BQh_uGqH.cjs → index-tags-CIRY2KnU.cjs} +2 -2
- package/dist/chunks/{index-tags-BQh_uGqH.cjs.map → index-tags-CIRY2KnU.cjs.map} +1 -1
- package/dist/chunks/{index-tags-43Xtd01A.js → index-tags-Dh8nwXqw.js} +2 -2
- package/dist/chunks/{index-tags-43Xtd01A.js.map → index-tags-Dh8nwXqw.js.map} +1 -1
- package/dist/components/a11y.cjs +1 -1
- package/dist/components/a11y.d.cts +1 -1
- package/dist/components/a11y.d.ts +1 -1
- package/dist/components/a11y.js +1 -1
- package/dist/components/angular.cjs +2 -1
- package/dist/components/angular.cjs.map +1 -1
- package/dist/components/angular.d.cts +2 -1
- package/dist/components/angular.d.ts +2 -1
- package/dist/components/angular.js +2 -1
- package/dist/components/angular.js.map +1 -1
- package/dist/components/bridge.cjs +154 -0
- package/dist/components/bridge.cjs.map +1 -0
- package/dist/components/bridge.d.cts +63 -0
- package/dist/components/bridge.d.ts +63 -0
- package/dist/components/bridge.js +147 -0
- package/dist/components/bridge.js.map +1 -0
- package/dist/components/jsx.d.cts +1 -1
- package/dist/components/jsx.d.ts +1 -1
- package/dist/components/lazy.cjs +1 -1
- package/dist/components/lazy.d.cts +1 -1
- package/dist/components/lazy.d.ts +1 -1
- package/dist/components/lazy.js +1 -1
- package/dist/components/lite.cjs +333 -10
- package/dist/components/lite.cjs.map +1 -1
- package/dist/components/lite.js +320 -11
- package/dist/components/lite.js.map +1 -1
- package/dist/components/perf.cjs +1 -1
- package/dist/components/perf.d.cts +1 -1
- package/dist/components/perf.d.ts +1 -1
- package/dist/components/perf.js +1 -1
- package/dist/components/react.cjs +1 -1
- package/dist/components/react.js +1 -1
- package/dist/components/solid.cjs +2 -1
- package/dist/components/solid.cjs.map +1 -1
- package/dist/components/solid.d.cts +2 -1
- package/dist/components/solid.d.ts +2 -1
- package/dist/components/solid.js +2 -1
- package/dist/components/solid.js.map +1 -1
- package/dist/components/svelte.cjs +2 -1
- package/dist/components/svelte.cjs.map +1 -1
- package/dist/components/svelte.d.cts +2 -1
- package/dist/components/svelte.d.ts +2 -1
- package/dist/components/svelte.js +2 -1
- package/dist/components/svelte.js.map +1 -1
- package/dist/components/vue.cjs +2 -1
- package/dist/components/vue.cjs.map +1 -1
- package/dist/components/vue.d.cts +2 -1
- package/dist/components/vue.d.ts +2 -1
- package/dist/components/vue.js +2 -1
- package/dist/components/vue.js.map +1 -1
- package/dist/components/webgl.cjs +184 -10
- package/dist/components/webgl.cjs.map +1 -1
- package/dist/components/webgl.css +1 -1
- package/dist/components/webgl.d.cts +59 -5
- package/dist/components/webgl.d.ts +59 -5
- package/dist/components/webgl.js +178 -12
- package/dist/components/webgl.js.map +1 -1
- package/dist/components.cjs +16 -1
- package/dist/components.cjs.map +1 -1
- package/dist/components.css +1 -1
- package/dist/components.d.cts +119 -6
- package/dist/components.d.ts +119 -6
- package/dist/components.js +3 -2
- package/dist/components.js.map +1 -1
- package/dist/components.umd.js +3 -2
- package/dist/components.umd.js.map +1 -1
- package/docs/ROADMAP.md +2 -2
- package/docs/components.md +7 -0
- package/docs/hybrid-apps.md +15 -0
- package/package.json +11 -1
package/dist/components/lite.cjs
CHANGED
|
@@ -388,7 +388,7 @@ const COMPONENT_CATEGORIES = {
|
|
|
388
388
|
timeline: ['usa-timeline'],
|
|
389
389
|
gesture: ['usa-swipeable', 'usa-pinch-zoom'],
|
|
390
390
|
svg: ['usa-draw', 'usa-morph', 'usa-mask-reveal', 'usa-anim-icon'],
|
|
391
|
-
webgl: ['usa-shader', 'usa-distort', 'usa-liquid'],
|
|
391
|
+
webgl: ['usa-shader', 'usa-distort', 'usa-liquid', 'usa-post-fx'],
|
|
392
392
|
depth: ['usa-cube', 'usa-depth'],
|
|
393
393
|
layout: ['usa-auto-animate', 'usa-masonry'],
|
|
394
394
|
packs: ['usa-pack'],
|
|
@@ -8953,6 +8953,12 @@ const SHADERS = {
|
|
|
8953
8953
|
waves: 'void main(){vec2 u=v_uv;float t=u_time*.4;float w=0.;for(int i=0;i<4;i++){float f=float(i)+1.;w+=sin(u.x*6.*f+t*f)*.08/f;}float l=smoothstep(.0,.02,abs(u.y-.5-w));vec3 col=mix(vec3(.2,.5,1.),vec3(.04,.06,.15),l)+vec3(.1,.0,.2)*u.y;gl_FragColor=vec4(col,1.);}',
|
|
8954
8954
|
aurora: 'void main(){vec2 u=v_uv;float t=u_time*.2;float b=0.;for(int i=0;i<3;i++){float f=float(i);b+=.4/abs((u.y-.6+.15*sin(u.x*3.+t+f*1.7))*(8.+f*4.));}vec3 col=vec3(.02,.03,.08)+b*mix(vec3(.1,.9,.6),vec3(.6,.3,1.),u.x)*.35;gl_FragColor=vec4(col,1.);}',
|
|
8955
8955
|
distort: 'void main(){vec2 u=v_uv;vec2 d=u-u_mouse;float r=length(d);float k=u_hover*.08*exp(-r*r*18.);u-=normalize(d+1e-4)*k;float s=u_hover*.006;vec3 col=vec3(texture2D(u_tex,u+vec2(s,0.)).r,texture2D(u_tex,u).g,texture2D(u_tex,u-vec2(s,0.)).b);gl_FragColor=vec4(col,1.);}',
|
|
8956
|
+
// 4.8 particle presets (procedural, one quad: no buffers, no per-particle JS)
|
|
8957
|
+
snow: 'float h(vec2 p){return fract(sin(dot(p,vec2(127.1,311.7)))*43758.5453);}void main(){vec2 u=v_uv;u.x*=u_resolution.x/max(u_resolution.y,1.);vec3 col=mix(vec3(.05,.08,.16),vec3(.12,.16,.3),v_uv.y);for(int l=0;l<3;l++){float s=8.+float(l)*7.;vec2 q=u*s;q.y+=u_time*(.6+float(l)*.35);q.x+=sin(q.y*.7+float(l))*.3;vec2 id=floor(q);vec2 f=fract(q)-.5;float r=h(id);if(r>.6){vec2 o=vec2(h(id+3.)-.5,h(id+7.)-.5)*.6;float d=length(f-o);col+=smoothstep(.09-float(l)*.02,0.,d)*(.5+.5*r);}}gl_FragColor=vec4(col,1.);}',
|
|
8958
|
+
fireflies: 'float h(vec2 p){return fract(sin(dot(p,vec2(127.1,311.7)))*43758.5453);}void main(){vec2 u=v_uv;u.x*=u_resolution.x/max(u_resolution.y,1.);vec3 col=vec3(.02,.04,.03);for(int l=0;l<2;l++){vec2 q=u*(5.+float(l)*4.);vec2 id=floor(q);vec2 f=fract(q)-.5;float r=h(id+float(l)*13.);vec2 o=.35*vec2(sin(u_time*(.4+r)+r*6.28),cos(u_time*(.3+r)+r*12.));float d=length(f-o);float tw=.5+.5*sin(u_time*3.*r+r*20.);col+=vec3(1.,.85,.3)*smoothstep(.12,0.,d)*tw*step(.45,r);}gl_FragColor=vec4(col,1.);}',
|
|
8959
|
+
stars: 'float h(vec2 p){return fract(sin(dot(p,vec2(127.1,311.7)))*43758.5453);}void main(){vec2 c=v_uv-.5;c.x*=u_resolution.x/max(u_resolution.y,1.);vec3 col=vec3(.01,.01,.04);for(int l=0;l<4;l++){float z=fract(float(l)*.25+u_time*.05);float sc=mix(20.,.5,z);vec2 q=c*sc+float(l)*7.;vec2 id=floor(q);vec2 f=fract(q)-.5;float r=h(id);float d=length(f-(vec2(h(id+1.),h(id+2.))-.5)*.7);col+=vec3(.8,.9,1.)*smoothstep(.06,0.,d)*step(.8,r)*smoothstep(0.,.5,z)*smoothstep(1.,.8,z)*2.;}gl_FragColor=vec4(col,1.);}',
|
|
8960
|
+
bokeh: 'float h(vec2 p){return fract(sin(dot(p,vec2(127.1,311.7)))*43758.5453);}void main(){vec2 u=v_uv;u.x*=u_resolution.x/max(u_resolution.y,1.);vec3 col=mix(vec3(.08,.03,.12),vec3(.02,.05,.12),v_uv.y);for(int l=0;l<3;l++){vec2 q=u*(2.5+float(l)*1.5);q.y-=u_time*.05*(1.+float(l));vec2 id=floor(q);vec2 f=fract(q)-.5;float r=h(id+float(l)*5.);float d=length(f-(vec2(h(id+4.),h(id+9.))-.5)*.5);vec3 tint=.5+.5*cos(r*6.28+vec3(0.,2.,4.));col+=tint*smoothstep(.3,.26,d)*.18*step(.35,r);}gl_FragColor=vec4(col,1.);}',
|
|
8961
|
+
rain: 'float h(float n){return fract(sin(n)*43758.5453);}void main(){vec2 u=v_uv;vec3 col=mix(vec3(.04,.06,.1),vec3(.1,.13,.2),u.y);float n=floor(u.x*120.);float sp=.8+h(n)*1.2;float y=fract(u.y+u_time*sp+h(n+1.));float drop=smoothstep(.0,.08,y)*smoothstep(.16,.08,y)*step(.7,h(n+2.));col+=vec3(.5,.6,.8)*drop*.6;gl_FragColor=vec4(col,1.);}',
|
|
8956
8962
|
liquid: 'void main(){vec2 u=v_uv;vec2 o=vec2(0.);for(int i=0;i<4;i++){vec4 r=u_ripples[i];if(r.w>0.){float d=distance(u,r.xy);float w=sin(d*60.-r.z*12.)*exp(-d*6.)*exp(-r.z*1.6)*r.w*.02;o+=normalize(u-r.xy+1e-4)*w;}}o+=vec2(sin(u.y*10.+u_time),cos(u.x*10.+u_time))*.002*u_hover;gl_FragColor=texture2D(u_tex,u+o);}',
|
|
8957
8963
|
};
|
|
8958
8964
|
/** Full fragment source for a preset or custom body (adds the shared header). */
|
|
@@ -9012,9 +9018,10 @@ function glQuad(canvas, frag) {
|
|
|
9012
9018
|
const U = (n) => g.getUniformLocation(prog, n);
|
|
9013
9019
|
const uT = U('u_time'), uR = U('u_resolution'), uM = U('u_mouse'), uH = U('u_hover'), uRp = U('u_ripples');
|
|
9014
9020
|
let tex = null;
|
|
9021
|
+
const extraLoc = {};
|
|
9015
9022
|
const quad = {
|
|
9016
|
-
resize() {
|
|
9017
|
-
const dpr = Math.min(2, (typeof devicePixelRatio === 'number' && devicePixelRatio) || 1);
|
|
9023
|
+
resize(scale = 1) {
|
|
9024
|
+
const dpr = Math.min(2, (typeof devicePixelRatio === 'number' && devicePixelRatio) || 1) * Math.min(1, Math.max(0.25, scale));
|
|
9018
9025
|
const w = Math.max(1, Math.round((canvas.clientWidth || 300) * dpr));
|
|
9019
9026
|
const h = Math.max(1, Math.round((canvas.clientHeight || 150) * dpr));
|
|
9020
9027
|
if (canvas.width !== w || canvas.height !== h)
|
|
@@ -9037,6 +9044,9 @@ function glQuad(canvas, frag) {
|
|
|
9037
9044
|
g.uniform1f(uH, u.hover ?? 0);
|
|
9038
9045
|
if (uRp)
|
|
9039
9046
|
g.uniform4fv(uRp, new Float32Array((u.ripples ?? []).concat(Array(16).fill(0)).slice(0, 16)));
|
|
9047
|
+
if (u.extra)
|
|
9048
|
+
for (const [k, v] of Object.entries(u.extra))
|
|
9049
|
+
g.uniform1f((extraLoc[k] ?? (extraLoc[k] = U(k))), v);
|
|
9040
9050
|
g.drawArrays(g.TRIANGLES, 0, 6);
|
|
9041
9051
|
},
|
|
9042
9052
|
dispose() {
|
|
@@ -9051,6 +9061,131 @@ function glQuad(canvas, frag) {
|
|
|
9051
9061
|
return quad;
|
|
9052
9062
|
}
|
|
9053
9063
|
|
|
9064
|
+
/**
|
|
9065
|
+
* 4.8 — WebGL preset library on `glQuad()`: particle presets (`snow`,
|
|
9066
|
+
* `fireflies`, `stars`, `bokeh`, `rain` — usable as `<usa-shader preset>`),
|
|
9067
|
+
* chainable post-processing passes for images (`<usa-post-fx>`), one CSS
|
|
9068
|
+
* fallback per preset, and an adaptive quality governor (fps + battery).
|
|
9069
|
+
*/
|
|
9070
|
+
const PARTICLE_PRESETS = ['snow', 'fireflies', 'stars', 'bokeh', 'rain'];
|
|
9071
|
+
/** Post-processing passes: `vec3 fx(vec3 c, vec2 uv)` bodies, applied in order. `u_intensity` 0–1. */
|
|
9072
|
+
const POST_EFFECTS = {
|
|
9073
|
+
vignette: 'c*=mix(1.,smoothstep(.85,.25,length(uv-.5)),u_intensity);',
|
|
9074
|
+
grain: 'c+=(fract(sin(dot(uv*u_resolution+u_time,vec2(12.9898,78.233)))*43758.5453)-.5)*.18*u_intensity;',
|
|
9075
|
+
chromatic: 'float s=.008*u_intensity;c=vec3(texture2D(u_tex,uv+vec2(s,0.)).r,c.g,texture2D(u_tex,uv-vec2(s,0.)).b);',
|
|
9076
|
+
scanlines: 'c*=1.-.25*u_intensity*step(.5,fract(uv.y*u_resolution.y*.5));',
|
|
9077
|
+
crt: 'vec2 d=uv-.5;float r=dot(d,d);c*=1.-.6*u_intensity*r;c*=.92+.08*sin(uv.y*u_resolution.y*3.14159);c.r*=1.+.05*u_intensity;',
|
|
9078
|
+
bloom: 'vec3 b=vec3(0.);for(int i=0;i<8;i++){float a=float(i)*.785;b+=max(texture2D(u_tex,uv+vec2(cos(a),sin(a))*.012).rgb-.6,0.);}c+=b*.35*u_intensity;',
|
|
9079
|
+
pixelate: 'float px=mix(1.,48.,u_intensity);vec2 g=floor(uv*u_resolution/px)*px/u_resolution;c=texture2D(u_tex,g+.5*px/u_resolution).rgb;',
|
|
9080
|
+
duotone: 'float l=dot(c,vec3(.299,.587,.114));c=mix(c,mix(vec3(.12,.05,.35),vec3(1.,.55,.4),l),u_intensity);',
|
|
9081
|
+
glitch: 'float k=step(.97,fract(sin(floor(uv.y*24.)+floor(u_time*6.))*4375.5));c=mix(c,texture2D(u_tex,uv+vec2(k*.04*u_intensity,0.)).rgb,k);',
|
|
9082
|
+
};
|
|
9083
|
+
/** One fragment shader running the passes in order over `u_tex` (pixel-sampling passes read the source). */
|
|
9084
|
+
function postFxShader(effects) {
|
|
9085
|
+
const list = effects.filter((e) => POST_EFFECTS[e]);
|
|
9086
|
+
const body = list.map((e) => `{${POST_EFFECTS[e]}}`).join('');
|
|
9087
|
+
return `uniform float u_intensity;void main(){vec2 uv=v_uv;vec3 c=texture2D(u_tex,uv).rgb;${body}gl_FragColor=vec4(clamp(c,0.,1.),1.);}`;
|
|
9088
|
+
}
|
|
9089
|
+
/** The unified CSS fallback (no WebGL / reduced data): a still background or image filter per preset. */
|
|
9090
|
+
const GL_FALLBACKS = {
|
|
9091
|
+
gradient: 'linear-gradient(120deg,#6366f1,#ec4899 50%,#22d3ee)',
|
|
9092
|
+
plasma: 'conic-gradient(from 90deg,#f43f5e,#a855f7,#06b6d4,#f43f5e)',
|
|
9093
|
+
waves: 'linear-gradient(#0a0f26,#1e3a8a)',
|
|
9094
|
+
aurora: 'radial-gradient(120% 60% at 30% 40%,#10b98155,transparent),radial-gradient(100% 50% at 70% 50%,#8b5cf655,transparent),#05070f',
|
|
9095
|
+
snow: 'radial-gradient(2px 2px at 20% 30%,#fff,transparent),radial-gradient(2px 2px at 70% 60%,#fff,transparent),radial-gradient(1.5px 1.5px at 40% 80%,#fff,transparent),linear-gradient(#0d1428,#1f2a4d)',
|
|
9096
|
+
fireflies: 'radial-gradient(3px 3px at 25% 40%,#fde68a,transparent),radial-gradient(3px 3px at 65% 70%,#fde68a,transparent),#05090a',
|
|
9097
|
+
stars: 'radial-gradient(1px 1px at 10% 20%,#fff,transparent),radial-gradient(1px 1px at 80% 30%,#fff,transparent),radial-gradient(1.5px 1.5px at 50% 70%,#cfe0ff,transparent),#02020a',
|
|
9098
|
+
bokeh: 'radial-gradient(40px 40px at 30% 40%,#f472b633,transparent),radial-gradient(60px 60px at 70% 60%,#60a5fa33,transparent),#140820',
|
|
9099
|
+
rain: 'repeating-linear-gradient(100deg,#ffffff10 0 1px,transparent 1px 14px),linear-gradient(#0a0f1a,#1a2133)',
|
|
9100
|
+
// post-fx fallbacks are CSS filters on the <img>
|
|
9101
|
+
'post:duotone': 'grayscale(1) sepia(.6) hue-rotate(220deg) saturate(2)',
|
|
9102
|
+
'post:vignette': 'brightness(.95) contrast(1.05)',
|
|
9103
|
+
'post:crt': 'contrast(1.15) saturate(1.2)',
|
|
9104
|
+
'post:bloom': 'brightness(1.08) saturate(1.15)',
|
|
9105
|
+
};
|
|
9106
|
+
/** CSS fallback for a shader preset / post effect list. */
|
|
9107
|
+
function glFallbackCss(preset, post = false) {
|
|
9108
|
+
if (post)
|
|
9109
|
+
return preset.split(/\s+/).map((e) => GL_FALLBACKS[`post:${e}`]).filter(Boolean).join(' ');
|
|
9110
|
+
return GL_FALLBACKS[preset] || GL_FALLBACKS.gradient;
|
|
9111
|
+
}
|
|
9112
|
+
/**
|
|
9113
|
+
* Adaptive quality for GL loops: measures fps, steps the resolution scale
|
|
9114
|
+
* down (1 → 0.5 → 0.35) after two slow seconds and back up after five good
|
|
9115
|
+
* ones, and caps the frame rate in battery-saver mode. Pure — feed it times.
|
|
9116
|
+
*/
|
|
9117
|
+
function glGovernor(options = {}) {
|
|
9118
|
+
const { minFps = 40, saverFps = 30 } = options;
|
|
9119
|
+
const STEPS = [1, 0.5, 0.35];
|
|
9120
|
+
let step = 0;
|
|
9121
|
+
let frames = 0;
|
|
9122
|
+
let winStart = -1;
|
|
9123
|
+
let last = -Infinity;
|
|
9124
|
+
let slow = 0;
|
|
9125
|
+
let good = 0;
|
|
9126
|
+
let fps = 60;
|
|
9127
|
+
const g = {
|
|
9128
|
+
saver: false,
|
|
9129
|
+
get scale() {
|
|
9130
|
+
return Math.min(STEPS[step], g.saver ? 0.6 : 1);
|
|
9131
|
+
},
|
|
9132
|
+
get fps() {
|
|
9133
|
+
return fps;
|
|
9134
|
+
},
|
|
9135
|
+
tick(t) {
|
|
9136
|
+
if (winStart < 0)
|
|
9137
|
+
winStart = t;
|
|
9138
|
+
if (g.saver && t - last < 1000 / saverFps - 1)
|
|
9139
|
+
return false;
|
|
9140
|
+
last = t;
|
|
9141
|
+
frames++;
|
|
9142
|
+
if (t - winStart >= 1000) {
|
|
9143
|
+
fps = Math.round((frames * 1000) / (t - winStart));
|
|
9144
|
+
frames = 0;
|
|
9145
|
+
winStart = t;
|
|
9146
|
+
const before = g.scale;
|
|
9147
|
+
if (fps < minFps && !g.saver) {
|
|
9148
|
+
good = 0;
|
|
9149
|
+
if (++slow >= 2 && step < STEPS.length - 1)
|
|
9150
|
+
((step++), (slow = 0));
|
|
9151
|
+
}
|
|
9152
|
+
else {
|
|
9153
|
+
slow = 0;
|
|
9154
|
+
if (++good >= 5 && step > 0)
|
|
9155
|
+
((step--), (good = 0));
|
|
9156
|
+
}
|
|
9157
|
+
if (g.scale !== before)
|
|
9158
|
+
g.onScale?.(g.scale);
|
|
9159
|
+
}
|
|
9160
|
+
return true;
|
|
9161
|
+
},
|
|
9162
|
+
};
|
|
9163
|
+
return g;
|
|
9164
|
+
}
|
|
9165
|
+
/** Watch the Battery Status API (where available) and Save-Data; calls `cb(true)` in saver conditions. Returns a stop function. */
|
|
9166
|
+
function watchPowerSaver(cb) {
|
|
9167
|
+
let stopped = false;
|
|
9168
|
+
const nav = (typeof navigator !== 'undefined' ? navigator : {});
|
|
9169
|
+
const saveData = !!nav.connection?.saveData;
|
|
9170
|
+
if (saveData)
|
|
9171
|
+
cb(true);
|
|
9172
|
+
if (typeof nav.getBattery !== 'function')
|
|
9173
|
+
return () => undefined;
|
|
9174
|
+
let battery = null;
|
|
9175
|
+
const update = () => !stopped && cb(saveData || (!!battery && !battery.charging && battery.level <= 0.2));
|
|
9176
|
+
nav.getBattery().then((b) => {
|
|
9177
|
+
battery = b;
|
|
9178
|
+
update();
|
|
9179
|
+
b.addEventListener?.('levelchange', update);
|
|
9180
|
+
b.addEventListener?.('chargingchange', update);
|
|
9181
|
+
}, () => undefined);
|
|
9182
|
+
return () => {
|
|
9183
|
+
stopped = true;
|
|
9184
|
+
battery?.removeEventListener?.('levelchange', update);
|
|
9185
|
+
battery?.removeEventListener?.('chargingchange', update);
|
|
9186
|
+
};
|
|
9187
|
+
}
|
|
9188
|
+
|
|
9054
9189
|
var css$2 = "";
|
|
9055
9190
|
|
|
9056
9191
|
function make(kind) {
|
|
@@ -9064,15 +9199,23 @@ function make(kind) {
|
|
|
9064
9199
|
this._hover = 0;
|
|
9065
9200
|
this._hoverTo = 0;
|
|
9066
9201
|
this._ripples = [];
|
|
9202
|
+
this._scale = 1;
|
|
9067
9203
|
}
|
|
9068
9204
|
static get observedAttributes() {
|
|
9069
|
-
return kind === 'shader' ? ['preset', 'speed'] : ['src'];
|
|
9205
|
+
return kind === 'shader' ? ['preset', 'speed', 'quality'] : kind === 'post' ? ['effects', 'intensity', 'quality'] : ['src'];
|
|
9070
9206
|
}
|
|
9071
9207
|
get active() {
|
|
9072
9208
|
return !!this._q;
|
|
9073
9209
|
}
|
|
9074
9210
|
fallback(reason) {
|
|
9075
9211
|
this.setAttribute('data-fallback', reason);
|
|
9212
|
+
// 4.8 unified fallback: a still CSS rendering of the preset / effects
|
|
9213
|
+
if (reason !== 'off') {
|
|
9214
|
+
if (kind === 'shader')
|
|
9215
|
+
this.style.setProperty('--usa-gl-fallback', glFallbackCss(this.str('preset', 'gradient')));
|
|
9216
|
+
if (kind === 'post')
|
|
9217
|
+
this.style.setProperty('--usa-gl-filter', glFallbackCss(this.str('effects', 'vignette grain'), true) || 'none');
|
|
9218
|
+
}
|
|
9076
9219
|
this._c?.remove();
|
|
9077
9220
|
this._c = null;
|
|
9078
9221
|
this._q?.dispose();
|
|
@@ -9090,12 +9233,13 @@ function make(kind) {
|
|
|
9090
9233
|
mouse: this._mouse,
|
|
9091
9234
|
hover: this._hover,
|
|
9092
9235
|
ripples: this._ripples.flatMap((r) => [r.x, r.y, (t - r.t) / 1000, this.num('strength', 1)]),
|
|
9236
|
+
extra: kind === 'post' ? { u_intensity: clamp(this.num('intensity', 0.6), 0, 1) } : undefined,
|
|
9093
9237
|
});
|
|
9094
9238
|
}
|
|
9095
9239
|
mount() {
|
|
9096
9240
|
this.removeAttribute('data-fallback');
|
|
9097
9241
|
const custom = this.querySelector('script[type="x-shader/x-fragment"]');
|
|
9098
|
-
const frag = kind === 'shader' ? custom?.textContent || this.str('preset', 'gradient') : kind;
|
|
9242
|
+
const frag = kind === 'shader' ? custom?.textContent || this.str('preset', 'gradient') : kind === 'post' ? postFxShader(this.str('effects', 'vignette grain').split(/[\s,]+/)) : kind;
|
|
9099
9243
|
const img = kind === 'shader' ? null : this.querySelector('img');
|
|
9100
9244
|
if (kind !== 'shader' && !img)
|
|
9101
9245
|
return this.fallback('no-image');
|
|
@@ -9120,7 +9264,7 @@ function make(kind) {
|
|
|
9120
9264
|
}
|
|
9121
9265
|
};
|
|
9122
9266
|
const draw = () => {
|
|
9123
|
-
q.resize();
|
|
9267
|
+
q.resize(this._scale);
|
|
9124
9268
|
this.frame();
|
|
9125
9269
|
};
|
|
9126
9270
|
if (img && !(img.complete && img.naturalWidth)) {
|
|
@@ -9134,7 +9278,7 @@ function make(kind) {
|
|
|
9134
9278
|
this.setAttribute('data-active', '');
|
|
9135
9279
|
this.onCleanup(() => this.removeAttribute('data-active'));
|
|
9136
9280
|
draw();
|
|
9137
|
-
if (kind
|
|
9281
|
+
if (kind === 'distort' || kind === 'liquid') {
|
|
9138
9282
|
const pos = (e) => {
|
|
9139
9283
|
const r = this.getBoundingClientRect();
|
|
9140
9284
|
this._mouse = [clamp((e.clientX - r.left) / (r.width || 1), 0, 1), clamp(1 - (e.clientY - r.top) / (r.height || 1), 0, 1)];
|
|
@@ -9151,7 +9295,7 @@ function make(kind) {
|
|
|
9151
9295
|
// 4.0.1: also follow the element's own size (grid reflow, card expand…)
|
|
9152
9296
|
if (typeof ResizeObserver !== 'undefined') {
|
|
9153
9297
|
const ro = new ResizeObserver(() => {
|
|
9154
|
-
q.resize();
|
|
9298
|
+
q.resize(this._scale);
|
|
9155
9299
|
if (!this._id)
|
|
9156
9300
|
this.frame();
|
|
9157
9301
|
});
|
|
@@ -9160,9 +9304,20 @@ function make(kind) {
|
|
|
9160
9304
|
}
|
|
9161
9305
|
if (this.reduced)
|
|
9162
9306
|
return; // one static frame, no loop
|
|
9307
|
+
// 4.8 adaptive quality: fps-driven resolution steps + battery saver frame cap
|
|
9308
|
+
const gov = glGovernor();
|
|
9309
|
+
const auto = this.str('quality', 'auto') !== 'high';
|
|
9310
|
+
gov.onScale = (sc) => {
|
|
9311
|
+
this._scale = sc;
|
|
9312
|
+
this.setAttribute('data-quality', String(sc));
|
|
9313
|
+
q.resize(sc);
|
|
9314
|
+
};
|
|
9315
|
+
if (auto)
|
|
9316
|
+
this.onCleanup(watchPowerSaver((saver) => ((gov.saver = saver), gov.onScale?.(gov.scale))));
|
|
9163
9317
|
let visible = false;
|
|
9164
9318
|
const loop = () => {
|
|
9165
|
-
|
|
9319
|
+
if (!auto || gov.tick(now()))
|
|
9320
|
+
this.frame();
|
|
9166
9321
|
this._id = raf(loop);
|
|
9167
9322
|
};
|
|
9168
9323
|
const sync = () => {
|
|
@@ -9173,7 +9328,7 @@ function make(kind) {
|
|
|
9173
9328
|
};
|
|
9174
9329
|
this.inView((v) => ((visible = v), sync()));
|
|
9175
9330
|
this.listen(document, 'visibilitychange', sync);
|
|
9176
|
-
this.listen(window, 'resize', () => q.resize(), { passive: true });
|
|
9331
|
+
this.listen(window, 'resize', () => q.resize(this._scale), { passive: true });
|
|
9177
9332
|
this.onCleanup(() => caf(this._id));
|
|
9178
9333
|
}
|
|
9179
9334
|
};
|
|
@@ -9201,6 +9356,16 @@ function defineDistort(tag = 'usa-distort') {
|
|
|
9201
9356
|
function defineLiquid(tag = 'usa-liquid') {
|
|
9202
9357
|
return defineElement(tag, make('liquid'), { id: 'webgl', text: css$2 });
|
|
9203
9358
|
}
|
|
9359
|
+
/**
|
|
9360
|
+
* `<usa-post-fx effects="vignette grain crt" intensity="0.6">` — GPU
|
|
9361
|
+
* post-processing over the `<img>` inside (4.8): `vignette` · `grain` ·
|
|
9362
|
+
* `chromatic` · `scanlines` · `crt` · `bloom` · `pixelate` · `duotone` ·
|
|
9363
|
+
* `glitch`, chained in order. `quality="high"` disables adaptive quality.
|
|
9364
|
+
* Fallback: the image with an approximate CSS filter.
|
|
9365
|
+
*/
|
|
9366
|
+
function definePostFx(tag = 'usa-post-fx') {
|
|
9367
|
+
return defineElement(tag, make('post'), { id: 'webgl', text: css$2 });
|
|
9368
|
+
}
|
|
9204
9369
|
|
|
9205
9370
|
/**
|
|
9206
9371
|
* use-scroll-animate/components/webgl — lightweight canvas / WebGL (v3.4).
|
|
@@ -9213,6 +9378,7 @@ function defineWebglComponents() {
|
|
|
9213
9378
|
defineShader();
|
|
9214
9379
|
defineDistort();
|
|
9215
9380
|
defineLiquid();
|
|
9381
|
+
definePostFx();
|
|
9216
9382
|
}
|
|
9217
9383
|
|
|
9218
9384
|
var css$1 = "";
|
|
@@ -10094,6 +10260,149 @@ function auditMotionA11y(root) {
|
|
|
10094
10260
|
/** Every `<usa-*>` tag, for sweeping audits. */
|
|
10095
10261
|
const ALL_TAGS = Object.values(COMPONENT_CATEGORIES).flat();
|
|
10096
10262
|
|
|
10263
|
+
/**
|
|
10264
|
+
* use-scroll-animate/components/bridge — native shell bridges (4.7).
|
|
10265
|
+
*
|
|
10266
|
+
* Keeps the web UI in sync with the host app's system settings when it runs
|
|
10267
|
+
* inside **WinUI 3 / WPF (WebView2)**, **.NET MAUI** (WebView / HybridWebView)
|
|
10268
|
+
* or **Flutter** (webview_flutter / flutter_inappwebview): the native side
|
|
10269
|
+
* sends "reduce motion", light / dark / high-contrast theme and accent color;
|
|
10270
|
+
* the page applies them to every `<usa-*>` component.
|
|
10271
|
+
*
|
|
10272
|
+
* Protocol (JSON, both directions):
|
|
10273
|
+
* - native → web `{ "type": "usa:settings", "reducedMotion": true, "theme": "dark", "accent": "#0078d4", "sensitivity": "gentle" }`
|
|
10274
|
+
* - web → native `{ "type": "usa:ready", "version": 1 }` on connect, `{ "type": "usa:request-settings" }`
|
|
10275
|
+
*
|
|
10276
|
+
* Hosts that can only run script call `window.usaNative.apply({...})`.
|
|
10277
|
+
* Samples: examples/native/{winui3,maui,flutter}.
|
|
10278
|
+
*/
|
|
10279
|
+
const BRIDGE_PROTOCOL_VERSION = 1;
|
|
10280
|
+
const win = () => (typeof window === 'undefined' ? null : window);
|
|
10281
|
+
/** Which native shell (if any) hosts this page. */
|
|
10282
|
+
function detectNativeHost(channel = 'UsaBridge') {
|
|
10283
|
+
const w = win();
|
|
10284
|
+
if (!w)
|
|
10285
|
+
return 'browser';
|
|
10286
|
+
if (w.chrome?.webview?.postMessage)
|
|
10287
|
+
return 'webview2';
|
|
10288
|
+
if (w.HybridWebView?.SendRawMessage || w.HybridWebView?.SendRawMessageToDotNet || /\bMAUI\b/i.test(w.navigator?.userAgent || ''))
|
|
10289
|
+
return 'maui';
|
|
10290
|
+
if (w.flutter_inappwebview?.callHandler || w[channel]?.postMessage)
|
|
10291
|
+
return 'flutter';
|
|
10292
|
+
if (w.__TAURI__ || w.__TAURI_INTERNALS__)
|
|
10293
|
+
return 'tauri';
|
|
10294
|
+
if (w.process?.versions?.electron || /Electron\//.test(w.navigator?.userAgent || ''))
|
|
10295
|
+
return 'electron';
|
|
10296
|
+
return 'browser';
|
|
10297
|
+
}
|
|
10298
|
+
/** Send a JSON message to the native host (no-op in a plain browser). Returns whether it was sent. */
|
|
10299
|
+
function postToNative(message, channel = 'UsaBridge') {
|
|
10300
|
+
const w = win();
|
|
10301
|
+
if (!w)
|
|
10302
|
+
return false;
|
|
10303
|
+
const json = JSON.stringify(message);
|
|
10304
|
+
try {
|
|
10305
|
+
if (w.chrome?.webview?.postMessage)
|
|
10306
|
+
return w.chrome.webview.postMessage(message), true;
|
|
10307
|
+
if (w.HybridWebView?.SendRawMessage)
|
|
10308
|
+
return w.HybridWebView.SendRawMessage(json), true;
|
|
10309
|
+
if (w.HybridWebView?.SendRawMessageToDotNet)
|
|
10310
|
+
return w.HybridWebView.SendRawMessageToDotNet(json), true;
|
|
10311
|
+
if (w.flutter_inappwebview?.callHandler)
|
|
10312
|
+
return w.flutter_inappwebview.callHandler(channel, json), true;
|
|
10313
|
+
if (w[channel]?.postMessage)
|
|
10314
|
+
return w[channel].postMessage(json), true;
|
|
10315
|
+
}
|
|
10316
|
+
catch {
|
|
10317
|
+
/* host went away */
|
|
10318
|
+
}
|
|
10319
|
+
return false;
|
|
10320
|
+
}
|
|
10321
|
+
const THEMES = ['light', 'dark', 'high-contrast'];
|
|
10322
|
+
const COLOR = /^(#[0-9a-f]{3,8}|rgba?\([\d\s.,%]+\)|hsla?\([\d\s.,%deg]+\))$/i;
|
|
10323
|
+
/** Validate an incoming message (string or object); unknown fields are dropped. */
|
|
10324
|
+
function parseNativeSettings(data) {
|
|
10325
|
+
let d = data;
|
|
10326
|
+
if (typeof d === 'string') {
|
|
10327
|
+
try {
|
|
10328
|
+
d = JSON.parse(d);
|
|
10329
|
+
}
|
|
10330
|
+
catch {
|
|
10331
|
+
return null;
|
|
10332
|
+
}
|
|
10333
|
+
}
|
|
10334
|
+
if (!d || typeof d !== 'object' || d.type !== 'usa:settings')
|
|
10335
|
+
return null;
|
|
10336
|
+
const out = {};
|
|
10337
|
+
if (typeof d.reducedMotion === 'boolean')
|
|
10338
|
+
out.reducedMotion = d.reducedMotion;
|
|
10339
|
+
if (THEMES.includes(d.theme))
|
|
10340
|
+
out.theme = d.theme;
|
|
10341
|
+
if (typeof d.accent === 'string' && COLOR.test(d.accent.trim()))
|
|
10342
|
+
out.accent = d.accent.trim();
|
|
10343
|
+
if (MOTION_SENSITIVITY_LEVELS.includes(d.sensitivity))
|
|
10344
|
+
out.sensitivity = d.sensitivity;
|
|
10345
|
+
return out;
|
|
10346
|
+
}
|
|
10347
|
+
/**
|
|
10348
|
+
* Apply native settings: reduce motion → `configureComponents({ reducedMotion: 'reduce' })`
|
|
10349
|
+
* (`false` → follow the media query again); theme → `data-theme`, `data-usa-contrast`
|
|
10350
|
+
* and `color-scheme`; accent → `--usa-accent`; sensitivity → `motionSensitivity`.
|
|
10351
|
+
*/
|
|
10352
|
+
function applyNativeSettings(s, root) {
|
|
10353
|
+
if (s.reducedMotion !== undefined)
|
|
10354
|
+
configureComponents({ reducedMotion: s.reducedMotion ? 'reduce' : 'user' });
|
|
10355
|
+
if (s.sensitivity)
|
|
10356
|
+
configureComponents({ motionSensitivity: s.sensitivity });
|
|
10357
|
+
const el = root || (typeof document !== 'undefined' ? document.documentElement : null);
|
|
10358
|
+
if (!el)
|
|
10359
|
+
return;
|
|
10360
|
+
if (s.theme) {
|
|
10361
|
+
el.setAttribute('data-theme', s.theme === 'high-contrast' ? 'dark' : s.theme);
|
|
10362
|
+
el.toggleAttribute('data-usa-contrast', s.theme === 'high-contrast');
|
|
10363
|
+
el.style.colorScheme = s.theme === 'light' ? 'light' : 'dark';
|
|
10364
|
+
}
|
|
10365
|
+
if (s.accent)
|
|
10366
|
+
el.style.setProperty('--usa-accent', s.accent);
|
|
10367
|
+
if (typeof document !== 'undefined')
|
|
10368
|
+
document.dispatchEvent(new CustomEvent('usa:native-settings', { detail: s }));
|
|
10369
|
+
}
|
|
10370
|
+
/**
|
|
10371
|
+
* Connect to the native shell: listens for `usa:settings` messages
|
|
10372
|
+
* (WebView2 `chrome.webview` messages, `window.postMessage`, or
|
|
10373
|
+
* `window.usaNative.apply()`), applies them, then announces `usa:ready` and
|
|
10374
|
+
* asks for the current settings. Returns `{ host, disconnect }`.
|
|
10375
|
+
*/
|
|
10376
|
+
function connectNativeShell(options = {}) {
|
|
10377
|
+
const w = win();
|
|
10378
|
+
const channel = options.channel || 'UsaBridge';
|
|
10379
|
+
const host = detectNativeHost(channel);
|
|
10380
|
+
if (!w)
|
|
10381
|
+
return { host, disconnect: () => undefined };
|
|
10382
|
+
const handle = (data) => {
|
|
10383
|
+
const s = parseNativeSettings(data);
|
|
10384
|
+
if (!s)
|
|
10385
|
+
return;
|
|
10386
|
+
applyNativeSettings(s, options.root);
|
|
10387
|
+
options.onSettings?.(s, host);
|
|
10388
|
+
};
|
|
10389
|
+
const onMessage = (e) => handle(e.data);
|
|
10390
|
+
w.chrome?.webview?.addEventListener?.('message', onMessage);
|
|
10391
|
+
w.addEventListener?.('message', onMessage);
|
|
10392
|
+
const prev = w.usaNative;
|
|
10393
|
+
w.usaNative = { apply: (s) => handle({ ...s, type: 'usa:settings' }), version: BRIDGE_PROTOCOL_VERSION, host };
|
|
10394
|
+
postToNative({ type: 'usa:ready', version: BRIDGE_PROTOCOL_VERSION }, channel);
|
|
10395
|
+
postToNative({ type: 'usa:request-settings' }, channel);
|
|
10396
|
+
return {
|
|
10397
|
+
host,
|
|
10398
|
+
disconnect: () => {
|
|
10399
|
+
w.chrome?.webview?.removeEventListener?.('message', onMessage);
|
|
10400
|
+
w.removeEventListener?.('message', onMessage);
|
|
10401
|
+
w.usaNative = prev;
|
|
10402
|
+
},
|
|
10403
|
+
};
|
|
10404
|
+
}
|
|
10405
|
+
|
|
10097
10406
|
/**
|
|
10098
10407
|
* use-scroll-animate/components
|
|
10099
10408
|
*
|
|
@@ -10163,11 +10472,13 @@ onDemandStyles(STYLE_BASE);
|
|
|
10163
10472
|
exports.ALL_TAGS = ALL_TAGS;
|
|
10164
10473
|
exports.AMBIENT_EFFECTS = AMBIENT_EFFECTS;
|
|
10165
10474
|
exports.ANIM_ICONS = ANIM_ICONS;
|
|
10475
|
+
exports.BRIDGE_PROTOCOL_VERSION = BRIDGE_PROTOCOL_VERSION;
|
|
10166
10476
|
exports.BUTTON_DEFORMS = BUTTON_DEFORMS;
|
|
10167
10477
|
exports.CARD_EFFECTS = CARD_EFFECTS;
|
|
10168
10478
|
exports.CLICK_EFFECTS = CLICK_EFFECTS;
|
|
10169
10479
|
exports.COMPONENT_CATEGORIES = COMPONENT_CATEGORIES;
|
|
10170
10480
|
exports.CURSOR_MODES = CURSOR_MODES;
|
|
10481
|
+
exports.GL_FALLBACKS = GL_FALLBACKS;
|
|
10171
10482
|
exports.JOINING_SCRIPT = JOINING_SCRIPT;
|
|
10172
10483
|
exports.LIVE_REGION_IDS = LIVE_REGION_IDS;
|
|
10173
10484
|
exports.MASK_SHAPES = MASK_SHAPES;
|
|
@@ -10179,6 +10490,8 @@ exports.MOTION_TOKENS = MOTION_TOKENS;
|
|
|
10179
10490
|
exports.PACKS = PACKS;
|
|
10180
10491
|
exports.PACK_PRIMITIVES = PACK_PRIMITIVES;
|
|
10181
10492
|
exports.PAGE_EFFECTS = PAGE_EFFECTS;
|
|
10493
|
+
exports.PARTICLE_PRESETS = PARTICLE_PRESETS;
|
|
10494
|
+
exports.POST_EFFECTS = POST_EFFECTS;
|
|
10182
10495
|
exports.REVEAL_EFFECTS = REVEAL_EFFECTS;
|
|
10183
10496
|
exports.SENSITIVITY_CSS = SENSITIVITY_CSS;
|
|
10184
10497
|
exports.SHADERS = SHADERS;
|
|
@@ -10195,6 +10508,7 @@ exports.adoptVariants = adoptVariants;
|
|
|
10195
10508
|
exports.animationBudget = animationBudget;
|
|
10196
10509
|
exports.announce = announce;
|
|
10197
10510
|
exports.applyMotionTokens = applyMotionTokens;
|
|
10511
|
+
exports.applyNativeSettings = applyNativeSettings;
|
|
10198
10512
|
exports.applyPack = applyPack;
|
|
10199
10513
|
exports.auditMotionA11y = auditMotionA11y;
|
|
10200
10514
|
exports.autoAnimate = autoAnimate;
|
|
@@ -10203,6 +10517,7 @@ exports.burst = burst;
|
|
|
10203
10517
|
exports.categoryOf = categoryOf;
|
|
10204
10518
|
exports.confetti = confetti;
|
|
10205
10519
|
exports.configureComponents = configureComponents;
|
|
10520
|
+
exports.connectNativeShell = connectNativeShell;
|
|
10206
10521
|
exports.countUp = countUp;
|
|
10207
10522
|
exports.createSpring = createSpring;
|
|
10208
10523
|
exports.defineAccordion = defineAccordion;
|
|
@@ -10271,6 +10586,7 @@ exports.defineParticles = defineParticles;
|
|
|
10271
10586
|
exports.definePhysicsComponents = definePhysicsComponents;
|
|
10272
10587
|
exports.definePinchZoom = definePinchZoom;
|
|
10273
10588
|
exports.definePopover = definePopover;
|
|
10589
|
+
exports.definePostFx = definePostFx;
|
|
10274
10590
|
exports.definePress = definePress;
|
|
10275
10591
|
exports.defineProgress = defineProgress;
|
|
10276
10592
|
exports.definePullRefresh = definePullRefresh;
|
|
@@ -10311,6 +10627,7 @@ exports.defineViewSwitch = defineViewSwitch;
|
|
|
10311
10627
|
exports.defineWaterRipple = defineWaterRipple;
|
|
10312
10628
|
exports.defineWaveText = defineWaveText;
|
|
10313
10629
|
exports.defineWebglComponents = defineWebglComponents;
|
|
10630
|
+
exports.detectNativeHost = detectNativeHost;
|
|
10314
10631
|
exports.deviceTilt = deviceTilt;
|
|
10315
10632
|
exports.drawLines = drawLines;
|
|
10316
10633
|
exports.easeOutExpo = easeOutExpo;
|
|
@@ -10324,6 +10641,8 @@ exports.gesture = gesture;
|
|
|
10324
10641
|
exports.getMotionIntensity = getMotionIntensity;
|
|
10325
10642
|
exports.getMotionSensitivity = getMotionSensitivity;
|
|
10326
10643
|
exports.getMotionTokens = getMotionTokens;
|
|
10644
|
+
exports.glFallbackCss = glFallbackCss;
|
|
10645
|
+
exports.glGovernor = glGovernor;
|
|
10327
10646
|
exports.glQuad = glQuad;
|
|
10328
10647
|
exports.graphemes = graphemes;
|
|
10329
10648
|
exports.haptic = haptic;
|
|
@@ -10350,8 +10669,11 @@ exports.orientationToTilt = orientationToTilt;
|
|
|
10350
10669
|
exports.pageTransition = pageTransition;
|
|
10351
10670
|
exports.parseDuration = parseDuration;
|
|
10352
10671
|
exports.parseEasing = parseEasing;
|
|
10672
|
+
exports.parseNativeSettings = parseNativeSettings;
|
|
10353
10673
|
exports.pathsCompatible = pathsCompatible;
|
|
10354
10674
|
exports.pinchScale = pinchScale;
|
|
10675
|
+
exports.postFxShader = postFxShader;
|
|
10676
|
+
exports.postToNative = postToNative;
|
|
10355
10677
|
exports.prefersReducedMotion = prefersReducedMotion;
|
|
10356
10678
|
exports.projectInertia = projectInertia;
|
|
10357
10679
|
exports.readScrollProgress = readScrollProgress;
|
|
@@ -10395,4 +10717,5 @@ exports.themeTransition = themeTransition;
|
|
|
10395
10717
|
exports.timeline = timeline;
|
|
10396
10718
|
exports.toast = toast;
|
|
10397
10719
|
exports.viewTransition = viewTransition;
|
|
10720
|
+
exports.watchPowerSaver = watchPowerSaver;
|
|
10398
10721
|
//# sourceMappingURL=lite.cjs.map
|