feat(app): dots background for node interface

This commit is contained in:
2026-02-09 16:53:57 +01:00
parent e89a46e146
commit 23a48572f3
7 changed files with 72 additions and 39 deletions

View File

@@ -11,6 +11,7 @@ uniform vec3 camPos;
uniform vec2 zoomLimits;
uniform vec3 backgroundColor;
uniform vec3 lineColor;
uniform int gridType; // 0 = grid lines, 1 = dots
// Anti-aliased step: threshold in the same units as `value`
float aaStep(float threshold, float value, float deriv) {
@@ -78,6 +79,7 @@ void main(void) {
float ux = (vUv.x - 0.5) * width + cx * cz;
float uy = (vUv.y - 0.5) * height - cy * cz;
if(gridType == 0) {
// extra small grid
float m1 = grid(ux, uy, divisions * 4.0, thickness * 4.0) * 0.9;
float m2 = grid(ux, uy, divisions * 16.0, thickness * 16.0) * 0.5;
@@ -107,6 +109,21 @@ void main(void) {
vec3 color = mix(backgroundColor, lineColor, c);
gl_FragColor = vec4(color, 1.0);
} else {
float large = circle_grid(ux, uy, cz * 20.0, 1.0) * 0.4;
float medium = circle_grid(ux, uy, cz * 10.0, 1.0) * 0.6;
float small = circle_grid(ux, uy, cz * 2.5, 1.0) * 0.8;
float c = mix(large, medium, min(nz * 2.0 + 0.05, 1.0));
c = mix(c, small, clamp((nz - 0.3) / 0.7, 0.0, 1.0));
vec3 color = mix(backgroundColor, lineColor, c);
gl_FragColor = vec4(color, 1.0);
}
}

View File

@@ -6,11 +6,12 @@
import BackgroundVert from './Background.vert';
type Props = {
minZoom: number;
maxZoom: number;
cameraPosition: [number, number, number];
width: number;
height: number;
minZoom?: number;
maxZoom?: number;
cameraPosition?: [number, number, number];
width?: number;
height?: number;
type?: 'grid' | 'dots' | 'none';
};
let {
@@ -18,9 +19,18 @@
maxZoom = 150,
cameraPosition = [0, 1, 0],
width = globalThis?.innerWidth || 100,
height = globalThis?.innerHeight || 100
height = globalThis?.innerHeight || 100,
type = 'grid'
}: Props = $props();
const typeMap = new Map([
['grid', 0],
['dots', 1],
['none', 2]
]);
const gridType = $derived(typeMap.get(type) || 0);
let bw = $derived(width / cameraPosition[2]);
let bh = $derived(height / cameraPosition[2]);
</script>
@@ -51,6 +61,9 @@
},
dimensions: {
value: [100, 100]
},
gridType: {
value: 0
}
}}
uniforms.camPos.value={cameraPosition}
@@ -59,6 +72,7 @@
uniforms.lineColor.value={appSettings.value.theme && colors['outline']}
uniforms.zoomLimits.value={[minZoom, maxZoom]}
uniforms.dimensions.value={[width, height]}
uniforms.gridType.value={gridType}
/>
</T.Mesh>
</T.Group>

View File

@@ -83,7 +83,7 @@ export class GraphState {
addMenuPosition = $state<[number, number] | null>(null);
snapToGrid = $state(false);
showGrid = $state(true);
backgroundType = $state<'grid' | 'dots' | 'none'>('grid');
showHelp = $state(false);
cameraDown = [0, 0];

View File

@@ -132,8 +132,9 @@
position={graphState.cameraPosition}
/>
{#if graphState.showGrid !== false}
{#if graphState.backgroundType !== 'none'}
<Background
type={graphState.backgroundType}
cameraPosition={graphState.cameraPosition}
{maxZoom}
{minZoom}

View File

@@ -13,7 +13,7 @@
settings?: Record<string, unknown>;
activeNode?: NodeInstance;
showGrid?: boolean;
backgroundType?: 'grid' | 'dots' | 'none';
snapToGrid?: boolean;
showHelp?: boolean;
settingTypes?: Record<string, unknown>;
@@ -27,7 +27,7 @@
registry,
settings = $bindable(),
activeNode = $bindable(),
showGrid = $bindable(true),
backgroundType = $bindable('grid'),
snapToGrid = $bindable(true),
showHelp = $bindable(false),
settingTypes = $bindable(),
@@ -43,7 +43,7 @@
const graphState = new GraphState(manager);
$effect(() => {
graphState.showGrid = showGrid;
graphState.backgroundType = backgroundType;
graphState.snapToGrid = snapToGrid;
graphState.showHelp = showHelp;
});

View File

@@ -30,10 +30,11 @@ export const AppSettingTypes = {
},
nodeInterface: {
title: 'Node Interface',
showNodeGrid: {
type: 'boolean',
label: 'Show Grid',
value: true
backgroundType: {
type: 'select',
label: 'Background',
options: ['grid', 'dots', 'none'],
value: 'grid'
},
snapToGrid: {
type: 'boolean',

View File

@@ -171,7 +171,7 @@
graph={pm.graph}
bind:this={graphInterface}
registry={nodeRegistry}
showGrid={appSettings.value.nodeInterface.showNodeGrid}
backgroundType={appSettings.value.nodeInterface.backgroundType}
snapToGrid={appSettings.value.nodeInterface.snapToGrid}
bind:activeNode
bind:showHelp={appSettings.value.nodeInterface.showHelp}