diff --git a/bun.lock b/bun.lock index cfd0bf0b0..6545d744c 100644 --- a/bun.lock +++ b/bun.lock @@ -26,6 +26,7 @@ "clsx": "^2.1.1", "culori": "4.0.2", "leva": "0.9.34", + "lodash-es": "4.17.21", "next": "15.3.6", "react": "19.2.2", "react-dom": "19.2.2", @@ -34,6 +35,7 @@ "@eslint/eslintrc": "3.2.0", "@tailwindcss/postcss": "4.1.12", "@types/culori": "4.0.0", + "@types/lodash-es": "4.17.12", "@types/node": "22.10.2", "@types/react": "19.1.0", "@types/react-dom": "19.1.1", @@ -47,11 +49,11 @@ }, "packages/shaders": { "name": "@paper-design/shaders", - "version": "0.0.68", + "version": "0.0.69", }, "packages/shaders-react": { "name": "@paper-design/shaders-react", - "version": "0.0.68", + "version": "0.0.69", "dependencies": { "@paper-design/shaders": "workspace:*", }, @@ -133,7 +135,7 @@ "@emnapi/core": ["@emnapi/core@1.4.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.0.1", "tslib": "^2.4.0" } }, "sha512-H+N/FqT07NmLmt6OFFtDfwe8PNygprzBikrEMyQfgqSmT0vzE515Pz7R8izwB9q/zsH/MA64AKoul3sA6/CzVg=="], - "@emnapi/runtime": ["@emnapi/runtime@1.7.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA=="], + "@emnapi/runtime": ["@emnapi/runtime@1.8.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg=="], "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.0.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw=="], @@ -415,6 +417,10 @@ "@types/json5": ["@types/json5@0.0.29", "", {}, "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="], + "@types/lodash": ["@types/lodash@4.17.20", "", {}, "sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA=="], + + "@types/lodash-es": ["@types/lodash-es@4.17.12", "", { "dependencies": { "@types/lodash": "*" } }, "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ=="], + "@types/node": ["@types/node@22.10.2", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ=="], "@types/react": ["@types/react@19.1.0", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-UaicktuQI+9UKyA4njtDOGBD/67t8YEBt2xdfqu8+gP9hqPUPsiXlNPcpS2gVdjmis5GKPG3fCxbQLVgxsQZ8w=="], @@ -949,6 +955,8 @@ "locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="], + "lodash-es": ["lodash-es@4.17.21", "", {}, "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="], + "lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="], "log-symbols": ["log-symbols@5.1.0", "", { "dependencies": { "chalk": "^5.0.0", "is-unicode-supported": "^1.1.0" } }, "sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA=="], diff --git a/docs/package.json b/docs/package.json index cf93718c6..7ae931869 100644 --- a/docs/package.json +++ b/docs/package.json @@ -17,6 +17,7 @@ "@vercel/analytics": "^1.5.0", "clsx": "^2.1.1", "culori": "4.0.2", + "lodash-es": "4.17.21", "leva": "0.9.34", "next": "15.3.6", "react": "19.2.2", @@ -28,6 +29,7 @@ "@types/node": "22.10.2", "@types/react": "19.1.0", "@types/react-dom": "19.1.1", + "@types/lodash-es": "4.17.12", "@tailwindcss/postcss": "4.1.12", "eslint": "9.17.0", "eslint-config-next": "15.1.2", diff --git a/docs/src/app/(shaders)/fluted-glass/page.tsx b/docs/src/app/(shaders)/fluted-glass/page.tsx index 1852fa7b8..36587fe8b 100644 --- a/docs/src/app/(shaders)/fluted-glass/page.tsx +++ b/docs/src/app/(shaders)/fluted-glass/page.tsx @@ -90,11 +90,11 @@ const FlutedGlassWithControls = () => { stretch: { value: defaults.stretch, min: 0, max: 1, order: 216 }, blur: { value: defaults.blur, min: 0, max: 1, order: 220 }, edges: { value: defaults.edges, min: 0, max: 1, order: 221 }, - margin: { value: defaults.margin, min: 0, max: 0.5, order: 500 }, - // marginLeft: { value: defaults.marginLeft, min: 0, max: 1, order: 501 }, - // marginRight: { value: defaults.marginRight, min: 0, max: 1, order: 502 }, - // marginTop: { value: defaults.marginTop, min: 0, max: 1, order: 503 }, - // marginBottom: { value: defaults.marginBottom, min: 0, max: 1, order: 504 }, + // margin: { value: defaults.margin, min: 0, max: 0.5, order: 500 }, + marginLeft: { value: defaults.marginLeft, min: 0, max: 1, order: 501 }, + marginRight: { value: defaults.marginRight, min: 0, max: 1, order: 502 }, + marginTop: { value: defaults.marginTop, min: 0, max: 1, order: 503 }, + marginBottom: { value: defaults.marginBottom, min: 0, max: 1, order: 504 }, grainMixer: { value: defaults.grainMixer, min: 0, max: 1, order: 550 }, grainOverlay: { value: defaults.grainOverlay, min: 0, max: 1, order: 551 }, scale: { value: defaults.scale, min: 0.5, max: 4, order: 600 }, diff --git a/docs/src/components/shader-container.tsx b/docs/src/components/shader-container.tsx index f7202801c..578cd5aac 100644 --- a/docs/src/components/shader-container.tsx +++ b/docs/src/components/shader-container.tsx @@ -3,7 +3,10 @@ import { SerializableValue, serializeParams } from '@/helpers/url-serializer'; import { ShaderDef } from '@/shader-defs/shader-def-types'; import { Leva } from 'leva'; import { CopyButton } from './copy-button'; -import { useState } from 'react'; +import { useEffect, useState } from 'react'; +import kebabCase from 'lodash-es/kebabCase'; + +const appUrl = process.env.NODE_ENV === 'development' ? 'http://localhost:5173' : 'https://app.paper.design'; export function ShaderContainer({ children, @@ -13,23 +16,35 @@ export function ShaderContainer({ currentParams?: Record; shaderDef?: ShaderDef; }>) { + const [isClient, setIsClient] = useState(false); + + // NOTE (douges): We set the URL after client hydration to minimize what's in the server-rendered HTML. + const openInPaperURL = + isClient && shaderDef + ? `${appUrl}/playground/${kebabCase(shaderDef.name)}#${serializeParams(currentParams as Record, shaderDef.params)}` + : appUrl; + + useEffect(() => { + setIsClient(true); + }, []); + return (
{shaderDef && currentParams && ( -
+

{shaderDef.name}

@@ -48,7 +63,7 @@ export function ShaderContainer({ {children}
setCanStartResize(event.altKey)} onPointerLeave={() => setCanStartResize(false)} >
{children}