29 déc. 2014

Access all famo.us examples without downloading the starter kit

One neat trick that we have used on famous-views to set some links to famo.us examples is to use rawgit. A nice service that allow exposing a Github page. Simply choose an index.html file from  Github and make it available using rawgit. Here is the link created for famo.us examples: http://rawgit.com/Famous/famous/master/examples/index.html.

28 déc. 2014

Debugging server side REST calls with mitmproxy in Meteor

Introduction

Isomorphic javascript offers a great flexibility for developper letting them choose where the code will get executed. On the clients or on the servers. While the Chrome DevTools have evolved at an impressive pace allowing to easily debug and see what is going on with your client's REST calls, the state of server side debugging may be a little bit deceptive in this field. Hence, when you need to put data fetching within your server, checking the flows of requests / responses could be a bit cumbersome if you solely rely on transaction logs or node-inspector. You could use technics like packet sniffing using Wireshark but setting a proper environment when using TLS with your REST call is a huge configuration process.

This is where mitmproxy comes to the rescue. Its name says it all: Man In The Middle PROXY. This incredible tool relies on the same technics as the infamous security attack, this time, for a greater purpose. For this article, I'm using mitmproxy as a local proxy server allowing me to trace all outgoing and incoming transactions from my server side Meteor app. Note that it is not the only use case that mitmproxy offers. Actually, this tool is incredibly agile allowing you to debug your mobile apps with great ease. Let us put our white hat on.

Installation on OSX

Using homebrew for installing mitmproxy is a one command line call:
brew install mitmproxy
Note that this steps actually installs 2 tools mitmproxy and mitmdump as well as a set of certificates in ~/.mitmproxy. We only use the first tool in this article but the second one could be handy when you need a lightweight display of your transaction flow and an easy way to save them in a replayable log. Note also that if you also intend to use mitmproxy for debugging other applications like native client ones, you can accept the certificate ~/.mitmproxy/mitmproxy-ca-cert.pemcertificate in OSX that mitmproxy has created just for you. Just a caveat here. When you set your proxy settings in OSX, be sure to remove the local filters that Apple gently put for you if you want to see your native apps talking to your local servers.

Here's a little screenshot of a debugging session using mitmproxy:

Not that isomorphic

For REST calls, Meteor comes with its own isomorphic library: HTTP. On the client, it acts as basic AJAX calls, while on the server, it relies on the request module. Like all isomorphic libraries, this allows you to put your code logic in your clients or in your server with a nice and uniform API. But this comes at a price, it only covers the features that makes sense for both the clients and the server.

A server is not a browser. Indeed, while having cookies on the browser make sense for retaining states in your application for each user, cookies on the server starts to be a weird concept. Are these cookies used for the clients that you will serve or should the server could be seen as a client to another server? The same goes for the proxy settings on a server. Why would you need a proxy on a production server? Therefore, what is available on the client side of your app may not be available on the server side. 

Unfortunately, you could have use cases where the REST API that you are using within your server may need cookies (which is a bit weird when speaking of REpresentational State Transfer which should rely on state-less operations ☺).  Additionally, for debugging our flows, we also need the proxy capabilities that are offered out of the box by our browsers. This is where comes the nice package http-more from dandv. It exposes some already baked in feature of the request module for your server side REST calls.

You install it by replacing Meteor's default package like so:
meteor remove http
meteor add dandv:http-more

Proxyfy your REST calls in your server

Now that our toolbox is setup, it is time to orient our server so that it takes advantages of mitmproxy. This is achieved via the freshly exposed options in the HTTP library.

For orienting your request to the proxy, play nice with your TLS layer and setting a cookie jar:
HTTP.get url,
  proxy: 'http://127.0.0.1:8080'
  strictSSL: false
  jar: true
, (e, r) ->
  console.log 'GET sent through the proxy :-)'
Now, you should see all your flows of your server on mitmproxy.

Some nice mitmproxy shortcuts and moves

mitmproxy's documentation is clear and very helpful. But before let you dive in, I'm sharing some of my most used shortcuts:
  • C to clear the list of flows.
  • and for selecting a flow.
  • for seeing the details of an exchange and q to go back to the list.
  • in detail of a flow to switch between the request and the response.
When you need to save a mitmproxy session for comparing it with other ones, you can use the save feature:
mitmproxy -w FILENAME

Once saved, you can reread it and modify it to only spare the relevant parts of your flows:
mitmproxy -nr FILENAME
Where:
  • n prevents to launch a proxy server.
  • r read the previous saved file.
For the editing your flows, use the following shortcuts:
  • d for deleting flows.
  • e for editing a request or a response.
  • w then a for saving your all your modifications of the flows for the session.
  • q then y for quitting edition mode.
Another nice move is mitmproxy's capabilities to replay a session. For instance, you can replay the client part of your spared session or the server part just by specifying -c or -s respectively. Very handy for debugging without assaulting the REST service that your implementing or using:
mitmproxy -c FILENAME

14 déc. 2014

Put your HTML, CSS and JS in a single file using Meteor

It could be a bit cumbersome to switch from your HTML template file to your JS logic to your CSS stylesheets. I consider that the method exposed hereafter isn't tailored for novice users. Still, it can help you understanding how Meteor works.

Actually, the method is quite simple. It all drills down to how the HTML files are generated using Blaze, the reactive UI. During the build process of your app, Meteor builds JS file out of your HTML template file and exposes / sends them to your clients. This method short-circuits the build process. If you write directly your HTML using Blaze, the reactive UI, you remove the HTML file. The second step is to use JS to write your CSS. Here, I use the CSSC package for Meteor.

Here is the results for an equivalent of the default Meteor  app.
You could think of it as a small component into a larger app.

And now, here is the code to create this small component. As promised, a single file, in CoffeeScript for brevity:
# Render the body when Meteor is ready
Meteor.startup Template.body.renderToDocument

# HTML
# ----
# Instantiate a main template
Template['main'] = new Template 'Template.main', ->
  # Return a table of DOM elements
  [
    # A 'p' tag with a reactive variable
    HTML.P 'Count ', Blaze.View => Spacebars.mustache @lookup 'count'
    # A 'button' tag
    HTML.BUTTON '+1'
  ]

# JS logic
# --------
# Declare a reactive variable
Session.set 'count', 0
# Expose the reactive variable to the template
Template.main.helpers 'count': -> Session.get 'count'
# Handle template events
Template.main.events
  'click button': (e,t) ->
    e.preventDefault()
    Session.set 'count', 1 + Session.get 'count'
# Add the template to the document's body
Template.body.addContent ->
  Spacebars.include @lookupTemplate 'main'

# CSS
# ---
# Instantiate a stylesheet
css = new CSSC
# Style the body and the text
css.add 'body',
  margin: CSSC.px 20
  backgroundColor: CSSC.navy
  color: CSSC.aqua
# Style the button
.add 'button',
  width: CSSC.px 50
  border: "#{CSSC.px 1} #{CSSC.maroon} solid"
  borderRadius: CSSC.px 3
  backgroundColor: CSSC.red
  color: CSSC.yellow

If you want to test it yourself, here is the set of required commands:
# Start by creating a simple app.
meteor create singlefile
cd singlefile
# Remove the Meteor's default app.
rm *
# We are going to focus only on the front.
# Our single file is being placed in the client directory.
mkdir client
# Add the necessary packages.
meteor add coffeescript pierreeric:cssc pierreeric:cssc-colors pierreeric:cssc-normalize
# Create your single file and start editing it.
touch client/main.coffee

At the beginning, it may look a bit weird. But this could be useful from time to time. Note that you can put some nice additions to this sample. For instance, instead of using the events helpers which will scan you DOM for the button, you could directly affect the click event logic when you are creating the button element. If you are looking for performances on some parts of your app, this could be an interesting technic.

10 déc. 2014

The fastest loading screen for Meteor

Introduction

Meteor offers a great way to build web apps at an incomparable speed. It leverages the power of Javascript anywhere. In production, its powerful server side build system named Isobuild transpiles all your HTML files into JS files, thanks to Blaze, and packs them with your JS files. This operation leads to a single JS file loaded by a tiny initial HTML loader that bootstraps your app.

