Question

Can I implement snap to grid operation with images in KineticJS using jquery? (http://jqueryui.com/demos/draggable/snap-to.html) Like I have few draggable images inside a canvas and I want them to restrict the movement inside a canvas...

Is it even possible that 2 images can snap together when one comes near the other in the canvas?? And can it be achieved using kinetic.js or javascript...

Thanks Ashish

Here is the code.. it's a little complicated. I mean I'm loading images from outside the canvas..and there are two sets..now I want one set to be able to snap to other..

  <script src="kinetic-v3.8.0.min.js">
  </script>
  <link rel="stylesheet" href="../../themes/base/jquery.ui.all.css">
<script src="jquery-1.7.1.js"></script>
<script src="jquery.ui.core.js"></script>
<script src="jquery.ui.widget.js"></script>
<script src="jquery.ui.mouse.js"></script>
<script src="jquery.ui.draggable.js"></script>



    <script>
        function drawImage(imageObj){

            var stage = new Kinetic.Stage("container", 578, 500);
            var layer = new Kinetic.Layer();
            var x = stage.width / 2 - 200 / 2;
            var y = stage.height / 2 - 137 / 2;
            var width = 200;
            var height = 137;

            // darth vader
            var darthVaderImg = new Kinetic.Shape(function(){
                var context = this.getContext();

                context.clearRect(x,y,width,height);
                context.drawImage(imageObj, x, y, width, height);
                // draw invisible detectable path for image
                context.beginPath();
                context.rect(x, y, width, height);
                context.closePath(); 


          });

            // enable drag and drop
            darthVaderImg.draggable(true);

            // add cursor styling
            darthVaderImg.on("mouseover", function(){
                document.body.style.cursor = "pointer";
            });
            darthVaderImg.on("mouseout", function(){
                document.body.style.cursor = "default";
            });
            //remove image on double click
            darthVaderImg.on("dblclick dbltap", function(){
            layer.remove(darthVaderImg);


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

            //events

        }


         function drawImage2(imageObj){

            var stage = new Kinetic.Stage("container", 578, 500);
            var layer = new Kinetic.Layer();

            var x = stage.width / 2 - 300 ;
            var y = stage.height / 2 - 137 ;
            var width = 200;
            var height = 137;

            // darth vader

            var darthVaderImg2 = new Kinetic.Shape(function(){
                var context = this.getContext();

                context.drawImage(imageObj, x, y, width, height);

                // draw invisible detectable path for image
                context.beginPath();
                context.rect(x, y, width, height);
                context.closePath();

            });

            // enable drag and drop
            darthVaderImg2.draggable(true);

            // add cursor styling
            darthVaderImg2.on("mouseover", function(){
                document.body.style.cursor = "pointer";
            });
            darthVaderImg2.on("mouseout", function(){
                document.body.style.cursor = "default";
            });
            //remove image on double click
            darthVaderImg2.on("dblclick dbltap", function(){
            layer.remove(darthVaderImg2);


            layer.draw();



                   });
                layer.add(darthVaderImg2);

             stage.add(layer);



          $( ".darthVaderImg2" ).draggable({ grid: [ 20,20 ] });

             }



               function load(img){
                 // load image

                 var imageObj = new Image();
                 imageObj.onload = function(){

                drawImage(this);

                  };
                   imageObj.src = img.src;
                    };
                 function load2(img){
             // load image
                 var imageObj = new Image();
                imageObj.onload = function(){
                drawImage2(this);
               };
               imageObj.src = img.src;
                 };
             </script>
            <title>HTMl5 drag drop multiple elements</title></head>
             <body onmousedown="return false;">
              <div id="container">
              </div>
             <div id="check1">
            <ul id="img"> <li><a href="#"onclick="load(document.getElementById('i1'))">
            <img class="ui-widget-header" src="dog.png" id="i1" alt="doggie"     width="60"height="55"/>
      </a></li>
      <li>
        <a href="#" onclick="load(document.getElementById('i2'))">
        <img src="dog2.png" id="i2" alt="Pulpit rock" width="60" height="55"        /></a>
    </li>
    </ul>
    </div>
    <ul id="img1">
        <li><a href="#" onclick="load2(document.getElementById('i4'))">
            <img alt="doggie" src="beach.png" id="i4" width="60" height="55" />
             </a></li>
             <li><a href="#" onclick="load2(document.getElementById('i5'))">
        <img alt="doggie" src="cat3.png" id="i5" width="60" height="55" /></a></li>
       </ul>
       </body>
        </html>
Was it helpful?

Solution

I submitted an answer to this question that doesn't use jQuery. Instead, there is a patch you can apply which gives you drag and drop with snap to grid in KineticJS on the HTML5 canvas.

Using jquery draggable UI with kineticJs to make elements snap to grid?

OTHER TIPS

You can do this different by using the dragBoundFunc.

      return {
        x: Math.round(pos.x / grid) * grid,
        y: Math.round(pos.y / grid) * grid
      }

I have created a complete snapping example: http://jsfiddle.net/PTzsB/1/

This is all very possible. It requires being a bit more familiar than the average jQuery user, though.

First, implementing the snap-to:

This is a simple idea. You use the jQuery UI Library. You add the necessary function for the 'snap-to' feature, by invoking 'snap-to' on all elements with the class of 'KineticJsImage'.

$( ".KineticJsImage" ).draggable({ snap: true });

Second, for all images propogated by KineticJs, we add the class 'KineticJsImage'

..I don't have anything to work with here...
You simply need to find where the image output is controlled and add a class
of KineticJsImage to the code.

As you mentioned in your first question, you'd found the snap-to operation. The 2nd box in the demo on that page uses the generic (code I mentioned above, as well) snap: true parameter. When you invoke this, you're telling the page to snap all draggable elements with the class of 'KineticJsImage' to ANY element that has ALSO been declared draggle.

 $(".someElement").draggable({ snap: false }); // drags wherever, does not snap.
 $(".KineticJsImage").draggable({snap: true }); // drags everywhere, snaps to anything.
 $(".KineticJsImage").draggable({snap: '.KineticJsImage' }); // This will ensure that
 any element with the class of 'KineticJsImage' is not only draggable, but will snap
 to any other element with the class of' 'KineticJsImage' that is also draggable.

Everything you want to achieve is doing able with jQuery UI and the draggable / droppable extensions provided within.

Fool around and try to figure out out. When you can't, come back with the code and we'll show you where to go from there. $("

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top