Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
0902a95
water drops
uuuulala Apr 27, 2025
28fb91d
saving progress
uuuulala May 2, 2025
ed3b21a
Merge remote-tracking branch 'origin/main' into water-drops
uuuulala May 3, 2025
d5da578
turning to blobs (saving work in progress)
uuuulala May 5, 2025
3b930b7
-
uuuulala May 5, 2025
3f9ddae
saving progress
uuuulala May 13, 2025
d6c5a6c
first version
uuuulala May 17, 2025
a81c4e9
Merge remote-tracking branch 'origin/main' into water-drops
uuuulala May 17, 2025
a9ffc15
fixing metadata
uuuulala May 17, 2025
276c439
component renaming
uuuulala May 17, 2025
21ba1e2
finish renaming, blobsGrid added to registry and homepage
uuuulala May 17, 2025
da6e068
prettier
uuuulala May 17, 2025
d9ee00b
homepage build fix
uuuulala May 17, 2025
bf216f2
Merge remote-tracking branch 'origin/main' into blobs-grid
uuuulala May 24, 2025
c1efa3f
adjusting to updated color management
uuuulala May 24, 2025
2a2a743
applying unified colorBack behaviour
uuuulala May 24, 2025
4b8c06e
blobs border anti-aliasing back
uuuulala May 24, 2025
2e3d04f
Merge remote-tracking branch 'origin/main' into blobs-grid
uuuulala Jun 6, 2025
ed4bad7
adjusting blobs to recent changes, removing the anti-crisp on blob edges
uuuulala Jun 6, 2025
05c1db0
blobs docs
uuuulala Jun 6, 2025
284f642
Merge branch 'main' into blobs-grid
uuuulala Jul 12, 2025
5c64973
merging fix, manual prettier
uuuulala Jul 12, 2025
d8ef66e
design refine
uuuulala Jul 12, 2025
2784094
Merge remote-tracking branch 'origin/main' into blobs-grid
uuuulala Jul 14, 2025
a9f6ae9
thicker stroke + presets rework
uuuulala Jul 14, 2025
4be3579
small adjustments
uuuulala Aug 5, 2025
1e2cda3
Merge remote-tracking branch 'origin/main' into blobs-grid
uuuulala Aug 5, 2025
ae9fccf
fix scale after merging
uuuulala Aug 5, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions docs/registry.json
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,19 @@
"type": "registry:component"
}
]
},
{
"name": "blobs-grid",
"type": "registry:component",
"title": "Blobs Grid Example",
"description": "Blobs Grid shader example.",
"dependencies": ["@paper-design/shaders-react"],
"files": [
{
"path": "registry/blobs-grid-example.tsx",
"type": "registry:component"
}
]
}
]
}
5 changes: 5 additions & 0 deletions docs/registry/blobs-grid-example.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { BlobsGrid, type BlobsGridProps } from '@paper-design/shaders-react';

export function BlobsGridExample(props: BlobsGridProps) {
return <BlobsGrid style={{ position: 'fixed', width: '100%', height: '100%' }} {...props} />;
}
9 changes: 9 additions & 0 deletions docs/src/app/blobs-grid/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Metadata } from 'next';

export const metadata: Metadata = {
title: 'Blobs Grid Shader | Paper',
};

export default function Layout({ children }: { children: React.ReactNode }) {
return <>{children}</>;
}
112 changes: 112 additions & 0 deletions docs/src/app/blobs-grid/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
'use client';

import { BlobsGrid, type BlobsGridParams, blobsGridPresets } from '@paper-design/shaders-react';
import { useControls, button, folder } from 'leva';
import { setParamsSafe, useResetLevaParams } from '@/helpers/use-reset-leva-params';
import { usePresetHighlight } from '@/helpers/use-preset-highlight';
import Link from 'next/link';
import { BackButton } from '@/components/back-button';
import { cleanUpLevaParams } from '@/helpers/clean-up-leva-params';
import { ShaderFit, ShaderFitOptions, blobsGridMeta } from '@paper-design/shaders';
import { useColors } from '@/helpers/use-colors';
import { toHsla } from '@/helpers/to-hsla';