Depending on your development strategy, this single JS file can end up very fat. This could seriously annoy your first time users who will wait many seconds before seing something on their screen. Of course, proxying your servers with Gzip or SPDY capable fronts greatly helps lowering this initial loading. Truncating this JS file could also help. Using a multiple domains strategy and CDNs also offer great loading time cuts. Still, on mobile, with a bad network access like GPRS, these several seconds rapidly become a problem. To understand the ins and outs of web performance optimization, WPO, I strongly recommend reading the book High Performance Browser Networking by Ilya Grigorik.

What is this about?

Not to be confused with the great masterpiece fast render from Arunoda Susiripala which is used for fastening the initial data required from your collections, the technic that I expose hereafter tackles the initial page load time, PLT. The first paints on the screen, if you prefer. This first paint comes even before the tiny initial HTML loader is fully loaded by your users's terminal.

On a regular Meteor app, while your users connect to your site and till the initial load of the JS file, their browser remains blank. Of course, they could see that something is happening. Almost all browser display at least a progress indicator. But users may not notice it and think that your site is either dead or hosted on a distant other planet. That is just very bad for user acquisition, isn't it? If you want to better understand how this affects user's perceptions as well as your search engine optimization strategy, SEO, Paul Irish has covered this in great details in his incredibly informative talk: Fast enough (check the comments for the slides and the Youtube video). What you need to know is that your PLT will be nice if your initial screen painting is under 14k. That seems like an impossible goal to achieve with an out-of-the-box Meteor app with an average weight of ~50k of compressed initial JS file.

But Meteor is far from being a classic website approach and is definitely not a low end build tool. You can use the raw power of its Isobuild to ask your servers for an injection of your initial screen content directly within the tiny initial HTML loader. It is the key to unlock the 14k barrier.

Performing the injection

This could be a bit scary for the majority of Meteor devs. But once again, Arunoda has you well covered. By using another great masterpiece from Arunoda and Gadi Cohen, this injection process is a no brainer: inject initial. Let us jump in the code.

In your app, installing inject initial is the one step classical stance:
meteor add meteorhacks:inject-initial
For the sake of brevity, the codes hereafter are in CoffeeScript.

In your server code, you can perform the initial injection. Hereafter, I'm just putting a little CSS spinner. Nothing fancy.

/server/startup.coffee
Inject.rawHead 'loader-style',
  # Force the initial scale for Android and iOS as our spinner may be
  #  distorted by their default viewport values.
  '<meta name="viewport" content="width=device-width,maximum-scale=1,' +
    'initial-scale=1,user-scalable=no">' +
  # The loading spinner needs some theming.
  '<style>' +
    'html{background-color: #36342e;}' +
    'body{color:#ddd;overflow:hidden;width:100%;}' +
    '.spinner {' +
      'bottom:0;height:80px;left:0;margin:auto;position:absolute;' +
      'top:0;right:0;width:80px;' +
      '-webkit-animation: rotation .6s infinite linear;' +
      'animation: rotation .6s infinite linear;' +
      'border-left:6px solid rgba(255,194,0,.20);' +
      'border-right:6px solid rgba(255,194,0,.20);' +
      'border-bottom:6px solid rgba(255,194,0,.20);' +
      'border-top:6px solid rgba(255,194,0,.9);' +
      'border-radius:100%;' +
    '}' +
    '@-webkit-keyframes rotation {' +
      'from {-webkit-transform: rotate(0deg);}' +
      'to {-webkit-transform: rotate(359deg);}' +
    '}' +
    '@-moz-keyframes rotation {' +
      'from {-moz-transform: rotate(0deg);}' +
      'to {-moz-transform: rotate(359deg);}' +
    '}' +
    '@-o-keyframes rotation {' +
      'from {-o-transform: rotate(0deg);}' +
      'to {-o-transform: rotate(359deg);}' +
    '}' +
    '@keyframes rotation {' +
      'from {transform: rotate(0deg);}' +
      'to {transform: rotate(359deg);}' +
    '}' +
    '</style>'
# The loading spinner is a CSS animation.
# /!\ WARNING: The trick is to create a fake body by injecting data
# in the HTML's head as Meteor is requesting JS  file in a blocking
# fashion and mobile only allow 1 HTTP request at a time on a GPRS network.
Inject.rawHead 'loader-body2', '<body><div class="spinner"></div></body>'
Here we have somewhat altered, the DOM structure of our app. Indeed, we have just created a body while the head of your your initial HTML loader wasn't even finished to get build. Is that a big problem? No. Your server will carry on filling the rest of your app in the body section that you have created (the styles, the scripts, ...).

At this point, you could tell me: "But wait? There is now a title and meta tags in the body of my app. That's just a disgusting code.". You are right. But the browsers are really not impacted by this. I could reply back: "Who care?". But, indeed, I care. Simply because one of the biggest interest of web technology is that all your codes are readable. It is important to let other developers having the possibility to understand how stuff works. It is part of the learning legacy that we owe to the web. So let us put things in the correct order.

Cleaning our loaded codes is done directly on the client side. We do that once everything is loaded. No hurry as it has no impact except a good readability of our DOM structure.

/client/startup.coffee
Meteor.startup ->
  # Reshape DOM: put back title and meta elements in the head.
  # style and script tags can leave in the body tag.
  $head = $ 'head'
  for tag in ['meta', 'title']
    $tags = $ tag
    $head.append $tags.clone()
    $tags.remove()
That's it. Nice and clean.

Testing it

There are several ways of testing these results and their behavior. On Mac, I use Network link conditionner, a handy tool provided by Apple. It allows you to modify the behavior of you TCP stack and use GPRS, 3G, ... profiles. Very neat when you are testing hybrid or native apps.

If you are testing full web apps, I strongly recommend using Chrome DevTools. The mobile emulator as a special feature allowing to change the network throttling.

Some constraints you need to be aware of

When your initial HTML loader and your initial JS file are being loaded, the JS engine and the SVG rendering engine are paused. I've always been annoyed by this browser behavior but we have to live with it. Thus, you can't put JS loaders or SVG animated loaders. You should favor CSS loader and choose the one that will be the less CPU intensive. Here, you should favor CSS3 animated loader which are animated by the GPU as the CPU will be intensively interpreting what it is finishing pumping from you servers.

A side note to finish this little article. This technic is not here to bypass the necessary work of making your app as lightweight as possible. It is still a good practice to ensure that your app will avoid consuming the data subscription of your users ;-)

8 déc. 2014

7 déc. 2014

3D hardware accelerated SVG using famo.us and Meteor

One of the main problem with SVG for Android or Chrome, desktop and mobile, is the lack of hardware acceleration. Multiple issues also prevents some nice effects like skewing for instance. Making smooth animated SVG in a browser or in Cordova tends to be tricky.

As stated in one of my former blog post, famo.us makes a good candidate for removing this pain and Meteor, with its famous-views package, makes a good candidate for tying up everything together.

This weekend, I've started working on a famous-views's plugin named fview-svg. Basically, it reads your SVG as template and create famo.us's Surface and StateModifier out of it. One of the sensitive parts of the process was the inverted coordinate system of SVG compare to DOM and SVG's responsive nature. But the beauty of making it a plugin with famous-views is that it will be available for anyone. Nice.

Here is a little video that demonstrates my first demo with fview-svg:

As you can check it in the source code, without the comments, this demo is less than 20 lines of codes. And there is room for improvements.

I've deployed a live demo and you can play with it: fview-svg.

I've tested on desktop in Safari, Chrome, Firefox and Opera. On iOS8, I've tested it, an iPad Mini, an iPad 2, an iPhone 5S. On Android, I've tested it on release 4.4.2 on a Samsung Galaxy Tab and on release 4.0.3 on an HTC Desire C. And this is this last test that just surprised me. You may not even know what this terminal is. It's a low end smarphone. Very cheap. A single core under 1GHz. What Android call a midpi. These terminals still equip a large portion of Android's market share. Just to give you a glimpse on these terminals, it doesn't even run the first Angry birds properly... And here, the SVG animation was perfect. Fluid. I almost shed a tear.

The source codes of the plugin as well as a tutorial for recreating this demo are available on Github:  fview-svg.

Note: The plugin is not already available on Atmosphere, the official Meteor repository. I wand to test it against several additional demos to check which API would be good to export for easing the integration. Still, you can start cloning it and import it in your project if you want to contribute or cannot wait few days.

1 déc. 2014

