0

Using famous with meteor and famous-views but at it's core this is really a famous question —

How can I get the position of a Draggable modifier after the on end event and until it stops moving?

Eg. while it's bouncing into a given position what is it's position vector? How can I put this into a session var etc. or pipe it somewhere else?

rjmoggach
  • 1,458
  • 15
  • 27

1 Answers1

1

Pure Famo.us Solution: Use the update and end events on a Draggable.

    draggable.on('update', function (e) {
        var pos = e.position;
        // Use the updating position here
    });

    draggable.on('end', function (e) {
        var pos = e.position;
        // Use the final position here
    });

As you can see from the snippet below, these two events will allow you to track the drag position. As you drag the surface, the other surface is transitioned to follow using the position of the Draggable.

Updated: returns to origin transform on drag end

define('main', function(require, exports, module) {
    var Engine = require('famous/core/Engine');
    var Surface = require('famous/core/Surface');
    var Transform = require('famous/core/Transform');
    var Modifier = require('famous/core/Modifier');
    var StateModifier = require('famous/modifiers/StateModifier');
    var Draggable = require('famous/modifiers/Draggable');
    var TransitionableTransform = require('famous/transitions/TransitionableTransform');

    var mainContext = Engine.createContext();

    var transTransform = new TransitionableTransform();
    transTransform.set(Transform.translate(100, 0, 0));
    
    var surface = new Surface({
        size: [300, 100],
        properties: {
            backgroundColor: 'rgba(255,0,0,0.1)',
            cursor: 'pointer'
        }
    });

    var dragSurface = new Surface({
        content: 'Drag Me',
        size: [100, 100],
        properties: {
            backgroundColor: 'rgba(0,0,0,0.1)',
            cursor: 'pointer'
        }
    });

    var modifier = new Modifier({
        origin: [0, 0],
        align: [0, 0],
        transform: transTransform
    });

    var draggable = new Draggable();

    draggable.subscribe(dragSurface);

    var content = 'Not Draggable';
    surface.setContent(content);

    mainContext.add(modifier).add(surface);
    mainContext.add(draggable).add(dragSurface);

    draggable.on('update', function (e) {
        var pos = e.position;
        surface.setContent('Draggable Position is '+pos);
        transTransform.set(Transform.translate(pos[0]+100, pos[1], 0));
    });

    draggable.on('end', function (e) {
        var pos = e.position;
        surface.setContent('Draggable End Position is '+pos);
        transTransform.setTranslate([100, 0, 0],{duration: 300});
      this.setPosition([0,0],{duration: 300});
    });
});

// Start Main App
require(['main']);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://requirejs.org/docs/release/2.1.16/minified/require.js"></script>
<script src="http://code.famo.us/lib/requestAnimationFrame.js"></script>
<script src="http://code.famo.us/lib/classList.js"></script>
<script src="http://code.famo.us/lib/functionPrototypeBind.js"></script>

<link rel="stylesheet" type="text/css" href="http://code.famo.us/famous/0.3.5/famous.css" />

<script src="http://code.famo.us/famous/0.3.5/famous.min.js"></script>

Updated: A more loosely coupled example.

Emit an event object to an EventHandler to be able to listen for the custom event and use the object to apply your outside transition.

define('main', function(require, exports, module) {
  var Engine = require('famous/core/Engine');
  var Surface = require('famous/core/Surface');
  var Transform = require('famous/core/Transform');
  var Modifier = require('famous/core/Modifier');
  var StateModifier = require('famous/modifiers/StateModifier');
  var Draggable = require('famous/modifiers/Draggable');
  var TransitionableTransform = require('famous/transitions/TransitionableTransform');

  var mainContext = Engine.createContext();

  var transTransform = new TransitionableTransform();
  transTransform.set(Transform.translate(100, 0, 0));

  var surface = new Surface({
    size: [300, 100],
    properties: {
      backgroundColor: 'rgba(255,0,0,0.1)',
      cursor: 'pointer'
    }
  });

  var dragSurface = new Surface({
    content: 'Drag Me',
    size: [100, 100],
    properties: {
      backgroundColor: 'rgba(0,0,0,0.1)',
      cursor: 'pointer'
    }
  });

  var modifier = new Modifier({
    origin: [0, 0],
    align: [0, 0],
    transform: transTransform
  });

  var draggable = new Draggable();

  draggable.subscribe(dragSurface);
  //draggable.pipe(surface._eventOutput);
  surface._eventOutput.subscribe(draggable);
  
  surface.setContent('Not Draggable');
  surface.on('updated', function(e) {
    var pos = e.position;
    this.setContent('Draggable Position is ' + pos);
    transTransform.set(Transform.translate(pos[0] + 100, pos[1], 0));
  });
  surface.on('ended', function(e) {
    var pos = e.position;
    this.setContent('Draggable End Position is ' + e.ending);
    transTransform.setTranslate([pos[0] + 100, pos[1], 0], {
      duration: e.duration
    });
  });

  mainContext.add(modifier).add(surface);
  mainContext.add(draggable).add(dragSurface);

  draggable.on('update', function(e) {
    this.eventOutput.emit('updated', {
      position: e.position
    });
  });

  draggable.on('end', function(e) {
    var finalPos = [0, 0];
    var duration = 300
    this.eventOutput.emit('ended', { position: finalPos, ending: e.position, duration: duration });
    this.setPosition(finalPos, { duration: duration });
  });
});

