refector viewport to use signals
This commit is contained in:
@@ -27,7 +27,7 @@
|
||||
let id = 1;
|
||||
const getId = () => `${id++}`;
|
||||
|
||||
const { screenToFlowPosition, flowToScreenPosition } = useSvelteFlow();
|
||||
const { screenToFlowPosition, flowToScreenPosition } = $derived(useSvelteFlow());
|
||||
|
||||
const handleConnectEnd: OnConnectEnd = (event) => {
|
||||
if (!connectingNodeId) return;
|
||||
|
||||
@@ -25,8 +25,7 @@ export default function drag(domNode: Element, params: UseDragParams) {
|
||||
onDragStop,
|
||||
onNodeMouseDown,
|
||||
getStoreItems: () => {
|
||||
const snapGrid = store.snapGrid;
|
||||
const vp = get(store.viewport);
|
||||
const { snapGrid, viewport } = store;
|
||||
|
||||
return {
|
||||
nodes: get(store.nodes),
|
||||
@@ -38,7 +37,7 @@ export default function drag(domNode: Element, params: UseDragParams) {
|
||||
nodeOrigin: store.nodeOrigin,
|
||||
multiSelectionActive: store.multiselectionKeyPressed,
|
||||
domNode: store.domNode,
|
||||
transform: [vp.x, vp.y, vp.zoom],
|
||||
transform: [viewport.x, viewport.y, viewport.zoom],
|
||||
autoPanOnNodeDrag: store.autoPanOnNodeDrag,
|
||||
nodesDraggable: store.nodesDraggable,
|
||||
selectNodesOnDrag: store.selectNodesOnDrag,
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import type { Writable } from 'svelte/store';
|
||||
import {
|
||||
PanOnScrollMode,
|
||||
XYPanZoom,
|
||||
@@ -10,7 +9,7 @@ import {
|
||||
} from '@xyflow/system';
|
||||
|
||||
type ZoomParams = {
|
||||
viewport: Writable<Viewport>;
|
||||
viewport: Viewport;
|
||||
initialViewport: Viewport;
|
||||
minZoom: number;
|
||||
maxZoom: number;
|
||||
@@ -45,11 +44,11 @@ export default function zoom(domNode: Element, params: ZoomParams) {
|
||||
minZoom,
|
||||
maxZoom,
|
||||
initialViewport,
|
||||
viewport,
|
||||
translateExtent,
|
||||
paneClickDistance,
|
||||
setPanZoomInstance,
|
||||
onDraggingChange
|
||||
onDraggingChange,
|
||||
onTransformChange
|
||||
} = params;
|
||||
|
||||
const panZoomInstance = XYPanZoom({
|
||||
@@ -61,8 +60,17 @@ export default function zoom(domNode: Element, params: ZoomParams) {
|
||||
paneClickDistance,
|
||||
onDraggingChange
|
||||
});
|
||||
const currentViewport = panZoomInstance.getViewport();
|
||||
viewport.set(currentViewport);
|
||||
|
||||
//TODO: is this neccessary?
|
||||
const viewport = panZoomInstance.getViewport();
|
||||
if (
|
||||
initialViewport.x !== viewport.x ||
|
||||
initialViewport.y !== viewport.y ||
|
||||
initialViewport.zoom !== viewport.zoom
|
||||
) {
|
||||
onTransformChange([viewport.x, viewport.y, viewport.zoom]);
|
||||
}
|
||||
|
||||
setPanZoomInstance(panZoomInstance);
|
||||
|
||||
panZoomInstance.update(params);
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
);
|
||||
|
||||
let store = useStore();
|
||||
let { viewport, edges } = store;
|
||||
let { edges } = store;
|
||||
|
||||
function onPointerDown(event: MouseEvent | TouchEvent) {
|
||||
const isMouseTriggered = isMouseEvent(event);
|
||||
@@ -81,7 +81,7 @@
|
||||
onConnectEnd: (event, connectionState) => {
|
||||
store.onconnectend?.(event, connectionState);
|
||||
},
|
||||
getTransform: () => [$viewport.x, $viewport.y, $viewport.zoom],
|
||||
getTransform: () => [store.viewport.x, store.viewport.y, store.viewport.zoom],
|
||||
getFromHandle: () => store.connection.fromHandle
|
||||
});
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
children
|
||||
}: PaneProps = $props();
|
||||
|
||||
const { viewport, nodes, edges } = store;
|
||||
const { nodes, edges } = store;
|
||||
|
||||
// svelte-ignore non_reactive_update
|
||||
let container: HTMLDivElement;
|
||||
@@ -131,7 +131,7 @@
|
||||
selectedNodes = getNodesInside(
|
||||
store.nodeLookup,
|
||||
nextUserSelectRect,
|
||||
[$viewport.x, $viewport.y, $viewport.zoom],
|
||||
[store.viewport.x, store.viewport.y, store.viewport.zoom],
|
||||
store.selectionMode === SelectionMode.Partial,
|
||||
true
|
||||
);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<script lang="ts">
|
||||
import { get } from 'svelte/store';
|
||||
import { onMount, getContext, setContext } from 'svelte';
|
||||
import cc from 'classcat';
|
||||
import { PanOnScrollMode } from '@xyflow/system';
|
||||
@@ -79,12 +78,9 @@
|
||||
props,
|
||||
container
|
||||
});
|
||||
const { viewport } = store;
|
||||
const initialViewport = props.initialViewport ?? get(viewport);
|
||||
|
||||
store.syncNodeStores(props.nodes);
|
||||
store.syncEdgeStores(props.edges);
|
||||
store.syncViewport(props.viewport);
|
||||
|
||||
const providerContext = getContext<ProviderContext>(key);
|
||||
if (providerContext) {
|
||||
@@ -128,7 +124,6 @@
|
||||
/>
|
||||
<Zoom
|
||||
{store}
|
||||
{initialViewport}
|
||||
{onMoveStart}
|
||||
{onMove}
|
||||
{onMoveEnd}
|
||||
@@ -142,7 +137,7 @@
|
||||
{paneClickDistance}
|
||||
>
|
||||
<Pane {store} {onpaneclick} {onpanecontextmenu} {panOnDrag} {selectionOnDrag}>
|
||||
<ViewportComponent viewport={$viewport}>
|
||||
<ViewportComponent {store}>
|
||||
<EdgeRenderer
|
||||
{store}
|
||||
{onedgeclick}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
<script lang="ts">
|
||||
import type { Viewport } from '@xyflow/system';
|
||||
import type { SvelteFlowStore } from '$lib/store/types';
|
||||
import type { Snippet } from 'svelte';
|
||||
|
||||
let { viewport, children }: { viewport: Viewport; children: Snippet } = $props();
|
||||
let { store, children }: { store: SvelteFlowStore; children: Snippet } = $props();
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="svelte-flow__viewport xyflow__viewport"
|
||||
style="transform: translate({viewport.x}px, {viewport.y}px) scale({viewport.zoom})"
|
||||
style="transform: translate({store.viewport.x}px, {store.viewport.y}px) scale({store.viewport
|
||||
.zoom})"
|
||||
>
|
||||
{@render children()}
|
||||
</div>
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
let {
|
||||
store,
|
||||
initialViewport = { x: 0, y: 0, zoom: 1 },
|
||||
onMoveStart,
|
||||
onMove,
|
||||
onMoveEnd,
|
||||
@@ -27,7 +26,10 @@
|
||||
let panOnScrollActive = $derived(store.panActivationKeyPressed || panOnScroll);
|
||||
|
||||
const onTransformChange = (transform: Transform) =>
|
||||
store.viewport.set({ x: transform[0], y: transform[1], zoom: transform[2] });
|
||||
(store.viewport = { x: transform[0], y: transform[1], zoom: transform[2] });
|
||||
|
||||
// We extract the initial value by destructuring
|
||||
const { viewport: initialViewport } = store;
|
||||
|
||||
onMount(() => {
|
||||
store.viewportInitialized = true;
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import type { SvelteFlowStore } from '$lib/store/types';
|
||||
import type { OnMoveStart, OnMove, OnMoveEnd, PanOnScrollMode, Viewport } from '@xyflow/system';
|
||||
import type { OnMoveStart, OnMove, OnMoveEnd, PanOnScrollMode } from '@xyflow/system';
|
||||
import type { Snippet } from 'svelte';
|
||||
|
||||
export type ZoomProps = {
|
||||
store: SvelteFlowStore;
|
||||
initialViewport?: Viewport;
|
||||
panOnScrollMode: PanOnScrollMode;
|
||||
onMove?: OnMove;
|
||||
onMoveStart?: OnMoveStart;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { get, type Writable } from 'svelte/store';
|
||||
import { get } from 'svelte/store';
|
||||
import {
|
||||
getOverlappingArea,
|
||||
isRectObject,
|
||||
@@ -197,7 +197,6 @@ export function useSvelteFlow(): {
|
||||
* const clientPosition = flowToScreenPosition({ x: node.position.x, y: node.position.y })
|
||||
*/
|
||||
flowToScreenPosition: (flowPosition: XYPosition) => XYPosition;
|
||||
viewport: Writable<Viewport>;
|
||||
/**
|
||||
* Updates a node.
|
||||
*
|
||||
@@ -279,7 +278,7 @@ export function useSvelteFlow(): {
|
||||
}
|
||||
|
||||
const store = useStore();
|
||||
const { viewport, nodes, edges } = store;
|
||||
const { nodes, edges } = store;
|
||||
|
||||
const getNodeRect = (node: Node | { id: Node['id'] }): Rect | null => {
|
||||
const nodeToUse = isNode(node) ? node : store.nodeLookup.get(node.id)!;
|
||||
@@ -378,9 +377,9 @@ export function useSvelteFlow(): {
|
||||
? panZoom.scaleTo(zoomLevel, { duration: options?.duration })
|
||||
: Promise.resolve(false);
|
||||
},
|
||||
getZoom: () => get(viewport).zoom,
|
||||
getZoom: () => store.viewport.zoom,
|
||||
setViewport: async (nextViewport, options) => {
|
||||
const currentViewport = get(viewport);
|
||||
const currentViewport = store.viewport;
|
||||
|
||||
if (!store.panZoom) {
|
||||
return Promise.resolve(false);
|
||||
@@ -397,7 +396,7 @@ export function useSvelteFlow(): {
|
||||
|
||||
return Promise.resolve(true);
|
||||
},
|
||||
getViewport: () => get(viewport),
|
||||
getViewport: () => store.viewport,
|
||||
setCenter: async (x, y, options) => {
|
||||
const nextZoom = typeof options?.zoom !== 'undefined' ? options.zoom : store.maxZoom;
|
||||
const currentPanZoom = store.panZoom;
|
||||
@@ -513,7 +512,7 @@ export function useSvelteFlow(): {
|
||||
}
|
||||
|
||||
const _snapGrid = options.snapToGrid ? store.snapGrid : false;
|
||||
const { x, y, zoom } = get(viewport);
|
||||
const { x, y, zoom } = store.viewport;
|
||||
const { x: domX, y: domY } = store.domNode.getBoundingClientRect();
|
||||
const correctedPosition = {
|
||||
x: position.x - domX,
|
||||
@@ -537,7 +536,7 @@ export function useSvelteFlow(): {
|
||||
return position;
|
||||
}
|
||||
|
||||
const { x, y, zoom } = get(viewport);
|
||||
const { x, y, zoom } = store.viewport;
|
||||
const { x: domX, y: domY } = store.domNode.getBoundingClientRect();
|
||||
const rendererPosition = rendererPointToPoint(position, [x, y, zoom]);
|
||||
|
||||
@@ -557,7 +556,7 @@ export function useSvelteFlow(): {
|
||||
data: { ...node.data }
|
||||
})),
|
||||
edges: get(edges).map((edge) => ({ ...edge })),
|
||||
viewport: { ...get(viewport) }
|
||||
viewport: { ...store.viewport }
|
||||
};
|
||||
},
|
||||
updateNode,
|
||||
@@ -579,8 +578,7 @@ export function useSvelteFlow(): {
|
||||
return getNodesBounds(nodes, { nodeLookup: store.nodeLookup, nodeOrigin: store.nodeOrigin });
|
||||
},
|
||||
getHandleConnections: ({ type, id, nodeId }) =>
|
||||
Array.from(store.connectionLookup.get(`${nodeId}-${type}-${id ?? null}`)?.values() ?? []),
|
||||
viewport
|
||||
Array.from(store.connectionLookup.get(`${nodeId}-${type}-${id ?? null}`)?.values() ?? [])
|
||||
};
|
||||
}
|
||||
function getElements(lookup: Map<string, InternalNode>, ids: string[]): Node[];
|
||||
|
||||
@@ -28,9 +28,6 @@
|
||||
}: BackgroundProps = $props();
|
||||
|
||||
const store = useStore();
|
||||
const { viewport } = store;
|
||||
|
||||
$inspect($viewport);
|
||||
|
||||
const patternSize = size ?? defaultSize[variant!];
|
||||
const isDots = variant === BackgroundVariant.Dots;
|
||||
@@ -38,8 +35,11 @@
|
||||
const gapXY: number[] = Array.isArray(gap!) ? gap! : [gap!, gap!];
|
||||
|
||||
let patternId = $derived(`background-pattern-${store.flowId}-${id ?? ''}`);
|
||||
let scaledGap = $derived([gapXY[0] * $viewport.zoom || 1, gapXY[1] * $viewport.zoom || 1]);
|
||||
let scaledSize = $derived(patternSize * $viewport.zoom);
|
||||
let scaledGap = $derived([
|
||||
gapXY[0] * store.viewport.zoom || 1,
|
||||
gapXY[1] * store.viewport.zoom || 1
|
||||
]);
|
||||
let scaledSize = $derived(patternSize * store.viewport.zoom);
|
||||
let patternDimensions = $derived(
|
||||
(isCross ? [scaledSize, scaledSize] : scaledGap) as [number, number]
|
||||
);
|
||||
@@ -56,8 +56,8 @@
|
||||
>
|
||||
<pattern
|
||||
id={patternId}
|
||||
x={$viewport.x % scaledGap[0]}
|
||||
y={$viewport.y % scaledGap[1]}
|
||||
x={store.viewport.x % scaledGap[0]}
|
||||
y={store.viewport.y % scaledGap[1]}
|
||||
width={scaledGap[0]}
|
||||
height={scaledGap[1]}
|
||||
patternUnits="userSpaceOnUse"
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
}: ControlsProps = $props();
|
||||
|
||||
const store = useStore();
|
||||
const { viewport } = store;
|
||||
|
||||
const buttonProps = {
|
||||
bgColor: buttonBgColor,
|
||||
@@ -46,8 +45,8 @@
|
||||
let isInteractive = $state(
|
||||
store.nodesDraggable || store.nodesConnectable || store.elementsSelectable
|
||||
);
|
||||
let minZoomReached = $derived($viewport.zoom <= store.minZoom);
|
||||
let maxZoomReached = $derived($viewport.zoom >= store.maxZoom);
|
||||
let minZoomReached = $derived(store.viewport.zoom <= store.minZoom);
|
||||
let maxZoomReached = $derived(store.viewport.zoom >= store.maxZoom);
|
||||
let orientationClass = $derived(orientation === 'horizontal' ? 'horizontal' : 'vertical');
|
||||
|
||||
const onZoomInHandler = () => {
|
||||
|
||||
@@ -43,7 +43,6 @@
|
||||
}: MiniMapProps = $props();
|
||||
|
||||
let store = useStore();
|
||||
const { viewport } = store;
|
||||
|
||||
let nodes = $derived(store.nodes);
|
||||
|
||||
@@ -58,10 +57,10 @@
|
||||
|
||||
// TODO: simplify this
|
||||
let viewBB = $derived({
|
||||
x: -$viewport.x / $viewport.zoom,
|
||||
y: -$viewport.y / $viewport.zoom,
|
||||
width: store.width / $viewport.zoom,
|
||||
height: store.height / $viewport.zoom
|
||||
x: -store.viewport.x / store.viewport.zoom,
|
||||
y: -store.viewport.y / store.viewport.zoom,
|
||||
width: store.width / store.viewport.zoom,
|
||||
height: store.height / store.viewport.zoom
|
||||
});
|
||||
let boundingRect = $derived(
|
||||
store.nodeLookup.size > 0
|
||||
@@ -102,8 +101,8 @@
|
||||
? maskStrokeWidth * viewScale
|
||||
: undefined}
|
||||
use:interactive={{
|
||||
store,
|
||||
panZoom: store.panZoom,
|
||||
viewport: store.viewport,
|
||||
getViewScale,
|
||||
translateExtent: store.translateExtent,
|
||||
width: store.width,
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
import { get, type Writable } from 'svelte/store';
|
||||
import {
|
||||
XYMinimap,
|
||||
type PanZoomInstance,
|
||||
type Viewport,
|
||||
type XYMinimapUpdate
|
||||
} from '@xyflow/system';
|
||||
import { XYMinimap, type PanZoomInstance, type XYMinimapUpdate } from '@xyflow/system';
|
||||
import type { SvelteFlowStore } from '$lib/store/types';
|
||||
|
||||
export type UseInteractiveParams = {
|
||||
panZoom: PanZoomInstance;
|
||||
viewport: Writable<Viewport>;
|
||||
store: SvelteFlowStore;
|
||||
getViewScale: () => number;
|
||||
} & XYMinimapUpdate;
|
||||
|
||||
@@ -17,7 +12,7 @@ export default function interactive(domNode: Element, params: UseInteractivePara
|
||||
domNode,
|
||||
panZoom: params.panZoom,
|
||||
getTransform: () => {
|
||||
const viewport = get(params.viewport);
|
||||
const { viewport } = params.store;
|
||||
return [viewport.x, viewport.y, viewport.zoom];
|
||||
},
|
||||
getViewScale: params.getViewScale
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
type XYResizerChildChange
|
||||
} from '@xyflow/system';
|
||||
import type { ResizeControlProps } from './types';
|
||||
import { get } from 'svelte/store';
|
||||
|
||||
let {
|
||||
nodeId,
|
||||
@@ -31,7 +32,7 @@
|
||||
children
|
||||
}: ResizeControlProps = $props();
|
||||
|
||||
const { nodeLookup, snapGrid, viewport, nodes, nodeOrigin, domNode } = useStore();
|
||||
const store = useStore();
|
||||
|
||||
let id = $derived(
|
||||
typeof nodeId === 'string' ? nodeId : getContext<string>('svelteflow__node_id')
|
||||
@@ -62,16 +63,16 @@
|
||||
nodeId: id,
|
||||
getStoreItems: () => {
|
||||
return {
|
||||
nodeLookup: $nodeLookup,
|
||||
transform: [$viewport.x, $viewport.y, $viewport.zoom],
|
||||
snapGrid: $snapGrid ?? undefined,
|
||||
snapToGrid: !!$snapGrid,
|
||||
nodeOrigin: $nodeOrigin,
|
||||
paneDomNode: $domNode
|
||||
nodeLookup: store.nodeLookup,
|
||||
transform: [store.viewport.x, store.viewport.y, store.viewport.zoom],
|
||||
snapGrid: store.snapGrid ?? undefined,
|
||||
snapToGrid: !!store.snapGrid,
|
||||
nodeOrigin: store.nodeOrigin,
|
||||
paneDomNode: store.domNode
|
||||
};
|
||||
},
|
||||
onChange: (change: XYResizerChange, childChanges: XYResizerChildChange[]) => {
|
||||
const node = $nodeLookup.get(id)?.internals.userNode;
|
||||
const node = store.nodeLookup.get(id)?.internals.userNode;
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
@@ -86,13 +87,13 @@
|
||||
}
|
||||
|
||||
for (const childChange of childChanges) {
|
||||
const childNode = $nodeLookup.get(childChange.id)?.internals.userNode;
|
||||
const childNode = store.nodeLookup.get(childChange.id)?.internals.userNode;
|
||||
if (childNode) {
|
||||
childNode.position = childChange.position;
|
||||
}
|
||||
}
|
||||
|
||||
$nodes = $nodes;
|
||||
store.nodes.set(get(store.nodes));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
children
|
||||
}: NodeToolbarProps = $props();
|
||||
|
||||
const { domNode, viewport, nodeLookup, nodes } = useStore();
|
||||
const store = useStore();
|
||||
const { nodes } = store;
|
||||
const { getNodesBounds } = useSvelteFlow();
|
||||
const contextNodeId = getContext<string>('svelteflow__node_id');
|
||||
|
||||
@@ -28,7 +29,7 @@
|
||||
const nodeIds = Array.isArray(nodeId) ? nodeId : [nodeId ?? contextNodeId];
|
||||
|
||||
return nodeIds.reduce<InternalNode[]>((res, nodeId) => {
|
||||
const node = $nodeLookup.get(nodeId);
|
||||
const node = store.nodeLookup.get(nodeId);
|
||||
|
||||
if (node) {
|
||||
res.push(node);
|
||||
@@ -41,7 +42,7 @@
|
||||
let transform: string = $derived.by(() => {
|
||||
const nodeRect = getNodesBounds(toolbarNodes);
|
||||
if (nodeRect) {
|
||||
return getNodeToolbarTransform(nodeRect, $viewport, position, offset, align);
|
||||
return getNodeToolbarTransform(nodeRect, store.viewport, position, offset, align);
|
||||
}
|
||||
return '';
|
||||
});
|
||||
@@ -63,11 +64,11 @@
|
||||
);
|
||||
</script>
|
||||
|
||||
{#if $domNode && isActive && toolbarNodes}
|
||||
{#if store.domNode && isActive && toolbarNodes}
|
||||
<div
|
||||
data-id={toolbarNodes.reduce((acc, node) => `${acc}${node.id} `, '').trim()}
|
||||
class="svelte-flow__node-toolbar"
|
||||
use:portal={{ domNode: $domNode }}
|
||||
use:portal={{ domNode: store.domNode }}
|
||||
style:position="absolute"
|
||||
style:transform
|
||||
style:z-index={zIndex}
|
||||
|
||||
@@ -22,7 +22,7 @@ import {
|
||||
import type { EdgeTypes, NodeTypes, Node, Edge, FitViewOptions } from '$lib/types';
|
||||
import { initialEdgeTypes, initialNodeTypes, getInitialStore } from './initial-store.svelte';
|
||||
import { type StoreSignals, type SvelteFlowStore, type SvelteFlowStoreActions } from './types';
|
||||
import { syncNodeStores, syncEdgeStores, syncViewportStores } from './utils';
|
||||
import { syncNodeStores, syncEdgeStores } from './utils';
|
||||
// import { getVisibleEdges } from './visible-edges';
|
||||
// import { getVisibleNodes } from './visible-nodes';
|
||||
|
||||
@@ -314,11 +314,10 @@ export function createStore(signals: StoreSignals): SvelteFlowStore {
|
||||
}
|
||||
|
||||
function panBy(delta: XYPosition) {
|
||||
const viewport = get(store.viewport);
|
||||
return panBySystem({
|
||||
delta,
|
||||
panZoom: store.panZoom,
|
||||
transform: [viewport.x, viewport.y, viewport.zoom],
|
||||
transform: [store.viewport.x, store.viewport.y, store.viewport.zoom],
|
||||
translateExtent: store.translateExtent,
|
||||
width: store.width,
|
||||
height: store.height
|
||||
@@ -346,7 +345,7 @@ export function createStore(signals: StoreSignals): SvelteFlowStore {
|
||||
const storeWithActions = Object.assign(store, {
|
||||
syncNodeStores: (nodes) => syncNodeStores(store.nodes, nodes),
|
||||
syncEdgeStores: (edges) => syncEdgeStores(store.edges, edges),
|
||||
syncViewport: (viewport) => syncViewportStores(store.panZoom, store.viewport, viewport),
|
||||
// syncViewport: (viewport) => syncViewportStores(store.panZoom, store.viewport, viewport),
|
||||
setNodeTypes,
|
||||
setEdgeTypes,
|
||||
addEdge,
|
||||
|
||||
@@ -118,9 +118,7 @@ export const getInitialStore = (signals: StoreSignals) => {
|
||||
nodeTypes: NodeTypes = $derived({ ...initialNodeTypes, ...signals.props.nodeTypes });
|
||||
edgeTypes: EdgeTypes = $derived({ ...initialEdgeTypes, ...signals.props.edgeTypes });
|
||||
|
||||
viewport: Writable<Viewport> = writable(
|
||||
signals.props.initialViewport ?? { x: 0, y: 0, zoom: 1 }
|
||||
);
|
||||
viewport: Viewport = $state(signals.props.initialViewport ?? { x: 0, y: 0, zoom: 1 });
|
||||
|
||||
connectionMode: ConnectionMode = $derived(
|
||||
signals.props.connectionMode ?? ConnectionMode.Strict
|
||||
@@ -128,10 +126,13 @@ export const getInitialStore = (signals: StoreSignals) => {
|
||||
rawConnection: ConnectionState = $state(initialConnection);
|
||||
connection: ConnectionState = $derived.by(() => {
|
||||
if (this.rawConnection.inProgress) {
|
||||
const viewport = get(this.viewport);
|
||||
return {
|
||||
...this.rawConnection,
|
||||
to: pointToRendererPoint(this.rawConnection.to, [viewport.x, viewport.y, viewport.zoom])
|
||||
to: pointToRendererPoint(this.rawConnection.to, [
|
||||
this.viewport.x,
|
||||
this.viewport.y,
|
||||
this.viewport.zoom
|
||||
])
|
||||
};
|
||||
} else {
|
||||
return { ...this.rawConnection };
|
||||
@@ -210,12 +211,12 @@ export const getInitialStore = (signals: StoreSignals) => {
|
||||
this.edges = createEdgesStore(edges, this.connectionLookup, this.edgeLookup);
|
||||
updateConnectionLookup(this.connectionLookup, this.edgeLookup, edges);
|
||||
|
||||
if (signals.props.fitView && this.width && this.height) {
|
||||
if (signals.props.fitView && !signals.props.initialViewport && this.width && this.height) {
|
||||
const bounds = getInternalNodesBounds(this.nodeLookup, {
|
||||
filter: (node) =>
|
||||
!!((node.width || node.initialWidth) && (node.height || node.initialHeight))
|
||||
});
|
||||
this.viewport.set(getViewportForBounds(bounds, this.width, this.height, 0.5, 2, 0.1));
|
||||
this.viewport = getViewportForBounds(bounds, this.width, this.height, 0.5, 2, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ import type { SvelteFlowProps } from '$lib/container/SvelteFlow';
|
||||
export type SvelteFlowStoreActions = {
|
||||
syncNodeStores: (nodesStore: Writable<Node[]>) => void;
|
||||
syncEdgeStores: (edgeStore: Writable<Edge[]>) => void;
|
||||
syncViewport: (viewportStore?: Writable<Viewport>) => void;
|
||||
// syncViewport: (viewportStore?: Writable<Viewport>) => void;
|
||||
setNodeTypes: (nodeTypes: NodeTypes) => void;
|
||||
setEdgeTypes: (edgeTypes: EdgeTypes) => void;
|
||||
addEdge: (edge: Edge | Connection) => void;
|
||||
|
||||
Reference in New Issue
Block a user