Kinetic js drag, drop, resize and rotate image
Asked Answered
H

1

41

I am trying to combine drag and drop resize image and rotating image on touch, and mine is behaving strange http://jsfiddle.net/littlechad/Kuaxn/

My code is as follows:

function update (activeAnchor) {
    var group       = activeAnchor.getParent();
    var topLeft     = group.get('.topLeft')[0];
    var topRight    = group.get('.topRight')[0];
    var bottomRight = group.get('.bottomRight')[0];
    var bottomLeft  = group.get('.bottomLeft')[0];
    var image       = group.get('.image')[0];
    var stage       = group.getStage();

    var anchorX     = activeAnchor.getX();
    var anchorY     = activeAnchor.getY();

    // update anchor positions
    switch (activeAnchor.getName()) {
        case 'topLeft':
            topRight.setY(anchorY);
            bottomLeft.setX(anchorX);
            break;
        case 'topRight':
            topLeft.setY(anchorY);
            bottomRight.setX(anchorX);
            break;
        case 'bottomRight':
            bottomLeft.setY(anchorY);
            topRight.setX(anchorX); 
            break;
        case 'bottomLeft':
            bottomRight.setY(anchorY);
            topLeft.setX(anchorX); 
            break;
    }

    image.setPosition(topLeft.getPosition());

    var height          = bottomLeft.attrs.y - topLeft.attrs.y;
    var width           = image.getWidth()*height/image.getHeight();

    topRight.attrs.x    = topLeft.attrs.x + width
    topRight.attrs.y    = topLeft.attrs.y;
    bottomRight.attrs.x = topLeft.attrs.x + width;
    bottomRight.attrs.y = topLeft.attrs.y + height;

    if (width && height) {
        image.setSize(width, height);
    }
}

function rotate (activeAnchor) {
    var group       = activeAnchor.getParent();
    var topLeft     = group.get('.topLeft')[0];
    var topRight    = group.get('.topRight')[0];
    var bottomRight = group.get('.bottomRight')[0];
    var bottomLeft  = group.get('.bottomLeft')[0];
    var image       = group.get('.image')[0];
    var stage       = group.getStage();

    var pos         = stage.getMousePosition();
    var xd          = 150 - pos.x ;
    var yd          = 150 - pos.y ;
    var theta       = Math.atan2(yd, xd);
    var degree      = theta / (Math.PI / 180) - 45;

    var height      = bottomLeft.attrs.y - topLeft.attrs.y;
    var width       = image.getWidth() * height / image.getHeight();

    console.log(degree);        
    console.log(width);
    console.log(height);

    image.setRotationDeg(degree);

    return {
        x: image.getAbsolutePosition().x,
        y: image.getAbsolutePosition().y
    }
}

function addAnchor (group, x, y, name) {
    var stage  = group.getStage();
    var layer  = group.getLayer();
    var anchor = new Kinetic.Circle({
        x: x,
        y: y,
        stroke: 'transparent',
        strokeWidth: 0,
        radius: 20,
        name: name,
        draggable: false,
        dragOnTop: false
    });

    if(name === 'topRight'){
        var anchor = new Kinetic.Circle({
            x: x,
            y: y,
            stroke: '#666',
            fill: '#ddd',
            strokeWidth: 2,
            radius: 20,
            name: name,
            draggable: true,
            dragOnTop: false
        }); 
    }

    anchor.on('dragmove', function () {
        update(this);
        rotate(this);
        layer.draw();
    });

    anchor.on('mousedown touchstart', function () {
        group.setDraggable(false);
        this.moveToTop();
    });

    anchor.on('dragend', function () {
        group.setDraggable(true);
        layer.draw();
    });

    group.add(anchor);

}    

