Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

323
Views
cropping image in svelte The first argument is required and must be an <img> or <canvas> element

I am struggling to get cropperjs to work in svelte. Any help would be appreciated.

The svelte script is as follows

<script>
import Cropper from 'cropperjs';

const image = document.getElementById('image');

const cropper = new Cropper(image, {
  aspectRatio: 16 / 9,
  crop(event) {
    console.log(event.detail.x);
    console.log(event.detail.y);
    console.log(event.detail.width);
    console.log(event.detail.height);
    console.log(event.detail.rotate);
    console.log(event.detail.scaleX);
    console.log(event.detail.scaleY);
  },
});


</script>
<img id="image" src="./images/favicon.png" alt="">

The error is:

Uncaught Error: The first argument is required and must be an <img> or <canvas> element.
    at new Cropper (cropper.js:3229:15)
    at instance$1 (Example5.svelte:8:14)
    at init (index.mjs:1809:11)
    at new Example5 (Example5.svelte:17:36)
    at create_fragment (Example5.svelte:17:36)
    at init (index.mjs:1824:37)
    at new App (Example5.svelte:17:36)
    at main.js:3:13
    at main.js:7:2
about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

There appears to be an issue using import Cropper from 'cropperjs'. Corrl supplied a work-around in a comment:

There seems to be a problem with import Cropper from 'cropperjs'; inside the REPL - when using <svelte:head> with script and stylesheet references to Cropper it looks better

Another problem is that the image hasn't completed loading by the time you pass the reference to Cropper. You could try using onMount instead which runs after the component is added to the dom. However, the image data hasn't always completed loading when onMount runs.

Another option is to bind to the onload event for the image. This answer to Svelte component onLoad shows the technique. However, you could simply call img.addEventListener('load', initCropper); within onMount which will initialize Cropper once the image has fully loaded.

<svelte:head>
    <link  href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/2.0.0-alpha.2/cropper.css" rel="stylesheet">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/2.0.0-alpha.2/cropper.min.js"></script>
</svelte:head>

<script>
    import { onMount } from 'svelte'

    let img, cropper;
    
    onMount(() => {
        // call initCropper when img is loaded   
        img.addEventListener('load', initCropper);
    });

    function initCropper() {
        cropper = new Cropper(img, {
            aspectRatio: 16 / 9,
            viewMode: 2,
            crop(event) {
                console.log(event.detail);
                console.log(event.detail.y);
                console.log(event.detail.width);
                console.log(event.detail.height);
                console.log(event.detail.rotate);
                console.log(event.detail.scaleX);
                console.log(event.detail.scaleY);
            },
        });     
    }
</script>

<div>
    <img {src} bind:this={img} />  
</div>

The code above works for me, you can see a demo here.


Alternative

There is a cropping library - svelte-easy-crop - which works with Svelte. The code below is taken from the demo:

<script>
  import Cropper from "svelte-easy-crop";

  let crop = { x: 0, y: 0 };
  let zoom = 1;
  let image = "https://cdn1-www.dogtime.com/assets/uploads/2011/03/puppy-development.jpg";
</script>

<Cropper {image} bind:crop bind:zoom />
about 4 years ago · Juan Pablo Isaza Report

0

yes the suggestion by Corrl was spot on. Adding the head elements sorted out the problem. Also the point by haldo, about using onMount is required as well.

about 4 years ago · Juan Pablo Isaza Report

0

An alternative to initializing Cropper inside onMount would be use:action > Docs > REPL

<svelte:head>
    <link  href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/2.0.0-alpha.2/cropper.css" rel="stylesheet">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/2.0.0-alpha.2/cropper.min.js"></script>
</svelte:head>

<script>
    let cropper;
    
    function initCropper(node){
        console.log('loaded', node.complete)
        cropper = new Cropper(node, {
            aspectRatio: 16 / 9,
            crop(event) {
                console.log(event.detail);
                console.log(event.detail.y);
                console.log(event.detail.width);
                console.log(event.detail.height);
                console.log(event.detail.rotate);
                console.log(event.detail.scaleX);
                console.log(event.detail.scaleY);
            },
        });     
    }
</script>

<div>
    <img use:initCropper src="https://cdn1-www.dogtime.com/assets/uploads/2011/03/puppy-development.jpg" alt="">
</div>

<style>
    img {
        display: block;
        max-width: 100%;
    }
</style>
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!