Getting Started
Install svelte-chop-chop and add image cropping to your Svelte 5 app in minutes.
Installation
npm install @we-are-singular/svelte-chop-chop Peer dependencies
Only Svelte 5 is required as a peer dependency:
peerDependencies:
svelte: "^5.0.0" Basic cropper
Import the Cropper component and pass it an image source. Use the toolbar snippet to add an export button. Export uses full resolution (original image pixels),
so large images export at their cropped region's actual dimensions.
Basic Cropper
No image loaded
<script lang="ts">
import { Cropper } from '@we-are-singular/svelte-chop-chop';
import '@we-are-singular/svelte-chop-chop/themes/default';
</script>
{#snippet cropToolbar(cropper)}
<button onclick={async () => {
const result = await cropper.export({ format: 'image/webp', quality: 0.9 });
if (result.blob) {
const url = URL.createObjectURL(result.blob);
const a = document.createElement('a');
a.href = url;
a.download = 'cropped.webp';
a.click();
}
}}>Crop</button>
{/snippet}
<Cropper src="/photo.jpg" aspectRatio={1} toolbar={cropToolbar} /> Full image editor
The ImageEditor component bundles crop, filters, finetune, rotate, resize, frame and watermark
panels:
Full ImageEditor with all plugins
No image loaded
<script lang="ts">
import { ImageEditor } from '@we-are-singular/svelte-chop-chop';
import { pluginFilters } from '@we-are-singular/svelte-chop-chop/plugins/filters';
import { pluginFinetune } from '@we-are-singular/svelte-chop-chop/plugins/finetune';
import { pluginFrame } from '@we-are-singular/svelte-chop-chop/plugins/frame';
import { pluginWatermark } from '@we-are-singular/svelte-chop-chop/plugins/watermark';
import { pluginResize } from '@we-are-singular/svelte-chop-chop/plugins/resize';
import '@we-are-singular/svelte-chop-chop/themes/default';
</script>
<ImageEditor
src="/photo.jpg"
plugins={[pluginFilters(), pluginFinetune(), pluginFrame(), pluginWatermark(), pluginResize()]}
onexport={(result) => console.log('exported', result.blob)}
/> Headless composable
Need full UI control? Use createCropper from the headless export. Bind the container and canvas via $effect :
<script lang="ts">
import { createCropper } from '@we-are-singular/svelte-chop-chop/headless';
const cropper = createCropper({
src: 'https://example.com/photo.jpg',
aspectRatio: 16 / 9,
});
let containerEl: HTMLElement | undefined;
let canvasEl: HTMLCanvasElement | undefined;
$effect(() => {
if (containerEl) cropper.bindContainer(containerEl);
if (canvasEl) cropper.bindCanvas(canvasEl);
return () => cropper.destroy();
});
</script>
<div bind:this={containerEl} class="my-container" style="height: 300px;">
<canvas bind:this={canvasEl}></canvas>
<!-- Render your own stencil using cropper.stencilProps -->
</div> See Cropper and Custom Stencil for details.
CSS themes
Three themes are included. Import exactly one:
import '@we-are-singular/svelte-chop-chop/themes/default'; // recommended
import '@we-are-singular/svelte-chop-chop/themes/dark';
import '@we-are-singular/svelte-chop-chop/themes/minimal';