function initStage () {

    var stage = new Kinetic.Stage({
        container: 'container',
        width: 500,
        height: 800
    });

    var imageGroup = new Kinetic.Group({
        x: 150,
        y: 150,
        draggable: true,
    });

    var layer  = new Kinetic.Layer({
        width: 128,
        height: 128,
        offset: [64, 64]
    });

    layer.add(imageGroup);

    var imgObj        = new Image();

    var imageInstance = new Kinetic.Image({
        x: 0,
        y: 0,
        image: imgObj,
        width: 200,
        height: 138,
        name: 'image',
    });

    imgObj.src = 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg';

    imageGroup.add(imageInstance);
    addAnchor(imageGroup, 0, 0, 'topLeft');
    addAnchor(imageGroup, 200, 0, 'topRight');
    addAnchor(imageGroup, 200, 138, 'bottomRight');
    addAnchor(imageGroup, 0, 138, 'bottomLeft');

    imageGroup.on('dragstart', function() {
        update(this);
        rotate(this);
        this.moveToTop();
    });

    stage.add(layer);
    stage.draw();
}

function writeMessage (messageLayer, message) {
    var context = messageLayer.getContext();
    messageLayer.clear();
    context.font = '18pt Calibri';
    context.fillStyle = 'black';
    context.fillText(message, 10, 25);
}

//loadImages(sources, initStage);
initStage();

It seems that updating the offset is the problem, I have tried several things to set the offset so that it stays in the middle, yet I still can't figure out how, I am really new to HTML5 and KineticJs, please help me on this.

UPDATE:

The above fiddle is no longer working due to the fillColor broken on new browsers, I have updated the fiddle, although I haven't been able to figure out the solution for this.

Thanks

Hamitic answered 24/4, 2013 at 11:49 Comment(8)
Thanks for the 'fiddle. What is the expected behavior? When should the picture be dragged, scaled or rotated?Mandi
@Mandi the expected behavior is that i can rotate, scale and drag-drog the image, the trigger would be on touch and drag, is that what you mean?Hamitic
How you want to rotate?Circassia
Your fiddle seems to be brokenNectarous
@Hamitic could you please post your solution if you have one.Complaint
The new fiddle seems broken as well.Scalise
I didn't understood what do you want and your fiddle is also broken. I've found 2 issues with your fiddle and code. First the cdn you have added to the fiddle for kineticjs denies the access. So i replaced the cdn. Second the method getMousePosition() is no longer available on kineticjs v5.x.x. So i have replaced that method with its equivalent getPointerPosition(). Here is the updated fiddle jsfiddle.net/k7moorthi/Kuaxn/36. I don't know is this the same you want or not but i hope this may help you!Septarium
@Kesavan thank you for correcting, i asked this question 4 years ago, and have left the project a year later, i am sorry if i havent been able to update my fiddle, and yes your fiddle has exactly the same result that made post the question, if you see the resize rotate doesnt work as expected.Hamitic
C
1

You were very close, just using some incorrect method names, and as was said before, the cdn needs to change.

function update(activeAnchor) {
var group       = activeAnchor.getParent();
var topLeft     = group.get('.topLeft')[0];
var topRight    = group.get('.topRight')[0];
var bottomRight = group.get('.bottomRight')[0];
var bottomLeft  = group.get('.bottomLeft')[0];
var image       = group.get('.image')[0];
var stage       = group.getStage();

var anchorX = activeAnchor.getX();
var anchorY = activeAnchor.getY();

switch (activeAnchor.getName()) {
    case 'topLeft':
        topRight.setY(anchorY);
        bottomLeft.setX(anchorX);
        break;
    case 'topRight':
        topLeft.setY(anchorY);
        bottomRight.setX(anchorX);
        break;
    case 'bottomRight':
        bottomLeft.setY(anchorY);
        topRight.setX(anchorX); 
        break;
    case 'bottomLeft':
        bottomRight.setY(anchorY);
        topLeft.setX(anchorX); 
        break;
}
image.setPosition(topLeft.getPosition());

var height = bottomLeft.attrs.y - topLeft.attrs.y;
var width  = image.getWidth()*height/image.getHeight();

topRight.attrs.x = topLeft.attrs.x + width
topRight.attrs.y = topLeft.attrs.y;
bottomRight.attrs.x = topLeft.attrs.x + width;
bottomRight.attrs.y = topLeft.attrs.y + height;

if(width && height) {
    image.setSize(width, height);
}
}

