inference-playground / src /lib /components /flow /actions /PanelCanvasActions.svelte
enzostvs's picture
enzostvs HF Staff
use better Dark theme
2d9278d
<script lang="ts">
import { tick } from 'svelte';
import { Camera, Maximize, Minus, Plus, Video, VideoOff } from '@lucide/svelte';
import { Panel } from '@xyflow/svelte';
import { Button } from '$lib/components/ui/button';
import { viewState } from '$lib/state/view.svelte';
import { useSvelteFlow } from '@xyflow/svelte';
import * as Tooltip from '$lib/components/ui/tooltip';
import { breakpointsState } from '$lib/state/breakpoints.svelte';
import { useNodes } from '@xyflow/svelte';
const { zoomIn, zoomOut, getZoom, fitView } = useSvelteFlow();
const nodesStore = useNodes();
function requestFitView() {
tick().then(() => {
requestAnimationFrame(() => {
const nodes = nodesStore.current;
if (nodes.length === 0) return;
fitView({
maxZoom: breakpointsState.isMobile ? 1 : 1.15,
minZoom: 0.7,
padding: breakpointsState.isMobile ? 0 : 0.15,
interpolate: 'smooth',
duration: 250,
nodes: nodes.map((n) => ({ id: n.id }))
});
});
});
}
function toggleDraggable() {
viewState.draggable = !viewState.draggable;
localStorage.setItem('draggable', viewState.draggable.toString());
}
</script>
<Panel
position="bottom-center"
class="flex items-center justify-start gap-2 p-1 max-lg:hidden lg:p-2"
>
<div
class="inline-flex w-fit flex-row gap-0.5 rounded-lg border border-border bg-background/30 p-1 text-primary backdrop-blur-sm"
>
<Button
variant="ghost"
size="icon-sm"
onclick={() => zoomIn({ duration: 200 })}
disabled={getZoom() >= 1.15}
>
<Plus />
</Button>
<Button
variant="ghost"
size="icon-sm"
onclick={() => zoomOut({ duration: 200 })}
disabled={getZoom() <= 0.7}
>
<Minus />
</Button>
<Button variant="ghost" size="icon-sm" onclick={requestFitView}>
<Maximize />
</Button>
<Tooltip.Root delayDuration={0}>
<Tooltip.Trigger>
<Button
variant={viewState.draggable ? 'default' : 'ghost'}
size="icon-sm"
onclick={toggleDraggable}
>
{#if viewState.draggable}
<Video />
{:else}
<VideoOff />
{/if}
</Button>
</Tooltip.Trigger>
<Tooltip.Content class="flex items-center gap-2">
{#if viewState.draggable}
<Camera class="size-3" />
Focus camera on scene
{:else}
<VideoOff class="size-3" />
Free camera movement
{/if}
</Tooltip.Content>
</Tooltip.Root>
</div>
</Panel>