/**
* You can copy/paste this example to use BlobsGrid in your app
*/
const BlobsGridExample = () => {
return <BlobsGrid style={{ position: 'fixed', width: '100%', height: '100%' }} />;
};

/**
* This example has controls added so you can play with settings in the example app
*/

const { worldWidth, worldHeight, ...defaults } = blobsGridPresets[0].params;

const BlobsGridWithControls = () => {
const { colors, setColors } = useColors({
defaultColors: defaults.colors,
maxColorCount: blobsGridMeta.maxColorCount,
});

const [params, setParams] = useControls(() => {
return {
Parameters: folder(
{
stepsPerColor: { value: defaults.stepsPerColor, min: 1, max: 3, step: 1, order: 0 },
colorBack: { value: toHsla(defaults.colorBack), order: 100 },
colorShade: { value: toHsla(defaults.colorShade), order: 101 },
colorSpecular: { value: toHsla(defaults.colorSpecular), order: 101 },
colorInnerShadow: { value: toHsla(defaults.colorInnerShadow), order: 102 },
distortion: { value: defaults.distortion, min: 0, max: 20, order: 300 },
size: { value: defaults.size, min: 0, max: 1, order: 301 },
specular: { value: defaults.specular, min: 0, max: 1, order: 302 },
specularNormal: { value: defaults.specularNormal, min: 0, max: 1, order: 303 },
shade: { value: defaults.shade, min: 0, max: 1, order: 304 },
innerShadow: { value: defaults.innerShadow, min: 0, max: 1, order: 305 },
speed: { value: defaults.speed, min: 0, max: 2, order: 400 },
},
{ order: 1 }
),
Transform: folder(
{
scale: { value: defaults.scale, min: 0.01, max: 4, order: 400 },
rotation: { value: defaults.rotation, min: 0, max: 360, order: 401 },
offsetX: { value: defaults.offsetX, min: -1, max: 1, order: 402 },
offsetY: { value: defaults.offsetY, min: -1, max: 1, order: 403 },
},
{
order: 2,
collapsed: false,
}
),
Fit: folder(
{
fit: { value: defaults.fit, options: Object.keys(ShaderFitOptions) as ShaderFit[], order: 404 },
worldWidth: { value: 1000, min: 1, max: 5120, order: 405 },
worldHeight: { value: 500, min: 1, max: 5120, order: 406 },
originX: { value: defaults.originX, min: 0, max: 1, order: 407 },
originY: { value: defaults.originY, min: 0, max: 1, order: 408 },
},
{
order: 3,
collapsed: true,
}
),
};
}, [colors.length]);

useControls(() => {
const presets = Object.fromEntries(
blobsGridPresets.map(({ name, params: { worldWidth, worldHeight, ...preset } }) => [
name,
button(() => {
const { colors, ...presetParams } = preset;
setColors(colors);
setParamsSafe(params, setParams, presetParams);
}),
])
);
return {
Presets: folder(presets, { order: -1 }),
};
});

// Reset to defaults on mount, so that Leva doesn't show values from other
// shaders when navigating (if two shaders have a color1 param for example)
useResetLevaParams(params, setParams, defaults);
usePresetHighlight(blobsGridPresets, params);
cleanUpLevaParams(params);

return (
<>
<Link href="/">
<BackButton />
</Link>
<BlobsGrid {...params} colors={colors} className="fixed size-full" />
</>
);
};

