konvajs / konva

Konva.js is an HTML5 Canvas JavaScript framework that extends the 2d context by enabling canvas interactivity for desktop and mobile applications.
http://konvajs.org/
Other
11.43k stars 918 forks source link

Different scaling behavior on SVGs in different browsers #1753

Closed danielL22 closed 5 months ago

danielL22 commented 5 months ago

Hello everyone,

I am currently working on an image editor with konva and I noticed different behaviour in scaling in firefox and chrome. In this editor we are working with SVG files so a height and witdth MUST be set or else the image does not load in firefox! As I understand, this leads in chrome to stretch the images to the full height and width while firefox tries to keep its ratio (see images for examples). Is there a way to make konva handle the image in Firefox like it handles the image in chrome? So scaling on one axis results in stretching the image, like in every image-editing-software?

Chrome: chrome Firefox: firefox

The code I use (I tried the jsbin-template but it did not load the image there)

const stage = new Konva.Stage({
    container: 'previewContainer',
    width: 500,
    height: 500,
});
const layer = new Konva.Layer();
stage.add(layer);

let imageObj = new Image();

imageObj.onload = function () {
    var element = new Konva.Image({
        x: 50,
        y: 50,
        image: imageObj,
        width: imageWidth, //imageWidth and imageHeight varibales come from another function, that calculates the real size of the svg, not relevant here
        height: imageHeight,
        scaleX: 0.1,
        scaleY: 0.1,
        draggable: true,
    });

    layer.add(element);

    let transformer = new Konva.Transformer({
        nodes: [element],
        rotationSnaps: [0, 90, 180, 270],
    });
    layer.add(transformer);
};
imageObj.src = originalPath;
lavrton commented 5 months ago

In https://polotno.com/, I am doing this workaround:

  1. Load SVG
  2. Create an external canvas element with the size of the SVG (or bigger, if better quality is required)
  3. Draw SVG into that canvas
  4. Use canvas for Konva.Image
imageObj.onload = function () {
    // Create an offscreen canvas
    const offscreenCanvas = document.createElement('canvas');
    offscreenCanvas.width = imageWidth;  // Set width of the SVG
    offscreenCanvas.height = imageHeight; // Set height of the SVG

    // Draw the SVG on the offscreen canvas
    const ctx = offscreenCanvas.getContext('2d');
    ctx.drawImage(imageObj, 0, 0, imageWidth, imageHeight);

    // Now use the canvas as the image for Konva.Image
    var konvaImage = new Konva.Image({
        x: 50,
        y: 50,
        image: offscreenCanvas,
        width: imageWidth,
        height: imageHeight,
        scaleX: 0.1,
        scaleY: 0.1,
        draggable: true
    });

    layer.add(konvaImage);
};