mirror of
https://github.com/narrrl/holy-flavor-rater.git
synced 2026-11-03 16:41:27 +01:00
ui redesign
This commit is contained in:
1 parent
d0a027a2a1
commit
67da3061a6
49 files changed
+1496
-458
No files matched your search
@@ -0,0 +1,143 @@
|
||||
/**
|
||||
* The SVG filter definitions behind the liquid-glass look, mounted exactly once
|
||||
* (from `AppProviders`) so `url(#…)` resolves anywhere in the app.
|
||||
*
|
||||
* Why these are static: refraction reads as *liquid* because the backdrop moves
|
||||
* behind a fixed displacement map — not because the map itself animates.
|
||||
* Animating `baseFrequency` would re-rasterise the turbulence every frame; a
|
||||
* static seed over the drifting aurora/canvas backdrop costs one raster pass
|
||||
* and looks the same.
|
||||
*
|
||||
* These are consumed through `theme.tokens.glass.rimFilter` /
|
||||
* `rimFilterChroma`, and only ever on a thin masked ring (see `Glass.tsx`) —
|
||||
* never over a whole pane, which would be Chrome-only and far too expensive on
|
||||
* a grid of cards.
|
||||
*/
|
||||
|
||||
/** Turbulence shared by both rim filters: soft, lens-like lobes rather than sand. */
|
||||
const Turbulence = () => (
|
||||
<>
|
||||
<feTurbulence
|
||||
type="fractalNoise"
|
||||
baseFrequency="0.008 0.012"
|
||||
numOctaves={2}
|
||||
seed={7}
|
||||
result="noise"
|
||||
/>
|
||||
<feGaussianBlur in="noise" stdDeviation="1.2" result="soft" />
|
||||
</>
|
||||
);
|
||||
|
||||
/** Isolates one channel of the source so it can be displaced independently. */
|
||||
const channelMatrix = (channel: 'r' | 'g' | 'b') =>
|
||||
({
|
||||
r: '1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0',
|
||||
g: '0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0',
|
||||
b: '0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0',
|
||||
})[channel];
|
||||
|
||||
export const GlassDefs = () => (
|
||||
<svg
|
||||
width="0"
|
||||
height="0"
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
style={{ position: 'absolute', width: 0, height: 0, overflow: 'hidden' }}
|
||||
>
|
||||
<defs>
|
||||
{/* Monochrome refraction — the workhorse, used on the `panel` tier. */}
|
||||
<filter
|
||||
id="hfr-rim"
|
||||
x="-20%"
|
||||
y="-20%"
|
||||
width="140%"
|
||||
height="140%"
|
||||
colorInterpolationFilters="sRGB"
|
||||
>
|
||||
<Turbulence />
|
||||
<feDisplacementMap
|
||||
in="SourceGraphic"
|
||||
in2="soft"
|
||||
scale={11}
|
||||
xChannelSelector="R"
|
||||
yChannelSelector="G"
|
||||
result="disp"
|
||||
/>
|
||||
{/* Displacement near an edge pulls in samples from outside the backdrop
|
||||
image, which come back as transparent black and paint a dark fringe
|
||||
along the rim. Compositing the displaced result *over* the original
|
||||
backdrop fills those gaps with the undisplaced pixels instead. */}
|
||||
<feComposite in="disp" in2="SourceGraphic" operator="over" />
|
||||
</filter>
|
||||
|
||||
{/* Chromatic refraction — R/G/B displaced by different amounts, then
|
||||
screened back together, giving the prismatic edge real glass has.
|
||||
Three displacement passes, so `chrome` tier only. */}
|
||||
<filter
|
||||
id="hfr-rim-chroma"
|
||||
x="-20%"
|
||||
y="-20%"
|
||||
width="140%"
|
||||
height="140%"
|
||||
colorInterpolationFilters="sRGB"
|
||||
>
|
||||
<Turbulence />
|
||||
<feColorMatrix
|
||||
in="SourceGraphic"
|
||||
type="matrix"
|
||||
values={channelMatrix('r')}
|
||||
result="rOnly"
|
||||
/>
|
||||
<feDisplacementMap
|
||||
in="rOnly"
|
||||
in2="soft"
|
||||
scale={14}
|
||||
xChannelSelector="R"
|
||||
yChannelSelector="G"
|
||||
result="rDisp"
|
||||
/>
|
||||
<feColorMatrix
|
||||
in="SourceGraphic"
|
||||
type="matrix"
|
||||
values={channelMatrix('g')}
|
||||
result="gOnly"
|
||||
/>
|
||||
<feDisplacementMap
|
||||
in="gOnly"
|
||||
in2="soft"
|
||||
scale={11}
|
||||
xChannelSelector="R"
|
||||
yChannelSelector="G"
|
||||
result="gDisp"
|
||||
/>
|
||||
<feColorMatrix
|
||||
in="SourceGraphic"
|
||||
type="matrix"
|
||||
values={channelMatrix('b')}
|
||||
result="bOnly"
|
||||
/>
|
||||
<feDisplacementMap
|
||||
in="bOnly"
|
||||
in2="soft"
|
||||
scale={8}
|
||||
xChannelSelector="R"
|
||||
yChannelSelector="G"
|
||||
result="bDisp"
|
||||
/>
|
||||
<feBlend in="rDisp" in2="gDisp" mode="screen" result="rg" />
|
||||
<feBlend in="rg" in2="bDisp" mode="screen" result="chroma" />
|
||||
{/* Same edge-fringe patch as #hfr-rim. */}
|
||||
<feComposite in="chroma" in2="SourceGraphic" operator="over" />
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
);
|
||||
|
||||
/**
|
||||
* Fine grain, as a self-contained data URI rather than a `filter: url()` chain —
|
||||
* it tiles as a plain background-image, so it costs nothing per frame.
|
||||
* Layered at low opacity over the aurora it kills gradient banding and gives
|
||||
* the rim refraction something fine-grained to bend.
|
||||
*/
|
||||
export const GRAIN_DATA_URI =
|
||||
"url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E\")";
|
||||
Reference in new issue
Block a user