feat: update some more components to svelte 5
All checks were successful
Deploy to GitHub Pages / build_site (push) Successful in 2m48s
All checks were successful
Deploy to GitHub Pages / build_site (push) Successful in 2m48s
This commit is contained in:
@@ -4,22 +4,26 @@
|
||||
import { onMount } from "svelte";
|
||||
import type { NodeType } from "@nodes/types";
|
||||
|
||||
export let position: [x: number, y: number] | null;
|
||||
type Props = {
|
||||
position: [x: number, y: number] | null;
|
||||
graph: GraphManager;
|
||||
};
|
||||
|
||||
export let graph: GraphManager;
|
||||
let { position = $bindable(), graph }: Props = $props();
|
||||
|
||||
let input: HTMLInputElement;
|
||||
let value: string = "";
|
||||
let activeNodeId: NodeType | undefined = undefined;
|
||||
let value = $state<string>();
|
||||
let activeNodeId = $state<NodeType>();
|
||||
|
||||
const allNodes = graph.getNodeDefinitions();
|
||||
|
||||
function filterNodes() {
|
||||
return allNodes.filter((node) => node.id.includes(value));
|
||||
return allNodes.filter((node) => node.id.includes(value ?? ""));
|
||||
}
|
||||
|
||||
$: nodes = value === "" ? allNodes : filterNodes();
|
||||
$: if (nodes) {
|
||||
const nodes = $derived(value === "" ? allNodes : filterNodes());
|
||||
$effect(() => {
|
||||
if (nodes) {
|
||||
if (activeNodeId === undefined) {
|
||||
activeNodeId = nodes[0].id;
|
||||
} else if (nodes.length) {
|
||||
@@ -29,6 +33,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function handleKeyDown(event: KeyboardEvent) {
|
||||
event.stopImmediatePropagation();
|
||||
@@ -75,7 +80,7 @@
|
||||
role="searchbox"
|
||||
placeholder="Search..."
|
||||
disabled={false}
|
||||
on:keydown={handleKeyDown}
|
||||
onkeydown={handleKeyDown}
|
||||
bind:value
|
||||
bind:this={input}
|
||||
/>
|
||||
@@ -88,7 +93,7 @@
|
||||
role="treeitem"
|
||||
tabindex="0"
|
||||
aria-selected={node.id === activeNodeId}
|
||||
on:keydown={(event) => {
|
||||
onkeydown={(event) => {
|
||||
if (event.key === "Enter") {
|
||||
if (position) {
|
||||
graph.createNode({ type: node.id, position, props: {} });
|
||||
@@ -96,17 +101,17 @@
|
||||
}
|
||||
}
|
||||
}}
|
||||
on:mousedown={() => {
|
||||
onmousedown={() => {
|
||||
if (position) {
|
||||
graph.createNode({ type: node.id, position, props: {} });
|
||||
position = null;
|
||||
}
|
||||
}}
|
||||
on:focus={() => {
|
||||
onfocus={() => {
|
||||
activeNodeId = node.id;
|
||||
}}
|
||||
class:selected={node.id === activeNodeId}
|
||||
on:mouseover={() => {
|
||||
onmouseover={() => {
|
||||
activeNodeId = node.id;
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -54,8 +54,9 @@
|
||||
},
|
||||
}}
|
||||
uniforms.camPos.value={cameraPosition}
|
||||
uniforms.backgroundColor.value={appSettings.theme && colors["layer-0"]}
|
||||
uniforms.lineColor.value={appSettings.theme && colors["outline"]}
|
||||
uniforms.backgroundColor.value={appSettings.value.theme &&
|
||||
colors["layer-0"]}
|
||||
uniforms.lineColor.value={appSettings.value.theme && colors["outline"]}
|
||||
uniforms.zoomLimits.value={[minZoom, maxZoom]}
|
||||
uniforms.dimensions.value={[width, height]}
|
||||
/>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
});
|
||||
$effect.root(() => {
|
||||
$effect(() => {
|
||||
appSettings.theme;
|
||||
appSettings.value.theme;
|
||||
circleMaterial.color = colors.edge.clone().convertSRGBToLinear();
|
||||
});
|
||||
});
|
||||
@@ -42,7 +42,7 @@
|
||||
let geometry: BufferGeometry | null = $state(null);
|
||||
|
||||
const lineColor = $derived(
|
||||
appSettings.theme && colors.edge.clone().convertSRGBToLinear(),
|
||||
appSettings.value.theme && colors.edge.clone().convertSRGBToLinear(),
|
||||
);
|
||||
|
||||
let lastId: number | null = null;
|
||||
@@ -114,6 +114,9 @@
|
||||
|
||||
{#if geometry}
|
||||
<T.Mesh position.x={from.x} position.z={from.y} position.y={0.1} {geometry}>
|
||||
<MeshLineMaterial width={Math.max(z * 0.0001, 0.00001)} color={lineColor} />
|
||||
<MeshLineMaterial
|
||||
width={Math.max(z * 0.00012, 0.00003)}
|
||||
color={lineColor}
|
||||
/>
|
||||
</T.Mesh>
|
||||
{/if}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
const { invalidate } = useThrelte();
|
||||
|
||||
$effect(() => {
|
||||
appSettings.theme;
|
||||
appSettings.value.theme;
|
||||
invalidate();
|
||||
});
|
||||
|
||||
|
||||
@@ -12,21 +12,23 @@ const variables = [
|
||||
"edge",
|
||||
] as const;
|
||||
|
||||
function getColor(variable: typeof variables[number]) {
|
||||
function getColor(variable: (typeof variables)[number]) {
|
||||
const style = getComputedStyle(document.body.parentElement!);
|
||||
let color = style.getPropertyValue(`--${variable}`);
|
||||
return new Color().setStyle(color, LinearSRGBColorSpace);
|
||||
}
|
||||
|
||||
export const colors = Object.fromEntries(variables.map(v => [v, getColor(v)])) as Record<typeof variables[number], Color>;
|
||||
export const colors = Object.fromEntries(
|
||||
variables.map((v) => [v, getColor(v)]),
|
||||
) as Record<(typeof variables)[number], Color>;
|
||||
|
||||
$effect.root(() => {
|
||||
$effect(() => {
|
||||
if (!appSettings.theme || !("getComputedStyle" in globalThis)) return;
|
||||
if (!appSettings.value.theme || !("getComputedStyle" in globalThis)) return;
|
||||
const style = getComputedStyle(document.body.parentElement!);
|
||||
for (const v of variables) {
|
||||
const hex = style.getPropertyValue(`--${v}`);
|
||||
colors[v].setStyle(hex, LinearSRGBColorSpace);
|
||||
}
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
const isSelected = $derived(graphState.selectedNodes.has(node.id));
|
||||
let strokeColor = $state(colors.selected);
|
||||
$effect(() => {
|
||||
appSettings.theme;
|
||||
appSettings.value.theme;
|
||||
strokeColor = isSelected
|
||||
? colors.selected
|
||||
: isActive
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
|
||||
{#each parameters as [key, value], i}
|
||||
<NodeParameter
|
||||
{node}
|
||||
bind:node
|
||||
id={key}
|
||||
input={value}
|
||||
isLast={i == parameters.length - 1}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import type { Node, Socket } from "@nodes/types";
|
||||
import { getContext } from "svelte";
|
||||
|
||||
const { node = $bindable<Node>() } = $props();
|
||||
const { node }: { node: Node } = $props();
|
||||
|
||||
const setDownSocket = getContext<(socket: Socket) => void>("setDownSocket");
|
||||
const getSocketPosition =
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
isLast?: boolean;
|
||||
};
|
||||
|
||||
const { node, input, id, isLast }: Props = $props();
|
||||
let { node = $bindable(), input, id, isLast }: Props = $props();
|
||||
|
||||
const inputType = node?.tmp?.type?.inputs?.[id]!;
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
<label for={elementId}>{input.label || id}</label>
|
||||
{/if}
|
||||
{#if inputType.external !== true}
|
||||
<NodeInput {elementId} {node} {input} {id} />
|
||||
<NodeInput {elementId} bind:node {input} {id} />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
index = getContext<() => number>("registerCell")();
|
||||
}
|
||||
|
||||
const sizes = getContext<string[]>("sizes");
|
||||
const sizes = getContext<{ value: string[] }>("sizes");
|
||||
|
||||
let downSizes: string[] = [];
|
||||
let downWidth = 0;
|
||||
@@ -16,7 +16,7 @@
|
||||
let startX = 0;
|
||||
|
||||
function handleMouseDown(event: MouseEvent) {
|
||||
downSizes = [...sizes];
|
||||
downSizes = [...sizes.value];
|
||||
mouseDown = true;
|
||||
startX = event.clientX;
|
||||
downWidth = wrapper.getBoundingClientRect().width;
|
||||
@@ -25,7 +25,7 @@
|
||||
function handleMouseMove(event: MouseEvent) {
|
||||
if (mouseDown) {
|
||||
const width = downWidth + startX - event.clientX;
|
||||
sizes[index] = `${width}px`;
|
||||
sizes.value[index] = `${width}px`;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
setContext("registerCell", function () {
|
||||
let index = registerIndex;
|
||||
registerIndex++;
|
||||
if (registerIndex > sizes.length) {
|
||||
sizes = [...sizes, "1fr"];
|
||||
if (registerIndex > sizes.value.length) {
|
||||
sizes.value = [...sizes.value, "1fr"];
|
||||
}
|
||||
return index;
|
||||
});
|
||||
@@ -20,7 +20,7 @@
|
||||
setContext("sizes", sizes);
|
||||
|
||||
const cols = $derived(
|
||||
sizes.map((size, i) => `${i > 0 ? "1px " : ""}` + size).join(" "),
|
||||
sizes.value.map((size, i) => `${i > 0 ? "1px " : ""}` + size).join(" "),
|
||||
);
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,11 +1,34 @@
|
||||
export function localState<T>(key: string, defaultValue: T): T {
|
||||
const stored = localStorage.getItem(key);
|
||||
const state = $state(stored ? JSON.parse(stored) : defaultValue);
|
||||
import { browser } from "$app/environment";
|
||||
|
||||
export class LocalStore<T> {
|
||||
value = $state<T>() as T;
|
||||
key = "";
|
||||
|
||||
constructor(key: string, value: T) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
|
||||
if (browser) {
|
||||
const item = localStorage.getItem(key);
|
||||
if (item) this.value = this.deserialize(item);
|
||||
}
|
||||
|
||||
$effect.root(() => {
|
||||
$effect(() => {
|
||||
const value = $state.snapshot(state);
|
||||
localStorage.setItem(key, JSON.stringify(value));
|
||||
localStorage.setItem(this.key, this.serialize(this.value));
|
||||
});
|
||||
});
|
||||
return state;
|
||||
}
|
||||
|
||||
serialize(value: T): string {
|
||||
return JSON.stringify(value);
|
||||
}
|
||||
|
||||
deserialize(item: string): T {
|
||||
return JSON.parse(item);
|
||||
}
|
||||
}
|
||||
|
||||
export function localState<T>(key: string, value: T) {
|
||||
return new LocalStore(key, value);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
<script lang="ts">
|
||||
import { T, useTask, useThrelte } from "@threlte/core";
|
||||
import { MeshLineGeometry, MeshLineMaterial, Text } from "@threlte/extras";
|
||||
import {
|
||||
Grid,
|
||||
MeshLineGeometry,
|
||||
MeshLineMaterial,
|
||||
Text,
|
||||
} from "@threlte/extras";
|
||||
import {
|
||||
type Group,
|
||||
type BufferGeometry,
|
||||
@@ -70,7 +75,7 @@
|
||||
}
|
||||
|
||||
$effect(() => {
|
||||
const wireframe = appSettings.debug.wireframe;
|
||||
const wireframe = appSettings.value.debug.wireframe;
|
||||
scene.traverse(function (child) {
|
||||
if (isMesh(child) && isMatCapMaterial(child.material)) {
|
||||
child.material.wireframe = wireframe;
|
||||
@@ -90,18 +95,25 @@
|
||||
|
||||
<Camera {center} {centerCamera} />
|
||||
|
||||
{#if appSettings.showGrid}
|
||||
<T.GridHelper
|
||||
args={[20, 20]}
|
||||
colorGrid={colors["outline"]}
|
||||
colorCenterLine={new Color("red")}
|
||||
{#if appSettings.value.showGrid}
|
||||
<Grid
|
||||
cellColor={colors["outline"]}
|
||||
cellThickness={0.7}
|
||||
infiniteGrid
|
||||
sectionThickness={0.7}
|
||||
sectionDistance={2}
|
||||
sectionColor={colors["outline"]}
|
||||
fadeDistance={50}
|
||||
fadeStrength={10}
|
||||
fadeOrigin={new Vector3(0, 0, 0)}
|
||||
/>
|
||||
<!-- <T.GridHelper args={[20, 20]} color5={colors["outline"]} /> -->
|
||||
{/if}
|
||||
|
||||
<T.Group>
|
||||
{#if geometries}
|
||||
{#each geometries as geo}
|
||||
{#if appSettings.debug.showIndices}
|
||||
{#if appSettings.value.debug.showIndices}
|
||||
{#each geo.attributes.position.array as _, i}
|
||||
{#if i % 3 === 0}
|
||||
<Text fontSize={0.25} position={getPosition(geo, i)} />
|
||||
@@ -109,7 +121,7 @@
|
||||
{/each}
|
||||
{/if}
|
||||
|
||||
{#if appSettings.debug.showVertices}
|
||||
{#if appSettings.value.debug.showVertices}
|
||||
<T.Points visible={true}>
|
||||
<T is={geo} />
|
||||
<T.PointsMaterial size={0.25} />
|
||||
@@ -121,7 +133,7 @@
|
||||
<T.Group bind:ref={scene}></T.Group>
|
||||
</T.Group>
|
||||
|
||||
{#if appSettings.debug.showStemLines && lines}
|
||||
{#if appSettings.value.debug.showStemLines && lines}
|
||||
{#each lines as line}
|
||||
<T.Mesh>
|
||||
<MeshLineGeometry points={line} />
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
const inputs = splitNestedArray(result);
|
||||
perf.endPoint();
|
||||
|
||||
if (appSettings.debug.showStemLines) {
|
||||
if (appSettings.value.debug.showStemLines) {
|
||||
perf.addPoint("create-lines");
|
||||
lines = inputs
|
||||
.map((input) => {
|
||||
@@ -91,7 +91,7 @@
|
||||
};
|
||||
</script>
|
||||
|
||||
{#if appSettings.debug.showPerformancePanel}
|
||||
{#if appSettings.value.debug.showPerformancePanel}
|
||||
<SmallPerformanceViewer {fps} store={perf} />
|
||||
{/if}
|
||||
|
||||
|
||||
@@ -77,13 +77,13 @@
|
||||
|
||||
let internalValue = $state(getDefaultValue());
|
||||
|
||||
let open = $state(openSections[id]);
|
||||
let open = $state(openSections.value[id]);
|
||||
|
||||
// Persist <details> open/closed state for groups
|
||||
if (depth > 0 && !isNodeInput(type[key!])) {
|
||||
$effect(() => {
|
||||
if (open !== undefined) {
|
||||
openSections[id] = open;
|
||||
openSections.value[id] = open;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -110,7 +110,7 @@
|
||||
<!-- Leaf input -->
|
||||
<div class="input input-{type[key].type}" class:first-level={depth === 1}>
|
||||
{#if type[key].type === "button"}
|
||||
<button onclick={() => console.log(type[key])}>
|
||||
<button onclick={() => type[key].callback()}>
|
||||
{type[key].label || key}
|
||||
</button>
|
||||
{:else}
|
||||
@@ -124,7 +124,7 @@
|
||||
<NestedSettings
|
||||
id={`${id}.${childKey}`}
|
||||
key={childKey}
|
||||
{value}
|
||||
bind:value
|
||||
{type}
|
||||
depth={depth + 1}
|
||||
/>
|
||||
@@ -142,7 +142,7 @@
|
||||
<NestedSettings
|
||||
id={`${id}.${childKey}`}
|
||||
key={childKey}
|
||||
value={value[key] as SettingsValue}
|
||||
bind:value={value[key] as SettingsValue}
|
||||
type={type[key] as unknown as SettingsType}
|
||||
depth={depth + 1}
|
||||
/>
|
||||
|
||||
@@ -144,7 +144,7 @@ type ExtractSettingsValues<T> = {
|
||||
: never;
|
||||
};
|
||||
|
||||
function settingsToStore<T>(settings: T): ExtractSettingsValues<T> {
|
||||
export function settingsToStore<T>(settings: T): ExtractSettingsValues<T> {
|
||||
const result = {} as any;
|
||||
for (const key in settings) {
|
||||
const value = settings[key];
|
||||
@@ -166,7 +166,7 @@ export let appSettings = localState(
|
||||
|
||||
$effect.root(() => {
|
||||
$effect(() => {
|
||||
const theme = appSettings.theme;
|
||||
const theme = appSettings.value.theme;
|
||||
const classes = document.documentElement.classList;
|
||||
const newClassName = `theme-${theme}`;
|
||||
if (classes) {
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
memoryRuntime.perf = performanceStore;
|
||||
|
||||
const runtime = $derived(
|
||||
appSettings.debug.useWorker ? workerRuntime : memoryRuntime,
|
||||
appSettings.value.debug.useWorker ? workerRuntime : memoryRuntime,
|
||||
);
|
||||
|
||||
let activeNode = $state<Node | undefined>(undefined);
|
||||
@@ -69,6 +69,11 @@
|
||||
},
|
||||
]);
|
||||
let graphSettings = $state<Record<string, any>>({});
|
||||
$effect(() => {
|
||||
if (graphSettings) {
|
||||
manager?.setSettings($state.snapshot(graphSettings));
|
||||
}
|
||||
});
|
||||
type BooleanSchema = {
|
||||
[key: string]: {
|
||||
type: "boolean";
|
||||
@@ -92,7 +97,7 @@
|
||||
);
|
||||
let b = performance.now();
|
||||
|
||||
if (appSettings.debug.useWorker) {
|
||||
if (appSettings.value.debug.useWorker) {
|
||||
let perfData = await runtime.getPerformanceData();
|
||||
let lastRun = perfData?.at(-1);
|
||||
if (lastRun?.total) {
|
||||
@@ -118,13 +123,13 @@
|
||||
//@ts-ignore
|
||||
AppSettingTypes.debug.stressTest.loadGrid.callback = () => {
|
||||
graph = templates.grid(
|
||||
appSettings.debug.amount.value,
|
||||
appSettings.debug.amount.value,
|
||||
appSettings.value.debug.amount.value,
|
||||
appSettings.value.debug.amount.value,
|
||||
);
|
||||
};
|
||||
//@ts-ignore
|
||||
AppSettingTypes.debug.stressTest.loadTree.callback = () => {
|
||||
graph = templates.tree(appSettings.debug.amount.value);
|
||||
graph = templates.tree(appSettings.value.debug.amount.value);
|
||||
};
|
||||
//@ts-ignore
|
||||
AppSettingTypes.debug.stressTest.lottaFaces.callback = () => {
|
||||
@@ -155,7 +160,7 @@
|
||||
bind:scene
|
||||
bind:this={viewerComponent}
|
||||
perf={performanceStore}
|
||||
centerCamera={appSettings.centerCamera}
|
||||
centerCamera={appSettings.value.centerCamera}
|
||||
/>
|
||||
</Grid.Cell>
|
||||
<Grid.Cell>
|
||||
@@ -163,10 +168,10 @@
|
||||
{graph}
|
||||
bind:this={graphInterface}
|
||||
registry={nodeRegistry}
|
||||
showGrid={appSettings.nodeInterface.showNodeGrid}
|
||||
snapToGrid={appSettings.nodeInterface.snapToGrid}
|
||||
showGrid={appSettings.value.nodeInterface.showNodeGrid}
|
||||
snapToGrid={appSettings.value.nodeInterface.snapToGrid}
|
||||
bind:activeNode
|
||||
bind:showHelp={appSettings.nodeInterface.showHelp}
|
||||
bind:showHelp={appSettings.value.nodeInterface.showHelp}
|
||||
bind:settings={graphSettings}
|
||||
bind:settingTypes={graphSettingTypes}
|
||||
onresult={(result) => handleUpdate(result)}
|
||||
@@ -176,7 +181,7 @@
|
||||
<Panel id="general" title="General" icon="i-tabler-settings">
|
||||
<NestedSettings
|
||||
id="general"
|
||||
value={appSettings}
|
||||
bind:value={appSettings.value}
|
||||
type={AppSettingTypes}
|
||||
/>
|
||||
</Panel>
|
||||
@@ -207,7 +212,7 @@
|
||||
id="performance"
|
||||
title="Performance"
|
||||
classes="text-red-400"
|
||||
hidden={!appSettings.debug.showPerformancePanel}
|
||||
hidden={!appSettings.value.debug.showPerformancePanel}
|
||||
icon="i-tabler-brand-speedtest"
|
||||
>
|
||||
{#if $performanceStore}
|
||||
@@ -218,7 +223,7 @@
|
||||
id="benchmark"
|
||||
title="Benchmark"
|
||||
classes="text-red-400"
|
||||
hidden={!appSettings.debug.showBenchmarkPanel}
|
||||
hidden={!appSettings.value.debug.showBenchmarkPanel}
|
||||
icon="i-tabler-graph"
|
||||
>
|
||||
<BenchmarkPanel run={randomGenerate} />
|
||||
@@ -250,7 +255,6 @@
|
||||
|
||||
<style>
|
||||
header {
|
||||
/* border-bottom: solid thin var(--outline); */
|
||||
background-color: var(--layer-1);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user