Some Famo.us demo with Meteor

Lately with famous-views, a package for Meteor, we have added some plugins for easing developments. To better demonstrate how to use them and what they bring, I've added some live demo for each one that I've created.

Here is a fast access to these demo:


30 nov. 2014

Responsive SVG devices for famo.us and Meteor

Introduction

When creating a landing page or when demonstrating an app, there are often some smartphone, tablet or desktop screenshots. This pattern of demonstration could be a bit enhanced if instead of simple screenshots, the real app could be demonstrated. That would be the power of HTML5 sets in motion.

The base component

Famo.us has a nice component that could be leverage for that: the ContainerSurface. It is basically a small context that can be clipped. By living in the same space of your main web site, it allows interesting demonstration patterns where you could demonstrate your app. The problem is to display this context exactly on the device that you want to present.

By using an adaptive or a responsive SVG, you can extract coordinates of the device screen where you want to present your app. You can then instantiates a ContainerSurface on this same coordinates and put you app as its content.

In this little plugin fview-devices for famous-views, a Meteor package, this is exactly what is done. Here is a little demonstration of it:

You can also play with it in this live demo: fview-devices.

Conclusion

Beyond this little example, some interesting points emerge such as the capability to mix SVG and Famo.us. It paves the way to further enhancements. For instance, CSS Transform and Animation are possible in SVG. Unfortunately, they are not hardware accelerated. Worst, some browsers have very uneasy bugs to circumvent. By extracting portions of SVG and putting them into Famo.us surfaces, you regain hardware acceleration and circumvent issues from wrong implementations. Basically, you open up wider the capability to use SVG to the mobile platforms.

It seems to me that a new story of apps using SVG, Famo.us and Meteor is about to begin. Happy coding.

Famo.us dot loader animation using Meteor's Famous-Views

A simple customizable dot loader ported for famous-views:

Source code: fview-dotloader

Demo site: fview-dotloader

Original work: LeXXik and Talves.

25 nov. 2014

Famo.us FlexGrid in CoffeeScript with Meteor

Did I just post something similar few hours ago? Indeed very similar. But this time, this goes on a very different scale. The same demonstration is now reactive with datasources coming from a MongoDB, your session or any reactive dictionary that Meteor can provide. 


But wait... There's more. Actually, this is not a piece of code that you will paste into your Meteor project. It's a plugin. One command and one line of templating and it is set. One line of templating means: in just one single line of code.

This is all made possible thanks to the efforts of Gadi Cohen's excellent package's Famous-Views and his community (in which I contribute a bit).

Basically, here is how it works. Famo.us components are registered in the Meteor's templating engine. It can be regular components or home made ones. Using your favorite templating language, being Spacebar or Jade, you create the layout of your app. You connect your reactive datasource in your templating if they are already available or via small template helpers à la Meteor.  It's like Famo.us/Angular with a full stack JS framework. And if you are using Jade, it is like drawing the Famo.us rendering tree with your code and connect it with reactive data source.

As an example, here is the code required for creating the example displayed in the video:
// This is pretty basic for every mobile app. 
head
  title FlexGrid test
  meta(charset='utf-8')
  meta(name='viewport', content='width=device-width, maximum-scale=1, user-scalable=no')
  meta(name='apple-mobile-web-app-capable', content='yes')
  meta(name='apple-mobile-web-app-status-bar-style', content='black')
  meta(name='apple-mobile-web-app-capable', content='yes')
  meta(name='mobile-web-app-capable', content='yes')
body
  // Every Famo.us apps starts with a context.
  +famousContext id="mainCtx"
    // The code is divided into reusable templates
    // looking very much like web components.
    +flexGridExample

template(name='flexGridExample')
  // Now we create our 'render tree'.
  +Scrollview id='scrollview'
    // Here is the FlexGrid: it's indeed a single line of code!
    +FlexGrid id='flexgrid'
      // Here, I connect my datasource: a reactive array.
      +famousEach items
        // I use the available values in each item of the array
        // Note that CSS styles can be passed as reactive value,
        +Surface class='surf' properties=color
          // Or as reactive content.
          p= name

Simple. The community has also brought some others nice plugins that speeds up the creation of your app. The number of plugins available is growing fast.

Famo.us FlexGrid in CoffeeScript

A simple Pen to demonstrate how inheriting from a View by recreating Shu Liu's FlexGrid in CoffeeScript.

PS: Watch it in CodePen to better play with the viewport's size. It's nicely animated.
See the Pen FlexGrid in CS by Pierre-Eric Marchandet (@PEM--) on CodePen.

24 nov. 2014

A better inheritance base class for Famo.us widget in Meteor

In former articles, I've proposed a base class for inheriting from Famo.us. There was something odd on the way I was using the DEFAULT_OPTIONS. Actually, it should be a static members. It makes the code even easier to write.

Here is my fixed example:
class @MyWidget extends famous.core.View
  DEFAULT_OPTIONS:
    size: [undefined, undefined]
    # ... Put your expected defaults here
  constructor: (@options) ->
    super @options
    # ... Put your remaining initialization code here

23 nov. 2014

A reactive favico for Meteor: rxFavico

I've packaged the nice favico.js project for Meteor: rxFavico. The added bonus is that it's now reactive. You simply modify a reactive dictionary, your favico changes automatically and all your associated display as well. This is handy for coupling it with a mailbox widget or the results of tests while developing.
Here is how to install it:
meteor add pierreeric:rxfavico
Here is an example in CoffeeScript for using it:
rxFavico.set 'count', 10
The source are available on Github.

4 nov. 2014

CSS color manipulation and normalize in CoffeeScript

Following my former article Create your CSS styles in CoffeeScript for Meteor, I've updated the CSSC packages to Meteor 1.0.0 and add some new features and plugins. You can now add multiple rules in one call and calls are chainable:
if Meteor.isClient
  Meteor.startup ->
  @maincss = new CSSC
  @maincss
    .add 'html',
      backgroundColor: CSSC.yellow
      fontFamily: 'Helvetica Neue, Arial, sans-serif'
    .add 'body',
      fontSize: CSSC.px 20
    .add ['h1', 'h2'],
      backgroundColor: CSSC.red
A new plugin allows to create the same rules as Normalize.css: CSSC-Normalize. Just add it classically:
meteor add pierreeric:cssc-normalize
The CSSC-Colors has been updated with color manipulation features:
# You can create basic RGB color from an hex String
c = new CSSC.Clr '#FF4136'
# From an hex string with alpha transparency
c = new CSSC.Clr ['#FF4136', .3]
# From the provided colors
c = new CSSC.Clr CSSC.yellow
# From some RGB value
c = new CSSC.Clr [255, 60, 0]
# From some RGB value with alpha transparency
c = new CSSC.Clr [255, 60, 0, .3]
# From some HSL value
c = new CSSC.Clr ['hsl', .5, 1, .5]
# From some HSL value with alpha transparency
c = new CSSC.Clr ['hsl', .5, 1, .5, .3]

# Once you have chosen your color, whatever the color schemes
#  that you use, you can modify its value.
# Lets add some 20% saturation
c.set 's', 1.2 * c.get 's'
# Lets lighten it by 30%
c.set 'l', 1.3 * c.get 'l'
# Lets make less opaque by 10%
c.set 'a', .9 * c.get 'a'

# Now that we are finished with it use as a simple string where you want.
# Through an automatic conversion
String c
# As a regular hex string
c.toString()
# As a CSS rgba value
c.rgba()  # rgba(255, 60, 0, .3)
# As a CSS hsl value
c.hsl()   # hsl(240, 100%, 50%)
# As a CSS hsla value
c.hsla()   # hsl(240, 100%, 50%, .3)

27 oct. 2014

Charts for easy choosing your Famo.us easing functions

Famo.us provides 30 different easing functions for tweening animations. Choosing the most appropriate one will give you the best results possible before creating your own if none matches your expectations.

With these charts, choosing is going to be far more easier:
See the Pen Famo.us easing functions by Pierre-Eric Marchandet (@PEM--) on CodePen.

Flare demo in Famo.us

A very simple Famo.us demo inspired from the 3d demo of Julian Shapiro.
See the Pen Flare 3D demo in Famo.us by Pierre-Eric Marchandet (@PEM--) on CodePen.

26 oct. 2014

Atom is getting ready for Meteor 1.0.0

Thanks to Ben Strahan, Atom.io is getting ready for the upcoming Meteor-1.0.0 with the Meteor-Helper package.

There are also few others fixes  and enhancements that you can see on the release notes: https://github.com/PEM--/meteor-helper/releases


A mind blowing talk from Douglas Crockford at Nordic.js 2014

This is just great. Hard to ingest. It is mind blowing but so true. Though, the video is titled the better parts, the bad parts are really interesting and worth hearing many times.

25 oct. 2014

Setup a Famo.us experiment using Codepen.io

I've created a CodePen for easing creation of experiments with Famo.us. It uses Jade and CoffeeScript as its defaults and imports Famo.us and jQuery in their minified version. Fork it and play with it. Happy coding!
See the Pen Famo.us simple physic box by Pierre-Eric Marchandet (@PEM--) on CodePen.

Create your slide deck using Famo.us and Meteor

Introduction

Yesterday, there was the Paris Famo.us Meetup organized by AdFab and Meetic France. I was presenting the first part, which consists of a live coding or demo showcasing. I intended to demonstrate some basic techniques on Famo.us's physic engine. Live coding is tough. There are always some "demo effect" and time runs out very quickly.

Fortunately, for this demo preparation, I created some slides. As the meetup was about Famo.us, I decided to code my slide deck using... Famo.us and Meteor.

The slides are deployed on Meteor: MeetupFamousSlides.


The core components

If you think about a presentation tool, it only consists of static pages that you present one after the other. This is definitely the job of iron:router.

Creating each slide is easily done when you are using a templating system with emphasis on semantic. Jade and Markdown fit very well in this equation. Therefore, I ended up choosing mquandalle:jade. Each slide is a single Jade file. Thanks to the power of Meteor, you can write additional logic in the template for animating the slide's content.

Speaking of animations, modern slide deck use some of them. Famo.us is really a nice framework for this task. But coupling Meteor and Famo.us is a bit tedious. This is where enters gadiccohen:famous-views. It bridges both worlds with an incredible ease of use. I strongly recommend you to have an eye on it.

Conclusion and code reuse

In less than 2 hours, the presentation engine was ready and I had a basic presentation. Adding slides was a no brainer simply consisting in updating the router and adding a Jade file.

You can find the code of the engine and the slide deck on this Github repository.



12 oct. 2014

Create your CSS styles in CoffeeScript for Meteor

I've created my first Meteor package today: CSSC. This package eases the creation of CSS stylesheets in CoffeeScript.

For using it, adds the package into your Meteor's project:
meteor add pierreeric:cssc
Once done, just create your stylesheets using DOM and CSSOM notation. For instance, I will create 2 classes selected and unselected:
if Meteor.isClient
  Meteor.startup ->
    css = new CSSC

    css.add '.selected',
      margin: CSSC.x 3
      border: "3px solid #{CSSC.yellow}"
      borderRadius: CSSC.x 5
    css.add '.unselected',
      color: CSSC.yellow
As you can see it, the syntax is close to what you would use in Stylus or SASS (when using .sass notation).

I've also created 2 plugins for this package:
With Meteor, this package and its plugins, you don't have to send CSS files to your client. Everything is packed within a single JS file.

15 sept. 2014

Free symbol font for IDE

I've created a free symbol fonts for any IDE that would like to integrate symbols. Here is a sample:
The font is under the MIT licence and available in my repo: FontClassesAndMethods. Feel free to modify it, tweak it, fork it, ...

13 sept. 2014

Debug Meteor with Atom and customize Meteor's access to MongoDB

I've just updated my Atom.io's plugin Meteor Helper with 2 new features: debug mode and custom Mongo URL.

For debugging your Meteor's server side app, just set the Debug flag, launch a Node-Inspector and open your Chrome navigator on the URL provided by Node-Inspector. Basically, it covers the Step 2 of the Meteorpedia article on debugging.

For launching Meteor so that it uses an alternate MongoDB instance, you simply specify the access to this instance. Default installation of MongoDB are usually accessed via mongodb://localhost:27017. Revert back to the classical MongoDB within Meteor, blank the content of the Mongo URL input field.

19 juil. 2014

Do we need HTML and CSS when we got JavaScript or more? A case for AbsurdJS, Meteor, Famo.us and CoffeeScript.

Introduction

AbsurdJS is an amazing project. What is it about? A processor for your HTML and CSS in JavaScript. In JSON to be more precise.

The problem

CSS was invented for designers. But do you really know that much designers that are able to provide you with a nice CSS rules that will be awesome on all screens? You are favored by gods if it is your case. Most of the time, they will provide you with some PSD (what an ugly form of design), AI (if you are lucky), Sketch or SVG (here, it is not anymore based on luck, it is like having an angel upon your shoulders).

The same goes with HTML. Semantics that appears with HTML5 were added for SEO. But do you know that much SEO guys that will give you the right HTML code? I haven't seen any in my whole 20 years on the web carrier(though SEO is not that long of a job).

Thus, why are we using 3 languages for writing our codes. Is that right? Do we have to? Is it done for helping us and keeping separation of concerns? Funny. Patterns like this exists since the dawn of design patterns from the GoF. And what if we need to synchronize this HTML, CSS and JS back together for animations purposes? We request back in our code the HTML tags that we have just declared? We hooks on the CSS? If we need a color theme, do we have to write it twice or more? Funny, too. Even media queries for responsive web designs, seems like an odd way of reproducing the abstract factory pattern (or the bridge depending on if you know to who you are distributing your files).

The solutions

There are many. Generally, I was keen on using preprocessors: SASS, LESS, Stylus, YAML, Jade, Blade, CoffeeScript, Typescript, Dart, ... But, it finally does not give me a proper answer to the problems previously mentioned. It still need glue code to make all of this work together properly. Things started to shape up when I end up using MeteorFamo.us and Velocity.js. The Blaze component of Meteor is transforming your HTML, more precisely, your HTML templates using Spacebar, a derivative of Mustache, into JS code. The same goes with Famo.us. It creates HTML and CSS rules that plays well together so that they limit layout trashing issues and combines this technics with advanced physic and animation engine. The same goes with Velocity.js. This jQuery plugins brings back synchronized CSS animations in with JS.

Still, plain vanilla JavaScript is a pain to write. While there are plenty of transpilers that could lessen the burden (like Dart and Typescript, to mention the most used ones), none have proven to be as easy as CoffeeScript to me.

Conclusion

Now the solution starts to shape up. Why not use the power of AbsurdJS, Meteor, Famo.us and CoffeeScript? This combination would be a real full stack. It would goes from the persistance layer, the application server to the front end with one and only one language. A transpiled one that even lessen the number of lines that you need to write.

14 juil. 2014

Jade within Atom.io: Fasten your HTML and SVG authoring and template debugging

When writing HTML, XML, SVG or templates based on this language, it is cumbersome to open and close tags. Even with a good editor that closes tags for you or a good plugin that write snippet codes, you end up with unreadable and long source files. Jade removes this hassle by providing a simple and elegant code that transpiles to tagged code.

Here's an example of Jade transpiled to HTML:

However, it is sometime handy to seen what your generated code will look like. I've published another Atom.io plugin that preview the generated results with ctrl+alt+j.

The package is available on Atom.io's repository: https://atom.io/packages/jade-compile
And its code source is available on Github: https://github.com/PEM--/jade-compile

9 juil. 2014

Meteor.js from within Atom.io: Full stack dev with live reload in one key combo

I've just published a simple Meteor plugin for Atom.io. It launches  Meteor with ctrl+alt+m. Whenever any problem is found on the server, a pane shows up from a dedicated status bar to warn you that something is going wrong.

The package is available on Atom.io's repository: https://atom.io/packages/meteor-helper
And its code source is available on Github: https://github.com/PEM--/meteor-helper

Here's a nice and simple video showing what it brings:

4 juil. 2014

14 juin 2014

Some bubbles with Famo.us's physic engine in CoffeeScript and Meteor.js

Introduction

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

Note for Chrome users on OSX : 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.

Preparing your development environment

I suppose that you have already install Node.jsMeteor.js and Meteorite on your system. 

So, lets get down to business. The first step is to create the app:
mrt create FamousBubble
cd FamousBubble
rm -rf FamousBubble.*
mkdir -p client/stylesheets client/startup client/views
mrt add coffeescript
mrt add stylus
mrt add jade
mrt add famono

