@@ -2,6 +2,9 @@ import { useId } from "react";
22
33import type { SurfaceFnDef } from "../src/helpers/surface-equations" ;
44import { convex } from "../src/helpers/surface-equations" ;
5+ import { ExampleArticle } from "./example-article" ;
6+
7+ export type BackgroundType = "article" | "checkerboard" ;
58
69export type SharedFilterProps = {
710 blur : number ;
@@ -12,6 +15,7 @@ export type SharedFilterProps = {
1215 specularOpacity : number ;
1316 specularAngle : number ;
1417 bezelHeightFn : SurfaceFnDef ;
18+ background : BackgroundType ;
1519} ;
1620
1721export const defaultFilterArgs : SharedFilterProps = {
@@ -23,6 +27,7 @@ export const defaultFilterArgs: SharedFilterProps = {
2327 specularOpacity : 0.9 ,
2428 specularAngle : 2 ,
2529 bezelHeightFn : convex ,
30+ background : "article" ,
2631} ;
2732
2833export const filterArgTypes = {
@@ -44,48 +49,88 @@ export const filterArgTypes = {
4449 control : { type : "range" as const , min : 0 , max : 6.28 , step : 0.01 } ,
4550 } ,
4651 bezelHeightFn : { table : { disable : true } } ,
52+ background : {
53+ control : { type : "inline-radio" as const } ,
54+ options : [ "article" , "checkerboard" ] ,
55+ } ,
4756} ;
4857
4958/**
50- * Wrapper that renders a filter + a div with that filter applied, over a colorful background.
59+ * Glass pane that applies an SVG backdrop-filter.
60+ * `children` should render the <Filter> / <FilterOBB> SVG element.
5161 */
52- export const FilterShowcase : React . FC < {
53- children : ( id : string ) => React . ReactNode ;
54- } > = ( { children } ) => {
55- const filterId = useId ( ) ;
56-
57- return (
62+ const GlassPane : React . FC < {
63+ filterId : string ;
64+ children : React . ReactNode ;
65+ } > = ( { filterId, children } ) => (
66+ < >
67+ { children }
5868 < div
5969 style = { {
60- position : "relative" ,
61- width : "100%" ,
62- height : "100vh" ,
63- background :
64- "repeating-conic-gradient(#e66465 0% 25%, #9198e5 0% 50%) 0 / 40px 40px ",
70+ width : 400 ,
71+ height : 300 ,
72+ backdropFilter : `url(# ${ filterId } )` ,
73+ borderRadius : 20 ,
74+ backgroundColor : "rgba(255, 255, 255, 0.15) ",
6575 display : "flex" ,
6676 alignItems : "center" ,
6777 justifyContent : "center" ,
78+ fontSize : 18 ,
79+ fontWeight : 600 ,
80+ color : "#333" ,
6881 } }
6982 >
70- { children ( filterId ) }
83+ Refractive Glass
84+ </ div >
85+ </ >
86+ ) ;
87+
88+ /**
89+ * Wrapper that renders a filter + a div with that filter applied, over a selectable background.
90+ */
91+ export const FilterShowcase : React . FC < {
92+ background ?: BackgroundType ;
93+ children : ( id : string ) => React . ReactNode ;
94+ } > = ( { background = "article" , children } ) => {
95+ const filterId = useId ( ) ;
96+
97+ const glass = < GlassPane filterId = { filterId } > { children ( filterId ) } </ GlassPane > ;
7198
99+ if ( background === "checkerboard" ) {
100+ return (
72101 < div
73102 style = { {
74- width : 400 ,
75- height : 300 ,
76- backdropFilter : `url(# ${ filterId } )` ,
77- borderRadius : 20 ,
78- backgroundColor : "rgba(255, 255, 255, 0.15) ",
103+ position : "relative" ,
104+ width : "100%" ,
105+ height : "100vh" ,
106+ background :
107+ "repeating-conic-gradient(#e66465 0% 25%, #9198e5 0% 50%) 0 / 40px 40px ",
79108 display : "flex" ,
80109 alignItems : "center" ,
81110 justifyContent : "center" ,
82- fontSize : 18 ,
83- fontWeight : 600 ,
84- color : "#333" ,
85111 } }
86112 >
87- Refractive Glass
113+ { glass }
114+ </ div >
115+ ) ;
116+ }
117+
118+ return (
119+ < div style = { { position : "relative" } } >
120+ < div
121+ style = { {
122+ position : "sticky" ,
123+ top : "50%" ,
124+ transform : "translateY(-50%)" ,
125+ display : "flex" ,
126+ justifyContent : "center" ,
127+ zIndex : 1 ,
128+ pointerEvents : "none" ,
129+ } }
130+ >
131+ < div style = { { pointerEvents : "auto" } } > { glass } </ div >
88132 </ div >
133+ < ExampleArticle />
89134 </ div >
90135 ) ;
91136} ;
0 commit comments