famo.us lightbox demo transition

555 Views Asked by At

I'm trying to get a transition that is similar to the lightbox demo that famous has put out. I have a grid layout, when I click a surface in the grid, Id like to have the surface transition, grow in size and be centered in the browser window.

--edit Here is the demo, what I would like to nail is the flyout of the clicked image from its location to the center of the screen. http://demo.famo.us/lightbox/

I have the following code that I've been using as a basis. http://codepen.io/heyimlance/pen/JooQMX

var Engine = famous.core.Engine;
var Surface = famous.core.Surface;
var GridLayout = famous.views.GridLayout;
var StateModifier = famous.modifiers.StateModifier;
var Transform = famous.core.Transform;
var RenderNode = famous.core.RenderNode;
var Easing = famous.transitions.Easing;

var mainContext = Engine.createContext();

var grid = new GridLayout({
    dimensions: [8, 8],
});

var surfaces = [];

grid.sequenceFrom(surfaces);

function newSurface(id) {
    var surface = new Surface({
        content: id + 1,
        properties: {
            backgroundColor: "hsl(" + (id * 70 / 64) + ", 60%, 70%)",
            lineHeight: '50px',
            textAlign: 'center'
        }
    });

    var smod = new StateModifier({
      size: [50,50],
      transform: Transform.translate(0,0,1),
      origin: [.5,.5]
    });
    var rnode = new RenderNode();
    rnode.add(smod).add(surface);
    surfaces.push(rnode);

    surface.on('click', function() {
        console.log(smod)
        var zpos = (this.up || this.up == undefined) ? 0 : -180;
        if (!zpos) {

            this.up = false;
            smod.setTransform(Transform.translate(0,0,2000), { curve:Easing.outElastic, duration: 1000 })
            gridModifier.setTransform(Transform.translate(0,0,-2000), { curve:Easing.outElastic, duration: 500 })
        } else {
            this.up = true;
            gridModifier.setTransform(Transform.translate(0,0,0), { curve:Easing.outElastic, duration: 400 })
            smod.setTransform(Transform.translate(0,0,0), { curve:Easing.outElastic, duration: 1000 })

        }

    });
}

for(var i = 0; i < 64; i++) {
    newSurface(i);
}

var gridModifier = new StateModifier({
    size: [400, 400],
    align: [.5, .5],
    origin: [.5, .5],
    transform : Transform.translate(0,0,0),
});

var gridRotate = new StateModifier({
    transform : Transform.rotate(0,0,0),
});


mainContext.add(gridModifier).add(grid);
mainContext.setPerspective(1000);
2

There are 2 best solutions below

3
On

I think the best way is to follow "StateModifier" example that you can find in famo.us university : http://famo.us/university/lessons/#/famous-102/transitionables/2

Do a scale :

// animates x- and y-scale to 1
stateModifier.setTransform(
    Transform.scale(1, 1, 1),
    { duration : 2000, curve: Easing.outBack }
);

and then a align [0.5, 0.5] :

var alignModifier = new Modifier({
    align: [0.5, 0.5]
});

and if you want background to be minified, you have to apply 'scale' modifier too to make all other surfaces smaller.

3
On

Using your code, I made a few changes to use the Lightbox render contoller at the time of the click. Not sure what transition you would like for the grid and surface, this should give you options to transition as you like.

Here is a codepen of the example

The code:

var Engine = famous.core.Engine;
var Surface = famous.core.Surface;
var GridLayout = famous.views.GridLayout;
var StateModifier = famous.modifiers.StateModifier;
var Transform = famous.core.Transform;
var RenderNode = famous.core.RenderNode;
var RenderController = famous.views.RenderController;
var Lightbox = famous.views.Lightbox;
var Easing = famous.transitions.Easing;

var mainContext = Engine.createContext();

var grid = new GridLayout({
  dimensions: [8, 8],
});

var surfaces = [];

var showing;

grid.sequenceFrom(surfaces);

var cmod = new StateModifier({
  origin: [0.5, 0.5],
  align: [0.5, 0.5]
});
var controller = new Lightbox({
  inTransition: true,
  outTransition: false,
  overlap: true
});
controller.hide();

function newSurface(id) {
  var surface = new Surface({
    size: [undefined, undefined],
    content: id + 1,
    properties: {
      backgroundColor: "hsl(" + (id * 70 / 64) + ", 60%, 70%)",
      lineHeight: '50px',
      textAlign: 'center',
      cursor: 'pointer'
    }
  });

  surface._smod = new StateModifier({
    size: [420,420],
    origin: [0.5, 0.5],
    align: [0.5, 0.5]
  });
  surface._rnode = new RenderNode();
  surface._rnode.add(surface._smod).add(surface);

  surfaces.push(surface);

  surface.on('click', function(context, e) {
    if (this === showing) {
      controller.hide({ curve:Easing.inElastic, duration: 1000 }, function(){
        gridModifier.setTransform(Transform.scale(1,1,1), 
            { curve:Easing.outElastic, duration: 1000 });
      });
      showing = null;
    } else {
      showing = this;
      gridModifier.setTransform(Transform.scale(0.001, 0.001, 0.001),
                        { curve:Easing.outCurve, duration: 300 });
      cmod.setTransform(Transform.translate(0, 0, 0.0001));
      controller.show(this._rnode, { curve:Easing.outElastic, duration: 2400 });
    }

  }.bind(surface, mainContext));
}

for(var i = 0; i < 64; i++) {
  newSurface(i);
}

var gridModifier = new StateModifier({
  size: [400, 400],
  align: [0.5, 0.5],
  origin: [0.5, 0.5]
});

mainContext.add(gridModifier).add(grid);
mainContext.add(cmod).add(controller);
mainContext.setPerspective(1000);