For the imported Require.js package, I keep it at the bare minimum. Famono places the imported packages from a file called client/lib/smart.require:
{
  "famous": {
    "git": "https://github.com/Famous/famous.git"
  },
  "famousPolyfills": {
    "git": "https://github.com/Famous/polyfills.git"
  }
}
This has not changed from the early version.

Linking Famo.us with Meteor.js

In Famono, what has changed is the way you require your dependencies. The client/startup/famous.coffee is greatly reduced:
# 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()

Everything is now imported into the main context of Meteor.js. There is no more boilerplate code.

Our main Jade file, client/index.jade stays unchanged:
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')

The Styus file, client/stylesheets/app.styl, is also unchanged:
@import nib

html
  font-family: Helvetica, Arial, sans-serif

*
  -webkit-user-drag: none

body
  -webkit-user-callout: none
  user-select: none
  background-color: #FF851B

Like the former file, the associated CoffeeScript file client/index.coffee to the index template is almost unchanged either:
Template.index.rendered = ->
  $(document).ready ->
    window.appView = new AppView()
    mainCtx.add appView
    appView.addDragger()
    appView.addBubbles()

Easier subclassing

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 the AppView, client/views/AppView.coffee that we just call in the previous file, the index template:
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
As you can see it, the inheritance from a Famo.us's View does 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, client/views/Dragger.coffee concerns the little dragging bubble used to play with the blue bubbles:
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

The second one, client/view/Bubble.coffee concerns the bubble themselves:
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

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.

9 juin 2014

Timbre demo from Famo.us University using Meteor.js and CoffeeScript

Introduction

As already demonstrated in my previous article Famo.us polaroid tutorial in CoffeeScript and within MeteorMeteor, CoffeeScript and Famo.us are incredibly useful tools for front end or full stack developers. This article just show the same principles with the Famo.us University Timbre tutorial. A live demo is deployed on Meteor's testing ground: http://famoustimbre.meteor.com/.

Show me the code, please

If you find yourself stuck at translating some JS concept to CoffeeScript while playing the nice tutorial from Famo.us University, I provide my code hereafter:
client/stylesheets/app.styl
@import nib

html
  font-family: Helvetica

*
  -webkit-user-drag: none

body
  -webkit-touch-callout: none
  user-select: none

client/index.jade
head
  title Famo.us Timbre
  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/lib/famous.coffee
window.Famous ?= {}

client/lib/timbre.coffee
window.Timbre ?= {}

client/startup/famous.coffee
# Import Famous
require 'famous/core/famous'
# Adds the famo.us dependencies
require 'famous-polyfills'
# Wait for document ready
$(document).ready ->
  # Load Famo.us libraries
  Famous.Engine           = require 'famous/core/Engine'
  Famous.Surface          = require 'famous/core/Surface'
  Famous.Transform        = require 'famous/core/Transform'
  Famous.View             = require 'famous/core/View'
  Famous.Modifier         = require 'famous/core/Modifier'
  Famous.StateModifier    = require 'famous/modifiers/StateModifier'
  Famous.HeaderFooter     = require 'famous/views/HeaderFooterLayout'
  Famous.ImageSurface     = require 'famous/surfaces/ImageSurface'
  Famous.FastClick        = require 'famous/inputs/FastClick'
  Famous.GenericSync      = require 'famous/inputs/GenericSync'
  Famous.MouseSync        = require 'famous/inputs/MouseSync'
  Famous.TouchSync        = require 'famous/inputs/TouchSync'
  Famous.GenericSync.register
    'mouse': Famous.MouseSync
    'touch': Famous.TouchSync
  Famous.Easing           = require 'famous/transitions/Easing'
  Famous.Transitionable   = require 'famous/transitions/Transitionable'
  Famous.Timer            = require 'famous/utilities/Timer'
  # Create main context
  Timbre.mainCtx = Famous.Engine.createContext()

client/models/StripData.coffee
Timbre.StripData = [
  {title: 'search', iconUrl: 'img/strip-icons/famous.png'}
  {title: 'starred', iconUrl: 'img/strip-icons/starred.png'}
  {title: 'friends', iconUrl: 'img/strip-icons/friends.png'}
  {title: 'settings', iconUrl: 'img/strip-icons/settings.png'}
]

client/index.coffee
ASPECT_RATIO = 320 / 548

Template.index.rendered = ->
  $document = $ document
  $document.ready ->
    docwidth = $document.width()
    docheight = $document.height()
    if docwidth / ASPECT_RATIO > docheight
      screenwidth = docheight * ASPECT_RATIO
      screenheight = docheight
    else
      screenwidth = docwidth
      screenheight = docwidth / ASPECT_RATIO
    appView = new Timbre.AppView()
    mainMod = new Famous.Modifier
      size: [screenwidth, screenheight]
    Timbre.mainCtx
      .add mainMod
      .add appView

client/models/AppView.coffee
$(document).ready ->
  class Timbre.AppView extends Famous.View
    DEFAULT_OPTIONS:
      openPosition: 276
      transition:
        duration: 300
        curve: Famous.Easing.inOutBack
      posThreshold: 138
      velTreshold: 0.75
    constructor: (@options) ->
      @constructor.DEFAULT_OPTIONS = @DEFAULT_OPTIONS
      super @options
      @menuToggle = false
      @pageViewPos = new Famous.Transitionable 0
      @createPageView()
      @createMenuView()
      @setListeners()
      @handleSwipe()
    createPageView: ->
      @pageView = new Timbre.PageView()
      @pageModifier = new Famous.Modifier
        transform: =>
          Famous.Transform.translate @pageViewPos.get(), 0, 0
      @add(@pageModifier).add @pageView
    createMenuView: ->
      @menuView = new Timbre.MenuView stripData: Timbre.StripData
      menuModifier = new Famous.StateModifier
        transform: Famous.Transform.behind
      @add(menuModifier).add @menuView
    setListeners: ->
      @pageView.on 'menuToggle', @toggleMenu
    toggleMenu: =>
      if @menuToggle
        @slideLeft()
      else
        @slideRight()
        @menuView.animateStrips()
      @menuToggle = !@menuToggle
    slideLeft: ->
      @pageViewPos.set 0, @options.transition, =>
        @menuToggle = false
    slideRight: ->
      @pageViewPos.set @options.openPosition, @options.transition, =>
        @menuToggle = true
    handleSwipe: ->
      sync = new Famous.GenericSync(
        ['mouse', 'touch']
      , {direction: Famous.GenericSync.DIRECTION_X}
      )
      @pageView.pipe sync
      sync.on 'update', (data) =>
        currentPosition = @pageViewPos.get()
        @pageViewPos.set Math.max 0, currentPosition + data.delta
        if currentPosition is 0 and data.velocity > 0
          @menuView.animateStrips()
      sync.on 'end', (data) =>
        velocity = data.velocity
        position = @pageViewPos.get()
        if position > @options.posThreshold
          if velocity < -@options.velTreshold
            @slideLeft()
          else
            @slideRight()
        else
          if velocity > @options.velTreshold
            @slideRight()
          else
            @slideLeft()

client/models/PageView.coffee
$(document).ready ->
  class Timbre.PageView extends Famous.View
    DEFAULT_OPTIONS:
      headerSize: 44
    constructor: (@options) ->
      @constructor.DEFAULT_OPTIONS = @DEFAULT_OPTIONS
      super @options
      @createLayout()
      @createHeader()
      @createBody()
      @setListeners()
    createLayout: ->
      @layout = new Famous.HeaderFooter
        headerSize: @options.headerSize
      layoutModifier = new Famous.StateModifier
        transform: Famous.Transform.translate 0, 0, .1
      @add(layoutModifier).add @layout
    createHeader: ->
      backgroundSurface = new Famous.Surface
        properties: backgroundColor: 'black'
      backgroundModifier = new Famous.StateModifier
        transform: Famous.Transform.behind
      @layout.header
        .add backgroundModifier
        .add backgroundSurface
      @hamburgerSurface = new Famous.ImageSurface
        size: [44, 44]
        content: 'img/hamburger.png'
      searchSurface = new Famous.ImageSurface
        size: [232, 44]
        content: 'img/search.png'
      iconSurface = new Famous.ImageSurface
        size: [44, 44]
        content: 'img/icon.png'
      hamburgerModifier = new Famous.StateModifier
        origin: [0, .5]
        align: [0, .5]
      searchModifier = new Famous.StateModifier
        origin: [.5, .5]
        align: [.5, .5]
      iconModifier = new Famous.StateModifier
        origin: [1, .5]
        align: [1, .5]
      @layout.header
        .add hamburgerModifier
        .add @hamburgerSurface
      @layout.header
        .add searchModifier
        .add searchSurface
      @layout.header
        .add iconModifier
        .add iconSurface
    createBody: ->
      @bodySurface = new Famous.ImageSurface
        size: [undefined, true]
        content: 'img/body.png'
      @layout.content.add @bodySurface
    setListeners: ->
      @hamburgerSurface.on 'click', =>
        @_eventOutput.emit 'menuToggle'
      @bodySurface.pipe @_eventOutput
    createBacking: ->
      backing = new Famous.Surface
        properties:
          backgroundColor: 'black'
          boxShadow: '0 0 20px rgba(0,0,0,0.5)'
      @add backing

client/models/MenuView.coffee
$(document).ready ->
  class Timbre.PageView extends Famous.View
    DEFAULT_OPTIONS:
      headerSize: 44
    constructor: (@options) ->
      @constructor.DEFAULT_OPTIONS = @DEFAULT_OPTIONS
      super @options
      @createLayout()
      @createHeader()
      @createBody()
      @setListeners()
    createLayout: ->
      @layout = new Famous.HeaderFooter
        headerSize: @options.headerSize
      layoutModifier = new Famous.StateModifier
        transform: Famous.Transform.translate 0, 0, .1
      @add(layoutModifier).add @layout
    createHeader: ->
      backgroundSurface = new Famous.Surface
        properties: backgroundColor: 'black'
      backgroundModifier = new Famous.StateModifier
        transform: Famous.Transform.behind
      @layout.header
        .add backgroundModifier
        .add backgroundSurface
      @hamburgerSurface = new Famous.ImageSurface
        size: [44, 44]
        content: 'img/hamburger.png'
      searchSurface = new Famous.ImageSurface
        size: [232, 44]
        content: 'img/search.png'
      iconSurface = new Famous.ImageSurface
        size: [44, 44]
        content: 'img/icon.png'
      hamburgerModifier = new Famous.StateModifier
        origin: [0, .5]
        align: [0, .5]
      searchModifier = new Famous.StateModifier
        origin: [.5, .5]
        align: [.5, .5]
      iconModifier = new Famous.StateModifier
        origin: [1, .5]
        align: [1, .5]
      @layout.header
        .add hamburgerModifier
        .add @hamburgerSurface
      @layout.header
        .add searchModifier
        .add searchSurface
      @layout.header
        .add iconModifier
        .add iconSurface
    createBody: ->
      @bodySurface = new Famous.ImageSurface
        size: [undefined, true]
        content: 'img/body.png'
      @layout.content.add @bodySurface
    setListeners: ->
      @hamburgerSurface.on 'click', =>
        @_eventOutput.emit 'menuToggle'
      @bodySurface.pipe @_eventOutput
    createBacking: ->
      backing = new Famous.Surface
        properties:
          backgroundColor: 'black'
          boxShadow: '0 0 20px rgba(0,0,0,0.5)'
      @add backing

client/models/StripView.coffee
$(document).ready ->
  class Timbre.StripView extends Famous.View
    DEFAULT_OPTIONS:
      width: 320
      height: 55
      angle: -0.2
      iconSize: 32
      iconUrl: 'img/strip-icons/famous.png'
      title: 'Famo.us'
      fontSize: 26
    constructor: (@options) ->
      @constructor.DEFAULT_OPTIONS = @DEFAULT_OPTIONS
      super @options
      @createBackground()
      @createIcon()
      @createTitle()
    createBackground: ->
      backgroundSurface = new Famous.Surface
        size: [@options.width, @options.height]
        properties:
          backgroundColor: 'black'
          boxShadow: '0 0 1px rgba(0, 0, 0, 1)'
      rotateModifier = new Famous.StateModifier
        transform: Famous.Transform.rotateZ @options.angle
      skewModifier = new Famous.StateModifier
        transform: Famous.Transform.skew 0, 0, @options.angle
      @add(rotateModifier)
        .add skewModifier
        .add backgroundSurface
    createIcon: ->
      iconSurface = new Famous.ImageSurface
        size: [@options.iconSize, @options.iconSize]
        content: @options.iconUrl
        properties:
          pointerEvents: 'none'
      iconModifier = new Famous.StateModifier
        transform: Famous.Transform.translate 24, 2, 0
      @add(iconModifier).add iconSurface
    createTitle: ->
      titleSurface = new Famous.Surface
        size: [true, true]
        content: @options.title
        properties:
          color: 'white'
          fontSize: "#{@options.fontSize}px"
          textTransform: 'uppercase'
          pointerEvents: 'none'
      titleModifier = new Famous.StateModifier
        transform: Famous.Transform.thenMove(
          Famous.Transform.rotateZ @options.angle
        , [75, -5, 0]
        )
      @add(titleModifier).add titleSurface

8 juin 2014

AdFab makes Badoit sparkling thanks to Famo.us

Famo.us has a physic engine. When used for animating screens, it's simply stunning.

4 juin 2014

Meteor docset is available in Dash

Docsets are offline and searchable docs that you can browse using Dash. Recently, Meteor's docset has been added. Now, even when you are offline, you can easily browse your favorite framework's docs.

You can even call Dash within Vim using the Vimdash plugin.

1 juin 2014

Velocity.js and Meteor

Introduction

Velocity.js is a new animation library in JS. It acts as a replacement of jQuery's animation library. Internally, it uses the CSS3 transformation and animation properties leveraging their hardware acceleration capabilities where possible and falling back on basic jQuery's animation when they are not available. Neat. Here is a small video of a simple animation developed by its creator:
Doing front end development with Meteor is so easy that I've recreated this demo and deployed it in less than one hour. Here is the result: http://velocity3ddemo.meteor.com/

Step-by-step recreation

Create a basic Meteor application:
mrt create Velocity3dDemo
cd Velocity3dDemo
rm -rf Velocity3dDemo*
Import packages:
mrt add coffeescript
mrt add jade
mrt add stylus
mrt add velocityjs
Create a basic web app structure:
mkdir -p client/stylesheets
Create the Stylus file client/stylesheets/app.styl:
@import 'nib'

*
  padding: 0
  margin: 0

body
  background-color: #060b14
  overflow: hidden
  color: #ffffff
  font-family: Helvetica Neue, Open Sans, sans-serif
  font-weight: 100

a
  color: #4bc2f1
  text-decoration: none
  &:hover
    text-decoration: underline

#container
  perspective: 50px
  transform-origin: 50% 100%
  pointer-events: none
  opacity: 0.55

#welcome
  position: fixed
  width: 22rem
  left: 50%
  top: 45%
  margin-top: -1rem
  margin-left: -11rem
  font-weight: 200
  opacity: 0.65
  text-align: center
  font-size: 0.775rem
  line-height: 1.05rem
  letter-spacing: 0.135em
  word-spacing: -0.075rem

@media screen and (max-width: 400px)
  #welcome
    font-size: 0.45rem !important

#logo
  position: fixed
  right: 0.75rem
  bottom: 0.65rem
  cursor: pointer
  text-decoration: none
  color: #d6d6d6
  font-size: 2rem
  letter-spacing: 0.025em

#logoDot
  color: #d74580

.dot
  position: fixed
  width: 30px
  height: 30px
  border-radius: 30px
  background-color: #4bc2f1
Create the Jade file client/index.jade:
head
  title Velocity 3D demo
body
  +index

template(name='index')
  #welcome No WebGL. No Canvas. Just pure DOM.
  a#logo(href='http://julian.com/research/velocity/') Velocity.js
  #container
Create the CoffeeScript file client/index.coffee:
Template.index.rendered = ->
  # Device detection
  isWebkit = /Webkit/i.test navigator.userAgent
  isChrome = /Chrome/i.test navigator.userAgent
  isMobile = window.ontouchstart isnt undefined
  isAndroid = /Android/i.test navigator.userAgent
  isIE = document.documentMode

  # Redirection
  if isMobile and isAndroid and not isChrome
    alert 'Use Chrome on Android'

  # Helpers
  # Randomly generate an integer between 2 numbers.
  r = (min, max) ->
    Math.floor(Math.random() * (1 + max - min)) + min

  # Dot creation
  # Differentiate dot counts on based on device and browser capabilities
  dotsCount = if isMobile then (if isAndroid then 40 else 60) else ( if isChrome then 175 else 125)
  dotsHtml = ''
  for i in [0..dotsCount]
    dotsHtml += '<div class="dot"></div>'
  $dots = $ dotsHtml

  # Setup
  $container = $ '#container'
  $welcome = $ '#welcome'

  screenWidth = window.screen.availWidth
  screenHeight = window.screen.availHeight
  chromeHeight = screenHeight - (document.documentElement.clientHeight or screenHeight)

  translateZMin = - 725
  translateZMax = 600

  containerAnimationMap =
    perspective: [215, 50]
    opacity: [0.90, 0.55]

  # IE10+ produce odd glitching issues when you rotateZ on a parent element subjected to 3D transforms.
  containerAnimationMap.rotateZ = [5, 0] if not(isIE)

  # Animation
  # Fade out the welcome message.
  $welcome.velocity
      opacity: [0, 0.65]
    ,
      display: 'none'
      delay: 3500
      duration: 1100
  # Animate the dot's container.
  $container
    .css 'perspective-origin', "#{screenWidth/2}px #{(screenHeight*0.45)-chromeHeight}px"
    .velocity containerAnimationMap, {duration: 800, loop: 1, delay: 3250}

  # Special visual enhancement for WebKit browsers which are faster at box-shadow manipulation
  ($dots.css 'boxShadow', '0px 0px 4px 0px #4bc2f1') if isWebkit

  $dots
    .velocity
        translateX: [
          -> '+=' + r -screenWidth/2.5, screenWidth/2.5
          -> r 0, screenWidth
        ]
        translateY: [
          -> '+=' + r -screenHeight/2.75, screenHeight/2.75
          -> r 0, screenHeight
        ]
        translateZ: [
          -> '+=' + r translateZMin, translateZMax
          -> r translateZMin, translateZMax
        ]
        opacity: [
          -> Math.random()
          -> Math.random() + 0.1
        ]
      ,
        duration: 6000
        easing: 'easeInOutsine'
    .velocity 'reverse', {easing: 'easeOutQuad'}
    .velocity
        opacity: 0
      ,
        duration: 2000
        complete: ->
          $welcome
            .html "<a href='https://www.youtube.com/watch?v=MDLiVB6g2NY&hd=1'>Watch the making of this demo.</a><br /><br />Go create something amazing.<br />Sincerely, <a href='http://twitter.com/shapiro'>@Shapiro</a>"
            .velocity
                opacity: 0.75
              ,
                duration: 3500
                display: 'block'
    .appendTo $container
Launch it:
mrt
Publish it:
mrt deploy velocity3ddemo.meteor.com
Side note: I've just redeploy this little web app with a link to Meteor. My browser was on the page. Automatically, my browser has been informed that a new release of the code was available. It has only reloaded the modified assets. This is the incredible power of the live reload even when your apps are deployed. Amazing.

The original tutorial

Julian Shapiro, the author of Velocity.js, has provided a very nice Youtube channel which describes how he achieves his demo. A must watch.

31 mai 2014

htop, a better CLI process viewer

Inside my CLI, I sometime like to see which process eats up my CPU or my RAM. top is generally a nice utility for that kind of tasks. But, there is a better and cleaner alternative: htop. A comparison picture is worth a thousand words.
Install it on OSX using:
brew install htop

25 mai 2014

Famo.us polaroid tutorial in CoffeeScript and within Meteor

Introduction

Since Famo.us v0.2.0, some new tutorials have been added to the Famo.us University. The 1st available project is a Polaroid tutorial which teaches you how to create your own app and widget with Famo.us. Just play this little video to check how incredible the animations are with plain simple HTML5 technologies. Note that, this example is completely responsive and I've tested it on smartphones, tablets and desktops.
This example project is not just beautiful. It works very well in iOS, Chrome on Android, Chrome, Safari and Opera. There are little flickers on Firefox but it seems more due to the browser than to the framework. Though, it is completely useable. As ever, the stock Android browser is definitely a knightmare. Meaning that, if you plan on encapsulating your WebApp in a native browser, Apache Cordova is the way to go for iOS but you will need to encapsulate Chromium if you plan on shipping your WebApp for Android. This can be achieve with projects such as Crosswalk, for instance.