function rotate(activeAnchor){
var group       = activeAnchor.getParent();
var topLeft     = group.get('.topLeft')[0];
var topRight    = group.get('.topRight')[0];
var bottomRight = group.get('.bottomRight')[0];
var bottomLeft  = group.get('.bottomLeft')[0];
var image       = group.get('.image')[0];
var stage       = group.getStage();

var pos     = stage.getPointerPosition();
var xd      = 150 - pos.x ;
var yd      = 150 - pos.y ;
var theta   = Math.atan2(yd, xd);
var degree  = theta / (Math.PI / 180) - 45;

var height  = bottomLeft.attrs.y - topLeft.attrs.y;
var width   = image.getWidth()*height/image.getHeight();

console.log(degree);

console.log(width);
console.log(height);
image.setRotationDeg(degree);
return {
    x: image.getAbsolutePosition().x,
    y: image.getAbsolutePosition().y
}
}

function addAnchor(group, x, y, name) {
var stage = group.getStage();
var layer = group.getLayer();
var anchor = new Kinetic.Circle({
    x: x,
    y: y,
    stroke: '#fff',
    fill: '#fff',
    strokeWidth: 2,
    radius: 20,
    name: name,
    draggable: false,
    dragOnTop: false
});

if(name === 'topRight'){
    var anchor = new Kinetic.Circle({
      x: x,
      y: y,
      stroke: '#666',
      fill: '#ddd',
      strokeWidth: 2,
      radius: 20,
      name: name,
      draggable: true,
      dragOnTop: false
    });
}
anchor.on('dragmove', function() {
    update(this);
    rotate(this);
    layer.draw();
});
anchor.on('mousedown touchstart', function() {
    group.setDraggable(false);
    this.moveToTop();
});
anchor.on('dragend', function() {
    group.setDraggable(true);
    layer.draw();
});
group.add(anchor);
}


function initStage() {          
var stage = new Kinetic.Stage({
    container: 'container',
    width: 500,
    height: 800
});

var imageGroup = new Kinetic.Group({
    x: 150,
    y: 150,
    draggable: true,
});

var layer  = new Kinetic.Layer({
    width: 128,
    height: 128,
    offset: [64, 64]
});
layer.add(imageGroup);

var imgObj        = new Image();
var imageInstance = new Kinetic.Image({
    x: 0,
    y: 0,
    image: imgObj,
    width: 200,
    height: 138,
    name: 'image',
});
imgObj.src = 'http://www.html5canvastutorials.com/demos/assets/darth-
vader.jpg';

imageGroup.add(imageInstance);
addAnchor(imageGroup, 0, 0, 'topLeft');
addAnchor(imageGroup, 200, 0, 'topRight');
addAnchor(imageGroup, 200, 138, 'bottomRight');
addAnchor(imageGroup, 0, 138, 'bottomLeft');

imageGroup.on('dragstart', function() {
    update(this);
    rotate(this);
    this.moveToTop();
});

stage.add(layer);
stage.draw();
}

function writeMessage(messageLayer, message) {
var context = messageLayer.getContext();
messageLayer.clear();
context.font = '18pt Calibri';
context.fillStyle = 'black';
context.fillText(message, 10, 25);
}

loadImages(sources, initStage);
initStage();
Cahilly answered 8/9, 2017 at 0:44 Comment(1)
i am sorry but i don't see much changes in your fix, i think the only thing changed is the getMousePosition to getPointerPosition , and i check this in the fiddle, it is still presenting the same problem as i encountered 4 years ago.Hamitic

© 2022 - 2024 — McMap. All rights reserved.