Refract and light water
Compare an original tiled subject, displacement, reflected light, and their combined result.
APIs demonstrated
Section titled “APIs demonstrated”- displacement from
@pibbl/core/filters - reflectedLight from
@pibbl/core/filters - PibblDisplacementFilterOptions from
@pibbl/core/filters - PibblReflectedLightFilterOptions from
@pibbl/core/filters - PibblReflectedLightSource from
@pibbl/core/filters
Complete example
Section titled “Complete example”Plain source. Run as a browser module after the document body exists. TSX uses jsx: "react-jsx" and jsxImportSource: "@pibbl/core".
import { pibbl, Group, Rectangle, Circle, useTexture } from "@pibbl/core";import { displacement, reflectedLight, type PibblDisplacementFilterOptions, type PibblReflectedLightFilterOptions, type PibblReflectedLightSource,} from "@pibbl/core/filters";import { waterWaves } from "@pibbl/core/textures";
function Scene({ mode,}: { mode: "original" | "displacement" | "light" | "both";}) { const waves = useTexture(waterWaves({ seed: 7, speed: 3 })); const map = waves.paint({ mode: "stretch" }); const region = { x: 0, y: 0, width: 224, height: 156 }; const refraction: PibblDisplacementFilterOptions = { map, region, strength: 12, }; const lightColor: PibblReflectedLightSource = "#ffffff"; const highlights: PibblReflectedLightFilterOptions = { map, region, source: lightColor, opacity: 0.65, direction: [-0.6, -0.8], }; const filters = mode === "original" ? [] : mode === "displacement" ? [displacement(refraction)] : mode === "light" ? [reflectedLight(highlights)] : [displacement(refraction), reflectedLight(highlights)]; return ( <Group style={{ filter: filters }}> <Rectangle style={{ width: 224, height: 156, fill: "#165165" }} /> {Array.from({ length: 35 }, (_, i) => ( <Rectangle key={i} style={{ left: (i % 7) * 32 + 2, top: Math.floor(i / 7) * 32 + 2, width: 28, height: 28, fill: "#79bac5", }} /> ))} <Circle style={{ cx: 112, cy: 78, radius: 40, fill: "#e4b852", stroke: "#fff", strokeWidth: 4, }} /> </Group> );}const grid = document.createElement("div");grid.style.cssText = "display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:16px;max-width:480px";document.body.append(grid);const comparisons = [ ["Original", "original"], ["Displacement", "displacement"], ["Reflected light", "light"], ["Both filters", "both"],] as const;const controllers = comparisons.map(([label, mode]) => { const figure = document.createElement("figure"); figure.style.margin = "0"; const caption = document.createElement("figcaption"); caption.textContent = label; const canvas = document.createElement("canvas"); canvas.width = 224; canvas.height = 156; figure.append(caption, canvas); grid.append(figure); return pibbl(canvas, <Scene mode={mode} />);});window.addEventListener( "pagehide", () => controllers.forEach((controller) => controller.dispose()), { once: true },);Usage notes
Section titled “Usage notes”- The map is a mount-owned texture; both filters use the same local region. Waves run at speed 3 so motion is clear. This comparison is automatic; Ripple a wave map demonstrates pointer-driven ripples.
Documentation version
Section titled “Documentation version”Documentation built with @pibbl/core 0.0.2, revision 2dccb19. ALPHA — NOT FOR PRODUCTION USE.