Though, the tutorial is incredibly nice and goes smoothly over every difficulties that you may encounter (one of the best tutorial, that I've seen so far), I didn't choose the same way as described. Actually, JavaScript's inheritance model is such a pain to write, that I prefer avoiding it as much as I can. Thus, I've recreated it using another set of tools and it runs as smoothly as the original:
The result is a very small set of code that produces the same WebApp in a fraction of the necessary code and installation steps.

Note that the following tutorial is not a replacement of the one from the Famo.us University. It is a complement to show how this framework is easily integrable with other powerful HTML5 technologies.

Configuring your Meteor project

Create your Meteor project with the dead simple following command:
meteor create Polaroid
cd Polaroid
Now create a common fullstack JS directory structure only targeted for a client WebApp without server side integration:
mkdir -p client/lib client/models client/startup client/stylesheets client/views lib packages public/img
Remove the automatically created files:
rm -rf Polaroid.*
Add the following package with Meteor:
meteor add coffeescript
meteor add stylus
And this one with Meteorite:
mrt add jade
mrt add famono
Easy as pie.

Get the unique required asset from Famo.us

This example WebApp needs a simple public/img/camera.png that you'll find in the Zip file that Famo.us provides in their download section.

Create your style file

The style file client/stylesheets/app.styl is kept as its minimum as most of the CSS rules are handled by Famo.us.
@import 'nib'

html
  background: #404040

body
  -webkit-touch-callout: none
  user-select: none
  font-family: 'AvenirNext-Medium'

Create your HTML file with Jade

As before for the style file, the main HTML file client/index.jade is kept as its minimum as most of the tags are handled by Famo.us
head
  title Famo.us Polaroid
body
  +index

template(name='index')
That's it, a simple template loaded by Meteor.

Create some namespaces

I like to isolate my code from the code that I import. Thus, I create 2 namespaces in 2 separate files.
  • One is dedicated to the WebApp in client/lib/polaroid.coffee:
    # Declare Polaroid namespace
    window.Polaroid ?= {}
    
  • The other one is dedicated to Famo.us in client/lib/famous.coffee:
    # Declare Famo.us namespace
    window.Famous ?= {}
    
The lib directory is used as it is loaded first by Meteor.

The model, a Picasa album

With this example, we do not leverage the power of the full JS stack that Meteor provides. We only use its features of live reloading the code and its easy to use build capability. The model is the same as the one provided in the Famo.us Zip file that you've downloaded except that it is created as a CoffeeScript file named client/models/slidedata.coffee:
Polaroid.SlideData =
  userId: "109813050055185479846"
  albumId: "6013105701911614529"
  picasaUrl: "https://picasaweb.google.com/data/feed/api/user/"
  queryParams: "?alt=json&hl=en_US&access=visible&fields=entry(id,media:group(media:content,media:description,media:keywords,media:title))"
  defaultImage: "https://lh4.googleusercontent.com/-HbYp2q1BZfQ/U3LXxmWoy7I/AAAAAAAAAJk/VqI5bGooDaA/s1178-no/1.jpg"
  getUrl: ->
    @picasaUrl + @userId + "/albumid/" + @albumId + @queryParams
  parse: (data) ->
    urls = []
    data = JSON.parse(data)
    entries = data.feed.entry
    i = 0

    while i < entries.length
      media = entries[i].media$group
      urls.push media.media$content[0].url
      i++
    urls
A simple dictionary with 2 methods.

Requiring the Famo.us libraries

I simply load all the Famo.us libraries in a single location. This drastically reduces the amount of code. I use the same file client/startup/famous.coffee to load the polyfills and to create the Famo.us's singleton so that if I enhance this WebApp with multiple page loaded with a router, there will be no additional loadings or instantiations.
# Import famous.css
require 'famous/core/famous'
# Adds the famo.us dependencies
require 'famous-polyfills'
# Wait for document ready
$(document).ready ->
  # Load Famo.us libraries
  Famous.Engine           = require 'famous/core/Engine'
  Famous.View             = require 'famous/core/View'
  Famous.Transform        = require 'famous/core/Transform'
  Famous.Surface          = require 'famous/core/Surface'
  Famous.StateModifier    = require 'famous/modifiers/StateModifier'
  Famous.Timer            = require 'famous/utilities/Timer'
  Famous.ImageSurface     = require 'famous/surfaces/ImageSurface'
  Famous.ContainerSurface = require 'famous/surfaces/ContainerSurface'
  Famous.Lightbox         = require 'famous/views/Lightbox'
  Famous.Utility          = require 'famous/utilities/Utility'
  Famous.Easing           = require 'famous/transitions/Easing'
  Famous.ContainerSurface = require 'famous/surfaces/ContainerSurface'
  Famous.Transitionable   = require 'famous/transitions/Transitionable'
  Famous.SpringTransition = require 'famous/transitions/SpringTransition'
  # Register transitions
  Famous.Transitionable.registerMethod 'spring', Famous.SpringTransition
  # Create main context
  Polaroid.mainCtx = Famous.Engine.createContext()

Instantiate the main template

The content of the main template is set under the client/index.coffee that goes along with our Jade file:
Template.index.rendered = ->
  # Get request to Picasa API
  Famous.Utility.loadURL Polaroid.SlideData.getUrl(), (data) ->
    data = Polaroid.SlideData.parse data
    # Instantiate the AppView with our URL's data
    Polaroid.appView = new Polaroid.AppView data: data
    Polaroid.mainCtx.add Polaroid.appView

Creating the views

The rest of this tutorial is pretty close to the one from the Famo.us University except that it uses the object model provided by CoffeeScript instead of the one from JavaScript. You should fill this 3 files while following the tutorial from the Famo.us University so that you get the nice explanations that they provided us.

The views are composed of 3 files:
  • client/views/appview.coffee
    $(document).ready ->
    
      class Polaroid.AppView extends Famous.View
        DEFAULT_OPTIONS:
          data: undefined
          cameraWidth: 0.6 * window.innerHeight
        constructor: (@options) ->
          @DEFAULT_OPTIONS.slideWidth = 0.8 * @DEFAULT_OPTIONS.cameraWidth
          @DEFAULT_OPTIONS.slideHeight = @DEFAULT_OPTIONS.slideWidth + 40
          @DEFAULT_OPTIONS.slidePosition = 0.77 * @DEFAULT_OPTIONS.cameraWidth
          @constructor.DEFAULT_OPTIONS = @DEFAULT_OPTIONS
          super @options
          @createCamera()
          @createSlideshow()
    
        createCamera: ->
          camera = new Famous.ImageSurface
            size: [@options.cameraWidth, true]
            content: 'img/camera.png'
            properties:
              width: '100%'
          cameraModifier = new Famous.StateModifier
            origin: [0.5, 0]
            align: [0.5, 0]
            transform: Famous.Transform.behind
          @add(cameraModifier).add camera
    
        createSlideshow: ->
          slideshowView = new Polaroid.SlideshowView
            size: [@options.slideWidth, @options.slideHeight]
            data: @options.data
          slideshowModifier = new Famous.StateModifier
            origin: [0.5, 0]
            align: [0.5, 0]
            transform: Famous.Transform.translate 0, @options.slidePosition, 0
          slideshowContainer = new Famous.ContainerSurface
            properties:
              overflow: 'hidden'
          @add(slideshowModifier).add slideshowContainer
          slideshowContainer.add slideshowView
          slideshowContainer.context.setPerspective 1000
    
  • client/views/slideshowview.coffee
    $(document).ready ->
    
      class Polaroid.SlideshowView extends Famous.View
        DEFAULT_OPTIONS:
          size: [450, 500]
          data: undefined
          lightboxOpts:
            inOpacity: 1
            outOpacity: 0
            inOrigin: [0, 0]
            outOrigin: [0, 0]
            showOrigin: [0, 0]
            inTransform: Famous.Transform.thenMove Famous.Transform.rotateX(0.9), [0, -300, -300]
            outTransform: Famous.Transform.thenMove Famous.Transform.rotateZ(0.7), [0, window.innerHeight, -1000]
            inTransition: duration: 500, curve: Famous.Easing.outBack
            outTransition: duration: 350, curve: Famous.Easing.inQuad
    
        constructor: (@options) ->
          @constructor.DEFAULT_OPTIONS = @DEFAULT_OPTIONS
          super @options
          @rootModifier = new Famous.StateModifier
            size: @options.size
            origin: [0.5, 0]
            align: [0.5, 0]
          @mainNode = @add @rootModifier
          @createLightbox()
          @createSlides()
    
        createLightbox: ->
          @lightbox = new Famous.Lightbox @options.lightboxOpts
          @mainNode.add @lightbox
    
        createSlides: =>
          @slides = []
          @currentIndex = 0
          console.log @options.data
          for url in @options.data
            slide = new Polaroid.SlideView
              size: @options.size
              photoUrl: url
            @slides.push slide
            slide.on 'click', @showNexSlide
          @showCurrentSlide()
    
        showCurrentSlide: ->
          @ready = false
          slide = @slides[@currentIndex]
          @lightbox.show slide, =>
            @ready = true
            slide.fadeIn()
    
        showNexSlide: =>
          return if @ready isnt true
          @currentIndex++
          if @currentIndex is @slides.length
            @currentIndex = 0
          @showCurrentSlide()
    
  • client/views/slideview.coffee
    $(document).ready ->
    
      class Polaroid.SlideView extends Famous.View
        DEFAULT_OPTIONS:
          size: [400, 450]
          filmBorder: 15
          photoBorder: 3
          photoUrl: Polaroid.SlideData.defaultImage
          angle: -0.5
    
        constructor: (@options) ->
          @constructor.DEFAULT_OPTIONS = @DEFAULT_OPTIONS
          super @options
          @rootModifier = new Famous.StateModifier
            size: @options.size
          @mainNode = @add @rootModifier
          @createBackground()
          @createFilm()
          @createPhoto()
    
        createBackground: ->
          background = new Famous.Surface
            properties:
              backgroundColor: '#fffff5'
              boxShadow: '0 10px 20px -5px rgba(0, 0, 0, 0.5)'
              cursor: 'pointer'
          @mainNode.add background
          background.on 'click', =>
            @_eventOutput.emit 'click'
    
        createFilm: ->
          @options.filmSize = @options.size[0] - 2 * @options.filmBorder
          film = new Famous.Surface
            size: [@options.filmSize, @options.filmSize]
            properties:
              backgroundColor: '#222'
              zIndex: 1
              # Make surface invisible to pointer events
              pointerEvents: 'none'
          filmModifier = new Famous.StateModifier
            origin: [0.5, 0]
            align: [0.5, 0]
            transform: Famous.Transform.translate 0, @options.filmBorder, 1
          @mainNode
            .add filmModifier
            .add film
    
        createPhoto: ->
          photoSize = @options.filmSize - 2 * @options.photoBorder
          photo = new Famous.ImageSurface
            size: [photoSize, photoSize]
            content: @options.photoUrl
            properties:
              zIndex: 2
              # Make surface invisible to pointer events
              pointerEvents: 'none'
          @photoModifier = new Famous.StateModifier
            origin: [0.5, 0]
            align: [0.5, 0]
            transform: Famous.Transform.translate 0, @options.filmBorder + @options.photoBorder, 2
            opacity: 0.01
          @mainNode
            .add @photoModifier
            .add photo
    
        fadeIn: =>
          @photoModifier.setOpacity 1, {duration: 1500, curve: 'easeIn'}
          @shake()
    
        shake: ->
          @rootModifier.halt()
          @rootModifier.setTransform Famous.Transform.rotateX(@options.angle), {duration: 200, curve: 'easeOut'}
          @rootModifier.setTransform Famous.Transform.identity, {method: 'spring', period: 600, dampingRatio: 0.15}
    

Further words

My integration is not as proper as I would like it to be. Each class declaration relies on a ready event that I did not succeed in removing. Identically, my class constructors call their parent's one explicitly. Feel free to post some comments if you have a better integration.