0

I want to do a scroll list with bunch of surface images. Then when I click or touch on a surface, I want to get the surface object being affected and do something with it (like change content).

The way I setup below is to have scrollview -> container -> view -> modifier -> surface. I don't know if it is efficient or not (maybe redundant). But I cannot get the exact object triggering event in console.log(data) of each sync object.

define(function(require, exports, module) {
  var Engine = require('famous/core/Engine');
  var Surface = require('famous/core/Surface');
  var ContainerSurface = require("famous/surfaces/ContainerSurface");
  var View             = require('famous/core/View');
  var Scrollview         = require('famous/views/Scrollview');

  var Transform = require('famous/core/Transform');
  var Modifier   = require("famous/core/Modifier");

  var GenericSync = require("famous/inputs/GenericSync");
  var MouseSync   = require("famous/inputs/MouseSync");
  var TouchSync   = require("famous/inputs/TouchSync");

  var mainContext = Engine.createContext();

  GenericSync.register({
      "mouse" : MouseSync,
      "touch" : TouchSync
  });

  var scrollview = new Scrollview({});

  var listContainer = [];
  var questionContainer = [];
  var imgSurface = [];
  var sync = [];

  var imgModifier = new Modifier({origin: [0.5, 0.5]});

  for (var i=0; i<10; i++) {
    questionContainer[i] = new ContainerSurface({
      size: [undefined, 300],
      properties:{
        overflow: 'hidden'
      }
    });

    imgSurface[i] = new Surface({
      content: '<img width="100%" src="http://placehold.it/400x300">'
    });

    sync[i] = new GenericSync(
        ["mouse", "touch"],
        {direction : GenericSync.DIRECTION_X}
    );

    questionContainer[i].add(imgModifier).add(imgSurface[i]);

    questionContainer[i].pipe(sync[i]);
    questionContainer[i].pipe(scrollview);

    sync[i].on("end", function(data) {
      console.log(data);
    });

    listContainer.push(questionContainer[i]);
  }

  scrollview.sequenceFrom(listContainer);
  mainContext.add(scrollview);
});

So how do I access the triggering surface or view in this case? I was hoping to get something like data.triggerObject.setContent() that referenced back to that particular surface in the array. Well, such thing doesn't seem to exist...

UPDATE 1:

The answer doesn't need to follow my code above. My "high level" goals are:

  1. Generate a list of surfaces with images. Data from some array.

  2. Detect click AND touch event per surface and do something with that surface

Basically, I tried to do an "advance" version of this example https://github.com/Famous/examples/blob/master/src/examples/core/View/example.js

HP.
  • 19,226
  • 53
  • 154
  • 253

1 Answers1

1

So GenericSync is working as an aggregator of the the Sync classes. The Sync classes give you useful information based on simpler events such as mousedown and mousemove. That means if you want more information, you are going to have to make MouseSync, for example, give it up.

If you do not wish to write your own MouseSync class, just take a look at where MouseSync emits its events. In the event handling function, you may access the original event. You can attach whatever you wish to the payload that is emitted.. Take for example _handleEnd in MouseSync.js

function _handleEnd(event) {
    if (!this._prevCoord) return;

    // I added this line..
    this._payload.origin = event.origin;

    this._eventOutput.emit('end', this._payload);
    this._prevCoord = undefined;
    this._prevTime = undefined;
}

If it feels too strange editing the source directly and tracking changes, you may just want to duplicate MouseSync to a different classname eg. MyMouseSync and make changes to only that file. The same logic applies to TouchSync.

Hope this helps!

EDIT TO YOUR UPDATED QUESTION:

You can use the default events available through famous surfaces. These include the origin property in the payload.

mousedown, mousemove mouseup, touchstart, touchmove, touchend

surface.on('touchstart',function(e){
    touchedSurface = e.origin;
});

In most of these cases, I would detect touch with something like Modernizr, and only apply the necessary events. Good Luck!

johntraver
  • 3,612
  • 18
  • 17
  • My goal is to detect which surface is touch/click. Is this supposed to be this complicated? Is there a workaround for the same goal? It doesn't have to follow my code above. I updated the question above. – HP. May 30 '14 at 06:02
  • So I have to do `surface.on('touchstart',function(e){});` and `surface.on('click',function(e){});` separately? Because I don't think Famo.us can do combined events in list like `touchstart click` right? – HP. May 30 '14 at 18:40
  • Yea it can't do combined events yet.. just define one function and bind to each event. Again, you might not want to apply both for touch devices or the same code may be run twice. – johntraver May 30 '14 at 19:08
  • So I tested this `surface.on('touchstart',function(e){});` on real iPhone / Cordova and it didn't work. `surface.on('click',function(e)` works on desktop click though. Any idea? – HP. May 30 '14 at 22:33
  • So I found out that 'click' works for both click and touch on mobile. There is no 'touchstart'. That is strange!! – HP. Jun 01 '14 at 03:12
  • Interesting.. I have had touchstart work on mobile for sure, I am usually using touchend though.. – johntraver Jun 01 '14 at 03:19
  • In the Tassky demo example, I didn't see any 'touchend' event either. Its all 'click' and it works on both desktop and mobile – HP. Jun 02 '14 at 00:37