Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Based on this statement:</p> <pre><code>stage.on('mousedown touchstart', function(){ // CACHING}) </code></pre> <p>I'm assuming that on <code>mousedown touchstart</code> you call <code>layer.toImage()</code> or <code>stage.toImage()</code> and you want to drag the new image on that one click/tap.</p> <ol> <li><p>You can invoke the drag event on the new generated image by using the <code>.startDrag()</code> function: <a href="http://kineticjs.com/docs/Kinetic.Shape.html#startDrag" rel="nofollow">Kinetic.Shape#startDrag</a></p> <p>You can then invoke <code>.stopDrag()</code> on <code>mouseup touchend</code> to stop the drag. <a href="http://kineticjs.com/docs/Kinetic.Shape.html#stopDrag" rel="nofollow">Kinetic.Shape#stopDrag</a></p> <p>Something like:</p> <pre><code>var image, ox, oy; stage.on('mousedown touchstart', function(){ // CACHING stage.toImage({ width: stage.getWidth(), height: stage.getHeight(), callback: function(img) { var image = new Kinetic.Image({ image: img, draggable: true }); ox = image.getX(); oy = image.getY(); image.startDrag(); } }); }); stage.on('mouseup touchend', function(){ image.stopDrag(); //Calculate dx, dy to update nodes. var newX = image.getX(); var newY = image.getY(); var dx = newX-ox; var dy = newY-oy; var children = layer.getChildren(); for (var i=0; i&lt;children.length; i++) { children.setX(children.getX()+dx); children.setY(children.getY()+dy); } image.hide(); //or remove() or destroy() layer.draw(); }); </code></pre> <p><strong>Note</strong> you need to update your original nodes after dragging the cached layer.</p> <p><strong>Another Note</strong> I haven't tested the code but I believe you could do something along the lines of what I've got up there.</p> <p><strong>Small UPDATE</strong>: You also should probably <code>hide()</code> the original layer while dragging the cached layer image! :) And then <code>show()</code> it again when you hide the cached image layer.</p></li> <li><p>Honestly I'm not sure how you would speed up that cache time unless you can predict when the user needs to click/tap the stage to move. I think your suggestion would cost more performance than it would save.</p> <p>I'm guessing that the desktop caches the image faster than on your mobile? It might fall into just being a limitation of KineticJS performance on Mobile vs Desktop...</p></li> </ol> <p><strong>UPDATE</strong></p> <p>Okay, I have an idea for <strong>#2</strong>, it's not exactly a fix but it might work better for you.</p> <ol> <li><p>Separate your stage <code>mousedown</code> event with your <code>touchstart</code> event. <code>mousedown</code> will be the same but <code>touchstart</code> we want to handle differently.</p></li> <li><p>On stage <code>touchstart</code> we want to <strong>drag</strong> the entire stage like normal, but <strong>meanwhile</strong> run the code for the original <code>mousedown</code> to <strong>cache</strong> the layer.</p></li> <li><p>When the <strong>cached image</strong> finishes loading (takes 1-2 seconds you say), use <code>.stopDrag()</code> on the original <strong>stage</strong> and hide it. At this moment you want to store the current <strong>x</strong> and <strong>y</strong> values of the stage, so that you can still calculate <strong>dx,dy</strong>. Then immediately call <code>.startDrag()</code> on the new cached image and continue on like we did for <code>mousedown</code>.</p></li> </ol> <p><strong>How to know when the cached image finishes loading?</strong> I think that's what the <code>toImage()</code> <code>callback function</code> is for. If not, than hopefully a javascript <code>onload</code> event will work to determine when the image finishes generating.</p> <p>The end result will be that you'll get your slow choppy drag on the stage for <strong>touch</strong> events UNTIL the image is cached. Then we flip the switch and stop dragging the stage, start dragging the cached image, and then revert/update the stage on <code>touchend</code>.</p> <p>Hope that works as a semi-solution to your problem...</p> <p><strong>ANOTHER UPDATE</strong></p> <p>Okay here's another idea that actually might help your performance!</p> <p>If your stage isn't modifying nodes very often, you can <strong>pre-cache</strong> the stage image so that it's already generated, and <code>.hide()</code> it. Then when you need to drag it, you just need to set the <strong>x,y</strong> of the cached image to match the stage's current <strong>x,y</strong> and then <code>.show()</code> the cached image. This will eliminate the time needed to wait/load the cached image when you first start dragging.</p> <p>If you do happen to add a node or move a node or anything, after that cache the image. Hopefully this is manageable as we don't want to <strong>cache</strong> the image too often (drains performance). Again the cached image will be ready for your <code>stage.drag</code> event beforehand.</p> <p>The goal is to have the stage cached before you do <code>mousedown touchstart</code> and start dragging. Hopefully this helps.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload