ericdrowell / KineticJS

KineticJS is an HTML5 Canvas JavaScript framework that extends the 2d context by enabling canvas interactivity for desktop and mobile applications.
http://www.kineticjs.com
3.98k stars 754 forks source link

Add layer add new canvas #669

Closed CSI68 closed 11 years ago

CSI68 commented 11 years ago

Hello,

For my project I've done a class with KinteticJS to add some element on my canvas. All seems working good but one thing is strange, when I add a text, an image or rect the script add a new canvas. So after adding 3 texts my html contain 3 canvas ... Not so good.

Here is my class:

jQuery.fn.customize = function (callback) { $.customize(this, callback); return this; }; jQuery.customize = function (container, callback) { var container = $(container).get(0); return container.customize || (container.customize = new jQuery._customize(container, callback)); }

jQuery._customize = function (container, callback) { // Store customize object var cust = this; var currentEl=false;

var objTxt={fontFamily:'Calibri', text:'Nouveau texte'}

cust.stage = new Kinetic.Stage({
    container: container
});

// Set background
cust.setBackground = function(support){
    var layer = new Kinetic.Layer();

    var rect = new Kinetic.Rect({
        x:0,
        y: 0,
        width: cust.stage.getWidth(),
        height: cust.stage.getHeight(),
        cornerRadius:10,
        fill: 'green'
    });

    // add the shape to the layer
    layer.add(rect);

    // add the layer to the stage
    cust.stage.add(layer);
};

// Change support format
cust.changeSupport = function(support){
    try{

        switch(support){
            case '4x3'  :   $('#main-container').css('width', 800+'px').css('height', 600+'px'); break
            case '3x4'  :   $('#main-container').css('width', 600+'px').css('height', 800+'px'); break
            default         :   $('#main-container').css('width', 600+'px').css('height', 800+'px'); break
        }

        cust.stage.setWidth($('#main-container').width());
        cust.stage.setHeight($('#main-container').height());

        //cstz_set_text();

    }catch(e){
        console.group("Error detected in `customize2.js` > `changeSupport`");
        console.error('Message : '+e.message);
        console.groupEnd();
    }
};

// Text default values
cust.text={
    text:'Nouveau texte',
    fontFamily:'Calibri',
    fontSize:40,
    color:'#ff0000',
    left: 'center',
    top: 'middle',
    align: 'center'
};

// Set size of the text
cust.setSize = function(size){
    switch(currentEl.type){
        case 'txt'  :   currentEl.setFontSize(size); break;
        case 'img'  :   {
            var s=cust.getSize(currentEl.attrs.width, currentEl.attrs.height, size);
            currentEl.setWidth(s.width);
            currentEl.setHeight(s.height);
            // Set offset
            currentEl.setOffset(s.width/2,s.height/2);
        }
    }
        currentEl.getLayer().draw();
}

// Set rotation of the element
cust.setRotation = function(deg){
    console.log(deg);
    currentEl.setRotationDeg(-deg);
    currentEl.getLayer().draw();
}

// Change color of an element
cust.setColor = function(color){
    currentEl.setFill(color);
    currentEl.setStroke(color);
    currentEl.getLayer().draw();
}

// ##################################################### Draw an image ##################################################### //
cust.setImage = function(src){
    try{

        var imgGroup = new Kinetic.Group({
            x: 0,
            y: 0,
            draggable: true
        });
        var layer = new Kinetic.Layer();
        layer.add(imgGroup);
        cust.stage.add(layer);

        image=new Image();

        image.onload = function() {
    var Img = new Kinetic.Image({
                    x: cust.stage.getWidth()/2,
                    y: cust.stage.getHeight()/2,
                    image: image,
                    name: 'image'
                });

    // add the shape to the group
    imgGroup.add(Img);

            // Resize
            var imgW=Img.getWidth();
            var imgH=Img.getHeight();

            var newSize=cust.getSize(imgW, imgH, cust.stage.getWidth()*80/100, cust.stage.getHeight()*60/100);
            Img.setWidth(newSize.width);
            Img.setHeight(newSize.height);

            // Set offset for rotation
            Img.setOffset(newSize.width/2,newSize.height/2);

            // Drag events
            imgGroup.on('dragend', function(e){
                // Auto center
                if(imgGroup.getX() > -10 && imgGroup.getX() < 10){
                    imgGroup.setX(0);
                    cust.stage.draw();
                }
                // Auto middle
                if(imgGroup.getY() > -10 && imgGroup.getY() < 10){
                    imgGroup.setY(0);
                    cust.stage.draw();
                }
            });

            Img.on('mousedown touchstart', function(e){
                console.log(e);
                $('#text-editor').val('');
                $('#color-picker').val('');

                currentEl=e.targetNode;
                currentEl.type='img';

                // Init the slider size
                cust.sliderSize.slider('option', 'max', 1000);
                cust.sliderSize.slider('value', currentEl.getWidth());
            });

            cust.stage.draw();
  };
        image.src = src;

    }catch(e){
        console.group("Error detected in `customize2.js` > `setImage`");
        console.error('Message : '+e.message);
        console.groupEnd();
    }
}

// ##################################################### Draw a new text ##################################################### //
cust.setText = function(obj){
    try{

        if(!currentEl){
            $.extend(cust.text, obj);

            if(cust.text.top=='middle'){
                cust.text.top=cust.stage.getHeight() / 2;
            }
            if(cust.text.left=='center'){
                cust.text.left=cust.stage.getWidth() / 2;
            }

            var layer = new Kinetic.Layer();

            var Text = new Kinetic.Text({
                x: cust.text.left,
                y: cust.text.top,
                text: cust.text.text,
                fontSize: cust.text.fontSize,
                fontFamily: cust.text.fontFamily,
                draggable: true,
                fill: cust.text.color,
                align: cust.text.align,
                stroke: cust.text.color,
                strokeWidth: 0.1,
                width: cust.stage.getWidth()
            });

            // to align text in the middle of the screen, we can set the
            // shape offset to the center of the text shape after instantiating it
            Text.setOffset({
                x: Text.getWidth() / 2
            });

            Text.on('mousedown touchstart', function(e){
                console.log(e);
                $('#text-editor').val(e.targetNode.attrs.text);
                $('#color-picker').val(e.targetNode.attrs.fill);

                currentEl=e.targetNode;
                currentEl.type='txt';

                // Init the slider size
                cust.sliderSize.slider('option', 'max', 500);
                cust.sliderSize.slider('value', currentEl.getFontSize());
            });

            // add cursor styling
            Text.on('mouseover', function() {
                document.body.style.cursor = 'pointer';
            });
            Text.on('mouseout', function() {
                document.body.style.cursor = 'default';
            });

            // Drag events

            layer.add(Text);
            cust.stage.add(layer);

        }else{
            currentEl.setText(obj);
            currentEl.getLayer().draw();
        }

    }catch(e){
        console.group("Error detected in `customize2.js` > `setText`");
        console.error('Message : '+e.message);
        console.groupEnd();
    }
};

// ##################################################### Resize keeping ratio ##################################################### //
cust.getSize = function(width, height, sizeW, sizeH){
    try{

        if(width>=height){
            var newWidth=sizeW;
            var newHeight=height/width*newWidth;
        }else{
            if(sizeH>0){
                var newHeight=sizeH;
            }else{
                var newHeight=sizeW;
            }
            var newWidth=width/height*newHeight;
        }

        return {width:newWidth, height:newHeight};

    }catch(e){
        console.group("Error detected in `customize2.js` > `getSize`");
        console.error('Message : '+e.message);
        console.groupEnd();
    }
};

// Init default support
cust.changeSupport();
cust.setBackground();

}

Here a sample call code :

// Initialize engine on main container var customize=$.customize('#main-container'); customize.setImage('hunawihr-hdr.jpg');

I think it's not a bug in Kinetic but I bug in my code !

Thanks for your help.

Best regards,

Clement

lavrton commented 11 years ago

A layer is creating new canvas element. This is expected behaviors. You should carefully read http://www.html5canvastutorials.com/kineticjs/html5-canvas-layer-management-with-kineticjs/

CSI68 commented 11 years ago

Oups, sorry for that. Thanks lavrton for your answer I will that.