简体   繁体   中英

Interspersing KineticJS and jQuery events

I am looking to build a simple photo collage using KineticJS and Canvas. In the canvas container, I have pre-defined image areas. I also have (in the DOM and outside of the canvas container), a strip of images which I want to drag and drop to the image wells on the canvas. I am able to drag an image and snap it to a (hard-coded) image well but while the image is moving on canvas I'm unable to get the x and y co-ordinates. I've tried using jQuery's drag/drag event but then it is blind to the canvas and I've tried to use use the KineticJS's dragover function but then I can't get the DOM image's x and y. The idea is that knowing the x,y of the image being dragged I can write some logic to figure out which image location it should get snapped to - as opposed to hard coding it's target.

Is it even possible to do this with KineticJS+jQuery - drag images from a DOM onto a canvas and have them snap into pre-defined image areas? Or, is there a simpler way?

as far as I understand your problem, I tried to reproduce it, but not seeing any difficulties

    <div width="600" height="500" style="background-color:green;padding-left:60px" id="wrap">
    <canvas id="a" width="300" height="225" style="background-color:yellow"></canvas>
</div>
<img id="dragMe" src="http://www.linuxmint.com/img/logo.png"/>
<div id="log">
    <span class="a"></span>
    <span class="b"></span>
    <span class="c"></span>
        <span class="d"></span>
</div>

$("#wrap").mousemove(function(e){
  var pageCoords = "( " + e.pageX + ", " + e.pageY + " )";
  var clientCoords = "( " + e.clientX + ", " + e.clientY + " )";
  $("#log > span.a").text("( e.pageX, e.pageY ) : " + pageCoords);
  $("#log > span.b").text("( e.clientX, e.clientY ) : " + clientCoords);
});
var p = $('#a').position();
$("#dragMe").draggable({
    drag: function(event, ui) {
        $("#log > span.c").text(  ui.offset.left+':' +ui.offset.top);
        $("#log > span.d").text( ( ui.offset.top-p.top)+':' +(ui.offset.left - p.left));
    }
});

http://jsfiddle.net/agj3N/1/

When I asked you if you had a reason you had the strip of images outside of the KineticJS stage, you answered:

Only because when I toJSON it (for saving and calling up for a future edit), I just want the images on my photo collage and not the photos on the strip.

My answer to this is:

You don't have to use toJSON on the entire stage.

If you separate the Photo Strip (previously outside of the canvas) into a different layer from the Collage (previously inside the canvas, then you can have two layers and use toJSON on only one of those layers!

The result will be that toJSON will only serialize the objects from that given layer, which sounds like what you need.

jsfiddle - here is an example to illustrate what I mean, excuse my poor logic for snapping the image to the group. I have 2 layers: photoStripLayer and collageLayer

  1. Click on the Collage toJSON button. Notice the console.log output does not include any of the images. This is because collageLayer only has a group inside it that has a child rectangle.

  2. Drag the first yoda (top left, the rest don't work this is just an example) into the red box. Sorry you'll have to play around with this to get it to snap properly (I'm assuming you have your "snap" code already)

  3. On dragend if the Yoda node is inside the red box, it will use KineticJS' moveTo function to move the yoda from the photoStripLayer --> collageLayer . You'll know it worked when the Yoda snaps to position (0,0) relative to the new group.

  4. Now Click on the Collage toJSON button. Notice that the yoda image is now a part of the toJSON console.log output. The yoda was moved to the new group, which is a child of collageLayer . Now part of the collageLayer, Yoda is .

Here's the dragend code:

             node.on('dragend', function () {
                var pos = stage.getMousePosition();
                var X = pos.x;
                var Y = pos.y;
                var minX = snap.getX();
                var maxX = snap.getX() + snap.getWidth();
                var minY = snap.getY();
                var maxY = snap.getY() + snap.getHeight();
                if (node.getX() < minX) {
                    node.moveTo(snap);
                    node.setX(0);
                    node.setY(0);
                }
                if (node.getX() > maxX) {
                    node.moveTo(snap);
                    node.setX(0);
                    node.setY(0);
                }
                if (node.getY() < minY) {
                    node.moveTo(snap);
                    node.setX(0);
                    node.setY(0);
                }
                if (node.getY() > maxY) {
                    node.moveTo(snap);
                    node.setX(0);
                    node.setY(0);
                }
                photoStripLayer.draw();
                collageLayer.draw();
            });

And the button click code to illustrate using toJSON:

            function collageToJSON() {
                var cjson = collageLayer.toJSON();
                console.log(cjson);
                /* To illustrate, you can also call toDataURL here. But in JSFiddle I think it throws a Security Error.
                collageLayer.toDataURL({
                    callback: function(dataUrl) {
                        window.open(dataUrl);
                    }
                });
                */
            }

            document.getElementById('CtoJSON').addEventListener('click', function () {
                collageToJSON();
            });

And there you have it! The issue is solved by letting KineticJS handle the entire process.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM