0
votes

I allow the user to upload an image to the canvas; when creating the Konvas.Image I set the height and width attributes based on the images naturalHeight and naturalWidth.

Upload Code:

function loadImageStep1(src) {        
    var imgKI = new Konva.Image({
        x: 0,
        y: 0,
        name: 'step1-label',
        id: 'step1-label'
    });

    layer1.add(imgKI);
    stage.add(layer1);//Add layer to stage.

    var layer1Img = stage.find('.step1-label');
    var reader = new FileReader();
    reader.onload = function(event) {
        img = new Image();
        img.onload = function() {
            imgKI.image(img);
            layer1.draw();
            layer1Img.setAttr('width', this.naturalWidth);
            layer1Img.setAttr('height', this.naturalHeight);                 
            layer1.draw();
        }
        img.src = event.target.result;//event.target.result
        layer1Img.setAttr('src', event.target.result);        
    }
    reader.readAsDataURL(src);

    return false;
}

When I save the canvas to a JSON string the image height and width is gone. I saved the Konva.Image object to a variable and added to the console log to verify that the attributes are present. Screen Shot of Console Log

Here is the JSON string provided by the stage.toJSON() function; please note that the height and width for the "step1-label" image object is not present.

{"attrs":{"width":500,"height":667,"id":"label-maker","fill":"#ddd"},"className":"Stage","children":[{"attrs":{"id":"background","name":"background"},"className":"Layer","children":[{"attrs":{"width":500,"height":667,"fill":"#ffffff"},"className":"Rect"}]},{"attrs":{"id":"layer1","name":"layer1"},"className":"Layer","children":[{"attrs":{"x":100,"y":180,"name":"step1-label","id":"step1-label","src":"[REMOVED TO MAKE STRING SMALLER]","scaleX":"1.72","scaleY":"1.72"},"className":"Image"}]},{"attrs":{"id":"layer3","name":"layer3"},"className":"Layer","children":[{"attrs":{"id":"txtGroup1","name":"txtGroup1","draggable":true,"x":-5,"y":202},"className":"Group","children":[{"attrs":{"x":250,"y":333.5,"text":"Fine Dinning \nSpecial Preserve","fontSize":"50","fontFamily":"Great Vibes","fill":"#000000","name":"text1","id":"text1","align":"center","lineHeight":"1","fontStyle":"bold","offsetX":203.81988525390625},"className":"Text"}]}]}]}

Here is my work around for this issue. I had to get the image objects and add in the height and width to the JSON string. This is simple because we only allow two images to be added to the canvas.

function saveLabel($title, $continue) {
    //Get current width, height and scale settings for the canvas. Use these values to reset once the canvas has beeen saved.
    var currentWidth = stage.width();
    var currentHeight = stage.height();
    var currentXScale = stage.scaleX();
    var currentYScale = stage.scaleY();
    stage.setWidth(width);
    stage.setHeight(height);
    stage.scale({ x: 1, y: 1 });
    stage.draw();
    var $json = stage.toJSON();
    //The Konvas library is dropping the height and width of the images when creating the json string, so we have to put them back in...   
    var layer1Img = stage.find('.step1-label');
    var layer2Img = stage.find('.custom');
    if (layer1Img.length) {
        $json = $json.replace('"id":"step1-label"','"id":"step1-label","height":' + layer1Img[0]["attrs"].height + ',"width":' + layer1Img[0]["attrs"].width);
    }
    if (layer2Img.length) {
        $json = $json.replace('"id":"custom"','"id":"custom","height":' + layer2Img[0]["attrs"].height + ',"width":' + layer2Img[0]["attrs"].width);
    }    
    var $dataURL = stage.toDataURL('image/png');   

    //Set the canvas back to original settings now that it's been saved.
    stage.setWidth(currentWidth);
    stage.setHeight(currentHeight);
    stage.scale({ x: currentXScale, y: currentYScale });
    stage.draw();

    saveLabelAjax($json, $dataURL, $title, $continue, label_maker, window.location.hash);
}

Is there something I'm missing in my code; am I setting the image attributes correctly?

I need the image height and width for a rotation function and when I load the canvas from the JSON the rotation functions doesn't work correctly because of this missing data.

1
What is layer1Img? I see you are setting width to this object. But inside the function, you created imgKI Konva.Image object. Probably you need to call imgKI.setAttr('width', this.naturalWidth);, NOT layer1Img.setAttr('width', this.naturalWidth);lavrton
I made the changes suggested and when I save the canvas to Json I'm still loosing the height and width attributes for the images.Robin Savinsky
It will be nice if you can provide a demo.lavrton
Here is the URL to my sandbox: bottlest.com/sandbox/label-maker/index.html#step-1. I log the image object to the console when it is added to the canvas and I log the JSON that is provided by the toJSON() function to the console when you click the "Quick Save" button.Robin Savinsky

1 Answers

0
votes

I found why you have no width and height in JSON.

While converting a Konva.Node to JSON Konva is trying to make it as minimal as possible. For example, it does save default values (for x and y in will be 0).

In you case width attribute of Konva.Image equals to the natural width of the native image you use. So it is useless in JSON.

When you restore a stage from JSON you will need just load native images and set them to Konva.Image instances.