Eraser
This example shows how to create an eraser tool that allows you to delete nodes and edges by wiping them out. It’s made up of two parts:
- The 
Erasercomponent that handles the erasing logic and rendering of the eraser trail. - The custom 
ErasableNodeandErasableEdgethat reacts to thetoBeDeletedflag. 
Determining if the trail intersects with a node is fairly straight forward - however detecting intersections between the trail and an edge is a bit more complex:
We sample points along the edge through the getPointAtLength method of the SVG path element,
construct a polyline that we can then use to detect intersections with the eraser trail.
This is a trade-off between performance and accuracy - you can play around with the sampleDistance variable to see the effect it has on the eraser trail.
<script lang="ts">
  import { SvelteFlow, Background, Controls, Panel } from '@xyflow/svelte';
 
  import ErasableNode, { type ErasableNodeType } from './ErasableNode.svelte';
  import ErasableEdge, { type ErasableEdgeType } from './ErasableEdge.svelte';
  import Eraser from './Eraser.svelte';
 
  import '@xyflow/svelte/dist/style.css';
 
  const initialNodes: ErasableNodeType[] = [
    {
      id: '1',
      type: 'erasable-node',
      position: { x: 0, y: 0 },
      data: { label: 'Hello' },
    },
    {
      id: '2',
      type: 'erasable-node',
      position: { x: 300, y: 0 },
      data: { label: 'World' },
    },
  ];
 
  const initialEdges: ErasableEdgeType[] = [
    {
      id: '1->2',
      type: 'erasable-edge',
      source: '1',
      target: '2',
      data: {},
    },
  ];
 
  const nodeTypes = {
    'erasable-node': ErasableNode,
  };
 
  const edgeTypes = {
    'erasable-edge': ErasableEdge,
  };
 
  let nodes = $state.raw(initialNodes);
  let edges = $state.raw(initialEdges);
 
  let isEraserActive = $state(true);
</script>
 
<SvelteFlow
  bind:nodes
  bind:edges
  {nodeTypes}
  {edgeTypes}
  fitView
  defaultEdgeOptions={{ type: 'erasable-edge' }}
>
  <Controls />
  <Background />
 
  {#if isEraserActive}
    <Eraser />
  {/if}
 
  <Panel position="top-left" class="controls">
    <div class="xy-theme__button-group">
      <button
        class={['xy-theme__button', isEraserActive && 'active']}
        onclick={() => {
          isEraserActive = true;
        }}
      >
        Eraser Mode
      </button>
      <button
        class={['xy-theme__button', !isEraserActive && 'active']}
        onclick={() => {
          isEraserActive = false;
        }}
      >
        Selection Mode
      </button>
    </div>
  </Panel>
</SvelteFlow>
 
<style>
  :global .controls {
    z-index: 1001;
  }
</style>Last updated on