1

I'm working through use of Draggable and GenericSync with famous and meteor famous-views package and not understanding (obviously)

I'd like to drag a surface with constraints and perform another action when predetermined limits are reached. I'm learning and from the examples I've found, I haven't been able to get this working with the degree of flexibility I'm looking for. Please help! I'm sure it's one or two lines to get me back on track.

Here's my simplified template (wrapped in a RenderController within a HeaderFooterView):

<template name="test4">
{{#View origin='[.5,.5]' align='[.5,.5]'}}
  {{>Surface id="cube4" template="cubeFace4" class="grayDarker" size="[400,400]" properties="padding:20px" modifier="Draggable"}}
{{/View}}
</template>

<template name="cubeFace4">
  <div style="width: 90%; height: 90%; margin: 5.5% auto;">
    {{>svgFamoWrapped}}
  </div>
</template>

and some coffeescript:

Template.test4.rendered = ->
  @fview = FView.byId 'cube4'
  @drag = @fview.modifier # modifier is 'Draggable'
  @cube = @fview.surface
  position = [0,0]
  # cube.pipe drag

  @drag.setOptions
    xRange: [-500,500]
    yRange: [-10,10]
    projection: 'Famous.Draggable._direction.x'

  @sync = new Famous.GenericSync ['mouse','touch'] #,
    # direction: Famous.GenericSync.DIRECTION_X

  @cube.pipe @drag
  @drag.pipe @sync

  @drag.on 'update', (data) ->
    position[0] += data.delta[0]
    position[1] += data.delta[1]
    console.log data
    @drag.setPosition position

  @drag.on 'end', =>
    drag.setPosition [0,0],
      curve: 'outElastic'
      duration: 400
rjmoggach
  • 1,458
  • 15
  • 27
  • [@mogga](http://stackoverflow.com/users/586932/mogga) do you want the answer using famono and coffeescript? If not, [I have answered a similar question using pure famo.us](http://stackoverflow.com/questions/28866020/how-to-get-famo-us-draggable-modifiers-render-node/28907214#28907214). – talves Mar 14 '15 at 18:01
  • @talves yes to both and also considering famous-views - I have my own solution I'll post shortly – rjmoggach Mar 14 '15 at 19:47

1 Answers1

1

As I've found after much trial and error Draggable is a convenience wrapper and GenericSync makes it easier to have the degree of flexibility I wanted.

The following template has a ContainerSurface to hold content and a transparent 'drag control' surface to drive both.

<template name="square">
  {{#ContainerSurface size="[undefined,undefined]" origin='[0.5,0.5]' align='[0.5,0.5]' perspective=getPerspective overflow="hidden"}}
    {{#StateModifier id="square" size="[400,400]" origin="[0.5,0.5]" align="[0.5,0.5]" transform=squareTransform }}
      {{#StateModifier size="[400,400]" origin="[0.5,0.5]" align="[0.5,0.5]" translate="[0,0,0]"}}
        {{>Surface template="squareContent" class="grayDarker backfaceVisible" size="[undefined,undefined]"}}
      {{/StateModifier}}
    {{/StateModifier}}
    {{#StateModifier size="[400,400]" origin="[0.5,0.5]" align="[0.5,0.5]" transform=dragTransform }}
      {{>Surface id="dragCtl" template="emptyDiv" size="[400,400]" class="redBorder" }}
    {{/StateModifier}}
  {{/ContainerSurface}}
</template>

Here's the coffeescript I used to make the surface draggable with respect to a separate drag control surface.

Template.square.created = ->
  position = [0,0]
  Session.set 'dragPosition',position


Template.square.helpers
  'dragTransform': ->
    position = Session.get 'dragPosition'
    absPosX = Math.abs position[0]
    limX = Math.round (window.innerWidth * 0.5)
    if absPosX < limX
      position[0] = position[0]
    else
      position[0] = Math.sign(position[0]) * limX
    console.log Famous.Transform
    Famous.Transform.translate(position[0],position[1],0)

  'squareTransform': ->
    position = Session.get 'dragPosition'
    limX = Math.round (window.innerWidth * 0.5)
    if Math.abs(position[0]) > limX
      position[0] = Math.sign(position[0]) * limX
    Famous.Transform.translate(position[0],position[1],0)

Template.square.rendered = ->
  position = [0,0]
  Session.set 'dragPosition',position
  Session.set 'perspective',1000

  dragFV = FView.byId 'dragCtl'
  dragSrf = dragFV.surface
  drag = dragFV.modifier

  @sync = new Famous.GenericSync ['mouse','touch']

  dragSrf.pipe @sync

  @sync.on 'update', (data) ->
    position[0] += data.delta[0]
    position[1] += data.delta[1]
    Session.set 'dragPosition',position

  @sync.on 'end', =>
    position = [0,0]
    Session.set 'dragPosition',[0,0]

Notes

  1. Perspective is driven by a UI.helper named getPerspective that gets it's value from a session var.
  2. As a sidebar, it's probably obvious I'm not totally clear on the proper use of this/@ with respect to javascript context as it relates to my code
rjmoggach
  • 1,458
  • 15
  • 27