import { postJson } from "../api/controlApi"; import { LayerCard } from "./LayerCard"; function moveItem(array, fromIndex, toIndex) { if (fromIndex < 0 || fromIndex >= array.length || toIndex < 0 || toIndex >= array.length) { return array; } const copy = [...array]; const [item] = copy.splice(fromIndex, 1); copy.splice(toIndex, 0, item); return copy; } export function LayerStack({ dragLayerId, dropTargetLayerId, expandedLayerIds, layers, pendingShaderId, setAppState, setDragLayerId, setDropTargetLayerId, setExpandedLayerIds, setPendingShaderId, shaders, }) { const expandedSet = new Set(expandedLayerIds); function updateLayerParameterOptimistically(layerId, parameterId, value) { return postJson("/api/layers/update-parameter", { layerId, parameterId, value, }); } function toggleExpanded(layerId) { setExpandedLayerIds((current) => current.includes(layerId) ? current.filter((id) => id !== layerId) : [...current, layerId], ); } function removeLayer(layerId) { setExpandedLayerIds((current) => current.filter((id) => id !== layerId)); postJson("/api/layers/remove", { layerId }); } function handleDrop(event, targetLayerId, targetIndex) { const sourceLayerId = event.dataTransfer.getData("text/plain") || dragLayerId; if (!sourceLayerId || sourceLayerId === targetLayerId) { setDragLayerId(null); setDropTargetLayerId(null); return; } setAppState((current) => { if (!current?.layers) { return current; } const sourceIndex = current.layers.findIndex((layer) => layer.id === sourceLayerId); const destinationIndex = current.layers.findIndex((layer) => layer.id === targetLayerId); if (sourceIndex < 0 || destinationIndex < 0 || sourceIndex === destinationIndex) { return current; } return { ...current, layers: moveItem(current.layers, sourceIndex, destinationIndex), }; }); postJson("/api/layers/reorder", { layerId: sourceLayerId, targetIndex, }); setDragLayerId(null); setDropTargetLayerId(null); } return (

Layers

Drag layers to reorder them. Each layer processes the output of the one above it.

{layers.map((layer, index) => ( { setDragLayerId(null); setDropTargetLayerId(null); }} onDragOver={setDropTargetLayerId} onDrop={handleDrop} onRemove={removeLayer} onLayerParameterChange={updateLayerParameterOptimistically} /> ))}
+
Add Layer
); }