Famo.us: From Zero to UI
Transcript of Famo.us: From Zero to UI
![Page 1: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/1.jpg)
famo.usFrom Zero to UI
![Page 2: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/2.jpg)
What is famo.us?
![Page 3: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/3.jpg)
The Building Blocks
![Page 4: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/4.jpg)
1 var Engine = require('famous/core/Engine'); 2 3 var mainContext = Engine.createContext(); 4 // set webkit-perspective on the context's div 5 mainContext.setPerspective(1000);
App Setup
![Page 5: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/5.jpg)
1 var Surface = require('famous/core/Surface'); 2 var surface = new Surface({ 3 // pixel size 4 size: [50,50], 5 // html 6 content: '<h1>Hi</h1>', 7 // css 8 properties: { 9 backgroundColor: 'red', 10 backfaceVisibility: 'visible' 11 }, 12 // classes 13 classes: ['classA', 'classB'], 14 });
HTMLSurface
![Page 6: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/6.jpg)
1 var mainContext = Engine.createContext(); 2 mainContext.setPerspective(1000); 3 4 var surface = new Surface({ 5 size: [50,50], 6 properties: { 7 backgroundColor: 'red', 8 backfaceVisibility: 'visible' 9 }, 10 }); 11 12 mainContext.add(surface);
App Setup
![Page 7: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/7.jpg)
Controlling the Render Tree
A
B C
1 a.add(b).add(c) 2 3 // or 4 var bNode = a.add(b); 5 bNode.add(c);
1 a.add(b) 2 a.add(c)
A
B
C
Nested Children Children as Siblings
![Page 8: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/8.jpg)
Animatable Properties
![Page 9: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/9.jpg)
Properties within the Render Tree
Transform Origin Align Opacity Size Proportions
A
B
C
![Page 10: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/10.jpg)
Transforms (Matrices)
![Page 11: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/11.jpg)
1 // Translation 2 Transform.translate(20, 10, 10); 3 4 // Rotation 5 Transform.rotateY(Math.PI) 6 Transform.rotateX(Math.PI) 7 Transform.rotateZ(Math.PI) 8 Transform.rotate(Math.PI, Math.PI, Math.PI); 9 10 // Scale 11 Transform.scale(0.5, 0.5) 12 13 // Skew 14 Transform.skew(0.5, 0.5, 0.5)
Matrix 3D: Basic Transforms
![Page 12: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/12.jpg)
Transform Multiplication
a x b !== b x a
![Page 13: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/13.jpg)
1 // Multiplication 2 Transform.multiply( 3 Transform.translate( 50, 50, 50 ), 4 Transform.rotateX( Math.PI ) 5 ); 6 7 Transform.moveThen( 8 [50, 50, 50], // same as Transform.translate 9 Transform.rotateX( Math.PI ) 10 ); 11 12 13 // DIFFERENT! a x b !== b x a 14 Transform.multiply( 15 Transform.rotateX( Math.PI ), 16 Transform.translate( 50, 50, 50 ) 17 ); 18 19 Transform.thenMove( 20 Transform.rotateX( Math.PI ), 21 [50, 50, 50] // same as Transform.translate 22 );
Matrix 3D: Advanced Transforms
![Page 14: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/14.jpg)
Origin & Align
![Page 15: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/15.jpg)
Origin
[0.5, 0.5] [0, 0] [1, 0] [1, 1] [0, 1]
![Page 16: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/16.jpg)
Align
![Page 17: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/17.jpg)
Alignorigin
align
[0.5, 0.5] [0, 0] [1, 0] [1, 1] [0, 1]
[0.5, 0.5]
[0, 0]
[1, 1]
![Page 18: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/18.jpg)
Proportions
![Page 19: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/19.jpg)
Proportions
[1, 1] [0.5, 1] [0.5, 0.5]
![Page 20: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/20.jpg)
Size
[undefined, undefined]
[undefined, true]
[true, 200]
undefined expand to width of containing bar
true match the size of the HTML
number hard coded size
Can be mixed together for width and height:
![Page 21: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/21.jpg)
Animating Properties
![Page 22: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/22.jpg)
Transitionables / Modifiers 1 var tt = new TransitionableTransform(); 2 modifier.transformFrom(tt); 3 4 tt.set(Transform.translate(100,100)); 5 function move () { 6 tt.set(Transform.translate(200, 100), { 7 duration: 500, 8 curve: 'outExpo' 9 }) 10 .set( 11 Transform.thenMove( 12 Transform.rotateX(Math.PI), 13 [200, 200] 14 ) , { 15 duration: 1500, 16 curve: 'outExpo' 17 }) 18 .set(Transform.translate(100, 100), { 19 duration: 500, 20 curve: 'outExpo' 21 }, move); 22 } 23 24 this.add(modifier).add(surface); 25 move();
![Page 23: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/23.jpg)
Animating Properties
![Page 24: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/24.jpg)
MoveableSurface
getOptions
setOptions
add
render
halt
delayByKey
getOrigin / setOrigin
getAlign / setAlign
getSize / setSize
getTransform / setTransform
getOpacity / setOpacity
getOpacity / setOpacity
getProportions / setProportions
MoveableSurface
getAttributes / setAttributes
getProperties / setProperties
getContent / setContent
removeClass
toggleClass
setClasses
getClassList
addClass
getProportions / setProportions
addListener / on
removeListener / off
![Page 25: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/25.jpg)
MoveableSurface In Practice 1 var surf = new MoveableSurface({ 2 size: [50,50], 3 properties: { 4 backgroundColor: 'red', 5 backfaceVisibility: 'visible' 6 } 7 }); 8 9 surf.setTransform(Transform.translate(100,100)); 10 function move() { 11 surf 12 .setTransform(Transform.translate(200, 100), { 13 duration: 500, 14 curve: 'outExpo' 15 }) 16 .setTransform( 17 Transform.thenMove( 18 Transform.rotateX(Math.PI), 19 [200, 200] 20 ) , { 21 duration: 1500, 22 curve: 'outExpo' 23 }) 24 .setTransform(Transform.translate(100, 100), { 25 duration: 500, 26 curve: 'outExpo' 27 }, move); 28 }; 29 this.add(surf); 30 move();
![Page 26: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/26.jpg)
Inheritance Chain
![Page 27: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/27.jpg)
Prototypal Inheritance 1 function Parent () { 2 this.name = 'parent'; 3 } 4 5 Parent.prototype.logName = function () { 6 console.log(this.name); 7 } 8 9 function Child () { 10 Parent.apply(this, arguments); 11 this.name = 'child' 12 } 13 14 Child.prototype = Object.create(Parent.prototype); 15 Child.prototype.constructor = Child; 16 17 var child = new Child(); 18 child.sayHi();
![Page 28: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/28.jpg)
MoveableSurface Inheritance
getOptions
setOptions
add
render
MoveableView
halt
delayByKey
getOrigin / setOrigin
getAlign / setAlign
getSize / setSize
getTransform / setTransform
getOpacity / setOpacity
getOpacity / setOpacity
getProportions / setProportions
MoveableSurface
getAttributes / setAttributes
getProperties / setProperties
getContent / setContent
removeClass
toggleClass
setClasses
getClassList
addClass
getProportions / setProportions
Event Emitter
addListener / on
removeListener / off
emit
![Page 29: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/29.jpg)
MoveableView 1 define(function(require, exports, module) { 2 var MoveableView = require('famous-moveable/MoveableView'); 3 var MoveableSurface = require('famous-moveable/MoveableSurface'); 4 var Transform = require('famous/core/Transform'); 5 6 function SceneOne () { 7 MoveableView.apply(this, arguments); 8 9 var surfOne = new MoveableSurface({ 10 size: [50,50], 11 properties: { 12 backgroundColor: 'red', 13 backfaceVisibility: 'visible' 14 } 15 }); 16 17 var surfTwo = new MoveableSurface({ 18 size: [50,50], 19 properties: { 20 backgroundColor: 'red', 21 backfaceVisibility: 'visible' 22 }, 23 transform: Transform.translate(50, 0) 24 }); 25 26 this.add(surfOne); 27 this.add(surfTwo); 28 } 29 30 SceneOne.prototype = Object.create(MoveableView.prototype); 31 SceneOne.prototype.constructor = SceneOne; 32 33 module.exports = SceneOne; 34 });
SceneOne
surfOne surfTwo
![Page 30: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/30.jpg)
Instantiating a MoveableView
1 var Engine = require('famous/core/Engine'); 2 var SceneOne = require('./one'); 3 // create the main context 4 var mainContext = Engine.createContext(); 5 mainContext.setPerspective(1000); 6 7 var myScene = new SceneOne() 8 mainContext.add(myScene); 9 10 myScene.setTransform(Transform.translate(50, 50)); 11
![Page 31: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/31.jpg)
View Options 1 function SceneOne () { 2 // same as before 3 } 4 5 SceneOne.DEFAULT_OPTIONS = { 6 customOption: 'optionA' 7 } 8 9 SceneOne.prototype = Object.create(MoveableView.prototype); 10 SceneOne.prototype.constructor = SceneOne; 11 12 var myScene = new SceneOne(); 13 myScene.options.customOption // -> 'optionA' 14 15 var customScene = new SceneOne({ 16 customOption: 'optionB' 17 }); 18 19 customScene.options.customOption // -> 'optionB'
![Page 32: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/32.jpg)
View Events 1 function SceneOne () { 2 // same as before 3 var self = this; 4 this.count = 0; 5 setInterval(function() { 6 self.count++; 7 self.emit('hi', self.count); 8 }, 1000); 9 } 10 11 SceneOne.prototype = Object.create(MoveableView.prototype); 12 SceneOne.prototype.constructor = SceneOne; 13 14 var myScene = new SceneOne(); 15 function log () { 16 console.log(arguments); 17 } 18 19 // listening to events 20 myScene.on('hi', log); 21 22 // stop listening to events 23 myScene.off('hi', log);
![Page 33: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/33.jpg)
MoveableView Recap• Rendering • Root Node with control over all animatable properties • Options Management • Eventing
![Page 34: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/34.jpg)
UI
![Page 35: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/35.jpg)
Button 1 function Button () { 2 MoveableView.apply(this, arguments); 3 this._button = new MoveableSurface(); 4 this._button.on('click', this.clickAnimation.bind(this)); 5 } 6 7 Button.prototype = Object.create(MoveableView.prototype); 8 Button.prototype.constructor = Button; 9 10 Button.prototype.clickAnimation = function () { 11 this._button.setTransform(Transform.translate(0,0, -50)); 12 this._button.setTransform(Transform.identity, { 13 duration: 500, 14 curve: 'outExpo' 15 }); 16 this.emit('selected'); 17 }
![Page 36: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/36.jpg)
Animation Design Pattern 1 function Button () { 2 MoveableView.apply(this, arguments); 3 this._button = new MoveableSurface(); 4 this._button.on('click', this.clickAnimation.bind(this)); 5 } 6 7 Button.prototype = Object.create(MoveableView.prototype); 8 Button.prototype.constructor = Button; 9 10 Button.prototype.clickAnimation = function () { 11 Button.animations.click[this.options.animation].call(this); 12 this.emit('selected'); 13 } 14 15 16 Button.DEFAULT_OPTIONS = { 17 animation: 'fadeOut' 18 } 19 20 Button.animations = { 21 animation: { 22 fadeOut: function (elem) { 23 this._button.setTransform(Transform.translate(0,0, -50)); 24 this._button.setTransform(Transform.identity, { 25 duration: 500, 26 curve: 'outExpo' 27 }); 28 } 29 } 30 }
![Page 37: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/37.jpg)
Layout
![Page 38: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/38.jpg)
Using Layout
1 var Layout = require(‘famous-moveable/Layout'); 2 var Layout = require('famous-moveable/SequentialLayout'); 3 4 var barLayout = new Layout({ 5 children: [ 6 buttonOne, 7 buttonTwo, 8 buttonThree 9 ], 10 layout: new SequentialLayout(), 11 }); 12 13 this.add(barLayout);
![Page 39: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/39.jpg)
Creating Custom Layouts
1 function LayoutBase (options) { 2 this.options = Utility.clone(this.constructor.DEFAULT_OPTIONS || {}); 3 this._optionsManager = new OptionsManager(this.options); 4 if (options) this.setOptions(options); 5 } 6 7 LayoutBase.DEFAULT_OPTIONS = {}; 8 9 LayoutBase.prototype.layout = function (children, sizes) {}; 10 LayoutBase.prototype.getSize = function (children, sizes) {}; 11 12 LayoutBase.prototype.setOptions = function (options) { 13 this._optionsManager.patch(options); 14 return this; 15 }
![Page 40: Famo.us: From Zero to UI](https://reader033.fdocuments.us/reader033/viewer/2022051618/55caed46bb61eb914f8b4574/html5/thumbnails/40.jpg)
Demo
github.com/timjchin/famous-moveable github.com/timjchin/famous-moveable-demo