A week ago, Raix , the author of Famono package used for integrating Require.js and Famo.us with Meteor.js , has published a new release that simplifies greatly the integration.I was willing to demonstrate just that when a nice demo of Famo.us 's physic engine has shown up on my radar: http://hbsand.com/HappyBoxes/ . So why not demonstrating both?You can access the live demo here: http://famousbubble.meteor.com/ You can also clone the code repository from Github: https://github.com/PEM--/famousbubble : The current release of Chrome, the 36, has a bug that stops the demo running after ~1-2s. This bug is fixed in Chrome Canary version 37. I didn't see it on the current Chrome for Android or iOS. Firefox and Safari work well on OSX.

So, lets get down to business. The first step is to create the app:

client/lib/smart.require

{ "famous": { "git": "https://github.com/Famous/famous.git" }, "famousPolyfills": { "git": "https://github.com/Famous/polyfills.git" } }

Linking Famo.us with Meteor.js

client/startup/famous.coffee

# This is equivalent to: require 'famousPolyfills' famousPolyfills # Identically, this is equivalent to: require 'famous.core.famous' famous.core.famous # Declaring the main context window.mainCtx = famous.core.Engine.createContext()

client/index.jade

head title Famo.us - Physic demo meta(name='viewport', content='width=device-width, maximum-scale=1, user-scalable=no') meta(name='mobile-web-app-capable', content='yes') meta(name='apple-mobile-web-app-capable', content='yes') meta(name='apple-mobile-web-app-status-bar-style', content='black') body +index template(name='index')

client/stylesheets/app.styl

@import nib html font-family: Helvetica, Arial, sans-serif * -webkit-user-drag: none body -webkit-user-callout: none user-select: none background-color: #FF851B

client/index.coffee

index

Template.index.rendered = -> $(document).ready -> window.appView = new AppView() mainCtx.add appView appView.addDragger() appView.addBubbles()

Easier subclassing

AppView

client/views/AppView.coffee

index

class @AppView extends famous.core.View DEFAULT_OPTIONS: numBodies: 10 gravity: [0, 0.0015, 0] constructor: (@options)-> @constructor.DEFAULT_OPTIONS = @DEFAULT_OPTIONS super @options surf = new famous.core.Surface size: [400, 400] properties: backgroundColor: '#FFDC00' borderRadius: '8px' mod = new famous.core.Modifier origin: [.5, .5] @add(mod).add surf @gravity = new famous.physics.forces.Force @options.gravity @ceiling = new famous.physics.constraints.Wall normal: [0, 1, 0] distance: 200 restitution: 0 @floor = new famous.physics.constraints.Wall normal: [0, -1, 0] distance: 200 restitution: 0 @left = new famous.physics.constraints.Wall normal: [1, 0, 0] distance: 200 restitution: 0 @right = new famous.physics.constraints.Wall normal: [-1, 0, 0] distance: 200 restitution: 0 @pe = new famous.physics.PhysicsEngine() @collision = new famous.physics.constraints.Collision restitution: 0 @bubbleBodies = [] famous.inputs.GenericSync.register 'mouse': famous.inputs.MouseSync 'touch': famous.inputs.TouchSync addDragger: -> @dragger = new Dragger() @pe.addBody @dragger.body (@_add @dragger.state).add @dragger.shape sync = new famous.inputs.GenericSync ['mouse', 'touch'] @dragger.shape.pipe sync sync.on 'update', (data) => @dragger.position[0] += data.delta[0] @dragger.position[1] += data.delta[1] @dragger.body.setPosition @dragger.position addBubble: (i) => bubble = new Bubble() @pe.addBody bubble.body bubble.state.transformFrom => @gravity.applyForce bubble.body bubble.body.getTransform() (@add bubble.state).add bubble.shape @pe.attach [@right, @left, @floor, @ceiling], bubble.body (@pe.attach @collision, @bubbleBodies, bubble.body) if i > 0 @pe.attach @collision, [bubble.body], @dragger.body @bubbleBodies.push bubble.body addBubbles: -> [0...@options.numBodies].map (i) => famous.utilities.Timer.setTimeout (@addBubble.bind @, i), 1000

View

client/views/Dragger.coffee

class @Dragger RADIUS: 30 constructor: -> @shape = new famous.core.Surface size: [2 * @RADIUS, 2 * @RADIUS] properties: border: '2px solid #FF4136' borderRadius: "#{2 * @RADIUS}px" backgroundColor: 'rgba(255, 255, 255, 0.5)' @body = new famous.physics.bodies.Circle radius: @RADIUS mass: 5 @position = [0, 0] @state = new famous.core.Modifier origin: [.5, .5] transform: => famous.core.Transform.translate @position[0], @position[1], 0

client/view/Bubble.coffee

class @Bubble constructor: -> radius = famous.math.Random.integer 20, 60 @shape = new famous.core.Surface size: [radius * 2, radius * 2] properties: backgroundColor: '#7FDBFF' border: '3px solid #0074D9' borderRadius: "#{radius}px" @body = new famous.physics.bodies.Circle radius: radius, mass: 2 @state = new famous.core.Modifier origin: [.5, .5]

Conclusion

For the imported Require.js package, I keep it at the bare minimum. Famono places the imported packages from a file calledThis has not changed from the early version.In Famono , what has changed is the way you require your dependencies. Theis greatly reduced:Everything is now imported into the main context of Meteor.js . There is no more boilerplate code.Our main Jade file,stays unchanged:The Styus file,, is also unchanged:Like the former file, the associated CoffeeScript fileto thetemplate is almost unchanged either:As the Famo.us's University told us, you create your views by inheriting from Famo.us 's ones. With Famono , it is now simplified. Here the code for thethat we just call in the previous file, thetemplate:As you can see it, the inheritance from a Famo.us 'sdoes not require you to wait for Famo.us to be loaded in your document. Additionally, the require step has been greatly simplified. Calling any class provided by Famo.us is done with a simple namespaced call.I've create 2 more classes. The first one,concerns the little dragging bubble used to play with the blue bubbles:The second one,concerns the bubble themselves:With the new Famono release, integrating Famo.us and Meteor.js is simpler than ever. My little sample is missing few things. A better separation of the controller from the views would be great. But, there is some upcoming Famo.us lessons that should arrive in the Famo.us's University . Therefore, they will surely cover their best practices. No rush.