// Start Main App
require(['main']);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://requirejs.org/docs/release/2.1.16/minified/require.js"></script>
<script src="http://code.famo.us/lib/requestAnimationFrame.js"></script>
<script src="http://code.famo.us/lib/classList.js"></script>
<script src="http://code.famo.us/lib/functionPrototypeBind.js"></script>

<link rel="stylesheet" type="text/css" href="http://code.famo.us/famous/0.3.5/famous.css" />

<script src="http://code.famo.us/famous/0.3.5/famous.min.js"></script>

New: Using the Draggable as a transform reference

define('main', function(require, exports, module) {
  var Engine = require('famous/core/Engine');
  var Surface = require('famous/core/Surface');
  var Transform = require('famous/core/Transform');
  var Modifier = require('famous/core/Modifier');
  var StateModifier = require('famous/modifiers/StateModifier');
  var Draggable = require('famous/modifiers/Draggable');
  var TransitionableTransform = require('famous/transitions/TransitionableTransform');

  var mainContext = Engine.createContext();

  var transTransform = new TransitionableTransform();
  transTransform.set(Transform.translate(100, 0, 0));

  var surface = new Surface({
    size: [300, 100],
    properties: {
      backgroundColor: 'rgba(255,0,0,0.1)',
      cursor: 'pointer'
    }
  });

  var dragSurface = new Surface({
    content: 'Drag Me',
    size: [100, 100],
    properties: {
      backgroundColor: 'rgba(0,0,0,0.1)',
      cursor: 'pointer'
    }
  });

  var draggable = new Draggable();

  var modifier = new Modifier({
    origin: [0, 0],
    align: [0, 0],
    transform: getTransform
  });

  function getTransform() {
    var pos = draggable.getPosition();
    surface.setContent('Draggable Position is ' + pos);  //needs performance enhancement
    transTransform.setTranslate([pos[0]+100,pos[1],0]);
    return transTransform.get();
  }

  draggable.subscribe(dragSurface);

  surface.setContent('Not Draggable');

  mainContext.add(modifier).add(surface);
  mainContext.add(draggable).add(dragSurface);

  draggable.on('update', function(e) {
    
  });

  draggable.on('end', function(e) {
    var finalPos = [0, 0];
    var duration = 300
    this.setPosition(finalPos, {
      duration: duration
    });
  });
});

// Start Main App
require(['main']);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://requirejs.org/docs/release/2.1.16/minified/require.js"></script>
<script src="http://code.famo.us/lib/requestAnimationFrame.js"></script>
<script src="http://code.famo.us/lib/classList.js"></script>
<script src="http://code.famo.us/lib/functionPrototypeBind.js"></script>

<link rel="stylesheet" type="text/css" href="http://code.famo.us/famous/0.3.5/famous.css" />

<script src="http://code.famo.us/famous/0.3.5/famous.min.js"></script>

New: Using the Draggable as a transform reference with events