export default BlobsGridWithControls;
172 changes: 86 additions & 86 deletions docs/src/home-shaders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ import {
staticMeshGradientPresets,
StaticRadialGradient,
staticRadialGradientPresets,
BlobsGrid,
blobsGridPresets,
} from '@paper-design/shaders-react';
import { StaticImageData } from 'next/image';
import TextureTest from './app/texture-test/page';
Expand All @@ -84,150 +86,148 @@ export const homeShaders = [
// shaderConfig: {},
// },
{
name: 'grain gradient',
url: '/grain-gradient',
ShaderComponent: GrainGradient,
image: grainGradientImg,
shaderConfig: { ...grainGradientPresets[0].params, frame: 7000, speed: 2 },
name: 'simplex noise',
image: simplexNoiseImg,
url: '/simplex-noise',
ShaderComponent: SimplexNoise,
shaderConfig: { ...simplexNoisePresets[0].params, scale: 0.35 },
},
{
name: 'mesh gradient',
image: meshGradientImg,
url: '/mesh-gradient',
ShaderComponent: MeshGradient,
shaderConfig: { ...meshGradientPresets[0].params, frame: 41500 },
shaderConfig: { ...meshGradientPresets[0].params },
},
{
name: 'static mesh gradient',
url: '/static-mesh-gradient',
ShaderComponent: StaticMeshGradient,
image: staticMeshGradientImg,
shaderConfig: { ...staticMeshGradientPresets[0].params, rotation: 270 },
},
{
name: 'static radial gradient',
url: '/static-radial-gradient',
ShaderComponent: StaticRadialGradient,
image: staticRadialGradientImg,
shaderConfig: { ...staticRadialGradientPresets[0].params, scale: 0.7 },
},
{
name: 'dithering',
url: '/dithering',
ShaderComponent: Dithering,
image: ditheringImg,
shaderConfig: { ...ditheringPresets[0].params, scale: 0.45 },
name: 'neuro noise',
image: neuroNoiseImg,
url: '/neuro-noise',
ShaderComponent: NeuroNoise,
shaderConfig: { ...neuroNoisePresets[0].params },
},
{
name: 'dot orbit',
image: dotOrbitImg,
url: '/dot-orbit',
ShaderComponent: DotOrbit,
shaderConfig: { ...dotOrbitPresets[0].params, scale: 0.45 },
shaderConfig: { ...dotOrbitPresets[0].params, scale: 0.35 },
},
{
name: 'smoke ring',
image: smokeRingImg,
url: '/smoke-ring',
ShaderComponent: SmokeRing,
shaderConfig: { ...smokeRingPresets[3].params },
},
{
name: 'metaballs',
image: metaballsImg,
url: '/metaballs',
ShaderComponent: Metaballs,
shaderConfig: { ...metaballsPresets[0].params },
},
{
name: 'dot grid',
url: '/dot-grid',
ShaderComponent: DotGrid,
image: dotGridImg,
shaderConfig: { ...dotGridPresets[0].params, scale: 1.1, size: 2 },
shaderConfig: { ...dotGridPresets[0].params, scale: 0.4 },
},
{
name: 'perlin',
url: '/perlin-noise',
ShaderComponent: PerlinNoise,
image: perlinNoiseImg,
shaderConfig: { ...perlinNoisePresets[1].params, scale: 0.8 },
},
{
name: 'voronoi',
url: '/voronoi',
ShaderComponent: Voronoi,
image: voronoiImg,
shaderConfig: { ...voronoiPresets[0].params, scale: 0.5 },
},
{
name: 'waves',
url: '/waves',
ShaderComponent: Waves,
image: wavesImg,
shaderConfig: { ...wavesPresets[0].params, shape: 1 },
},
{
name: 'warp',
url: '/warp',
ShaderComponent: Warp,
image: warpImg,
shaderConfig: { ...warpPresets[0].params, speed: 2, offsetX: -0.2, scale: 0.6, frame: 20000 },
shaderConfig: { ...warpPresets[2].params, scale: 0.25 },
},
{
name: 'god rays',
url: '/god-rays',
ShaderComponent: GodRays,
image: godRaysImg,
shaderConfig: { ...godRaysPresets[0].params, offsetX: -1.1, midSize: 1 },
},
{
name: 'spiral',
url: '/spiral',
ShaderComponent: Spiral,
image: spiralImg,
shaderConfig: { ...spiralPresets[0].params, scale: 0.5, speed: 2 },
shaderConfig: { ...spiralPresets[1].params },
},
{
name: 'swirl',
url: '/swirl',
ShaderComponent: Swirl,
image: swirlImg,
shaderConfig: { ...swirlPresets[0].params, speed: 0.7 },
},
{
name: 'waves',
url: '/waves',
ShaderComponent: Waves,
image: wavesImg,
shaderConfig: { ...wavesPresets[0].params, scale: 0.9 },
shaderConfig: { ...swirlPresets[0].params },
},
{
name: 'neuro noise',
image: neuroNoiseImg,
url: '/neuro-noise',
ShaderComponent: NeuroNoise,
shaderConfig: { ...neuroNoisePresets[0].params, scale: 0.6, frame: 1500, offsetX: -0.17 },
},
{
name: 'perlin',
url: '/perlin-noise',
ShaderComponent: PerlinNoise,
image: perlinNoiseImg,
shaderConfig: { ...perlinNoisePresets[0].params, scale: 0.8, speed: 0.2 },
name: 'dithering',
url: '/dithering',
ShaderComponent: Dithering,
shaderConfig: { ...ditheringPresets[0].params },
},
{
name: 'simplex noise',
image: simplexNoiseImg,
url: '/simplex-noise',
ShaderComponent: SimplexNoise,
shaderConfig: { ...simplexNoisePresets[0].params, scale: 0.4 },
name: 'liquid metal',
url: '/liquid-metal',
ShaderComponent: LiquidMetal,
shaderConfig: { ...liquidMetalPresets[0].params },
},
{
name: 'voronoi',
url: '/voronoi',
ShaderComponent: Voronoi,
image: voronoiImg,
shaderConfig: { ...voronoiPresets[0].params, scale: 0.35 },
name: 'grain gradient',
url: '/grain-gradient',
ShaderComponent: GrainGradient,
shaderConfig: { ...grainGradientPresets[0].params },
},
{
name: 'pulsing border',
url: '/pulsing-border',
ShaderComponent: PulsingBorder,
image: pulsingBorderImg,
shaderConfig: { ...pulsingBorderPresets[0].params, scale: 0.45 },
},
{
name: 'metaballs',
image: metaballsImg,
url: '/metaballs',
ShaderComponent: Metaballs,
shaderConfig: { ...metaballsPresets[0].params, scale: 0.7, frame: 21300, offsetY: -0.01 },
shaderConfig: { ...pulsingBorderPresets[0].params },
},
{
name: 'color panels',
url: '/color-panels',
ShaderComponent: ColorPanels,
image: colorPanelsImg,
shaderConfig: { ...colorPanelsPresets[0].params, speed: 2, scale: 0.6 },
shaderConfig: { ...colorPanelsPresets[0].params },
},
{
name: 'smoke ring',
image: smokeRingImg,
url: '/smoke-ring',
ShaderComponent: SmokeRing,
shaderConfig: { ...smokeRingPresets[0].params, scale: 0.6, speed: 2 },
name: 'static mesh gradient',
url: '/static-mesh-gradient',
ShaderComponent: StaticMeshGradient,
shaderConfig: { ...staticMeshGradientPresets[0].params },
},
{
name: 'liquid metal',
url: '/liquid-metal',
ShaderComponent: LiquidMetal,
image: liquidMetalImg,
shaderConfig: { ...liquidMetalPresets[0].params, scale: 0.45 },
name: 'static radial gradient',
url: '/static-radial-gradient',
ShaderComponent: StaticRadialGradient,
shaderConfig: { ...staticRadialGradientPresets[0].params },
},
{
name: 'god rays',
url: '/god-rays',
ShaderComponent: GodRays,
image: godRaysImg,
shaderConfig: { ...godRaysPresets[0].params, speed: 2, scale: 0.5, offsetY: -0.5 },
name: 'blobs grid',
url: '/blobs-grid',
ShaderComponent: BlobsGrid,
shaderConfig: { ...blobsGridPresets[0].params },
},
] satisfies HomeShaderConfig[];
Loading