define('main', function(require, exports, module) {
  var Engine = require('famous/core/Engine');
  var Surface = require('famous/core/Surface');
  var Transform = require('famous/core/Transform');
  var Modifier = require('famous/core/Modifier');
  var StateModifier = require('famous/modifiers/StateModifier');
  var Draggable = require('famous/modifiers/Draggable');
  var TransitionableTransform = require('famous/transitions/TransitionableTransform');

  var mainContext = Engine.createContext();

  var transTransform = new TransitionableTransform();
  transTransform.set(Transform.translate(100, 0, 0));

  var surface = new Surface({
    size: [300, 100],
    properties: {
      backgroundColor: 'rgba(255,0,0,0.1)',
      cursor: 'pointer'
    }
  });

  var dragSurface = new Surface({
    content: 'Drag Me',
    size: [100, 100],
    properties: {
      backgroundColor: 'rgba(0,0,0,0.1)',
      cursor: 'pointer'
    }
  });

  var draggable = new Draggable();

  var modifier = new Modifier({
    origin: [0, 0],
    align: [0, 0],
    transform: transTransform
  });

  function getTransform() {
    var pos = draggable.getPosition();
    surface.setContent('Draggable Position is ' + pos);
    transTransform.setTranslate([pos[0] + 100, pos[1], 0]);
    return transTransform.get();
  }

  draggable.subscribe(dragSurface);
  surface._eventOutput.subscribe(draggable.eventOutput);

  surface.on('updating', function(e) {
    var pos = e.position;
    surface.setContent('Draggable Position is ' + pos);
    transTransform.setTranslate([pos[0] + 100, pos[1], 0]);
  });
  surface.on('startedEnd', function(e) {
    modifier.transformFrom(getTransform);
  });
  surface.on('endedEnd', function(e) {
    modifier.transformFrom(transTransform);
  });

  surface.setContent('Not Draggable');

  mainContext.add(modifier).add(surface);
  mainContext.add(draggable).add(dragSurface);

  draggable.on('update', function(e) {
    this.eventOutput.emit('updating', {
      position: e.position
    });
  });

  draggable.on('end', function(e) {
    var finalPos = [0, 0];
    var duration = 2000
    this.eventOutput.emit('startedEnd', {
      position: e.position,
      finalPos: finalPos
    });
    this.setPosition(finalPos, {
      duration: duration
    }, function() {
      this.eventOutput.emit('endedEnd', {
        position: this.position
      });
    }.bind(this));
  });
});

// Start Main App
require(['main']);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://requirejs.org/docs/release/2.1.16/minified/require.js"></script>
<script src="http://code.famo.us/lib/requestAnimationFrame.js"></script>
<script src="http://code.famo.us/lib/classList.js"></script>
<script src="http://code.famo.us/lib/functionPrototypeBind.js"></script>

<link rel="stylesheet" type="text/css" href="http://code.famo.us/famous/0.3.5/famous.css" />

<script src="http://code.famo.us/famous/0.3.5/famous.min.js"></script>
talves
  • 13,993
  • 5
  • 40
  • 63
  • This is not *quite* what I'm looking for. I'm aware of how to do what you've done. Using the TransitionableTransform is a different way of accomplishing what I've already done with GenericSync and StateModifier. My question is when I have a Transform on the Draggable that makes it move to a position on end (eg. bounce or snap to original position) how do I get that Transform data position and/or delta? – rjmoggach Mar 16 '15 at 19:41
  • I updated my question to include your snippet updated as it relates to my question... I want both boxes to return on end. – rjmoggach Mar 16 '15 at 19:55
  • You are adding to your question and now it has become two part. Also, I do not agree with you copying my code into your question. Just refer to my code. I will attempt to answer what you are asking though. – talves Mar 16 '15 at 20:47
  • Hopefully these edits address your needs. Remember, the custom events that are emitted could be sent to a view or render node that contains your `draggable`. – talves Mar 16 '15 at 22:30
  • removed your code - accepted your answer - i thought the original question was clear in asking for the position **after** the on end event, hence the clarification - thank you for the answer... putting it to good use now – rjmoggach Mar 16 '15 at 22:34
  • I thought your original answer was asking for the position that is returned, but I understand what you mean now. No problem. Thanks for being patient. – talves Mar 16 '15 at 22:36
  • FYI - your code doesn't update the text in the non-draggable box - it's stuck at the 'end' position would be nice to see that update reactively as well (and slow down the transition so it's obvious) – rjmoggach Mar 16 '15 at 22:36
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/73114/discussion-between-mogga-and-talves). – rjmoggach Mar 16 '15 at 22:38
  • Thanks. I did add one more example snippet to switch the transforms for performance with events. – talves Mar 17 '15 at 04:16