Famo.us is a new JavaScript framework that includes an open source 3D layout engine fully integrated with a 3D physics animation engine that can render to DOM, Canvas, or WebGL.
Famo.us is a great framework to create really cool UI’s with 2d/3d animations of any kind. However I’ve noticed some bugs (which is ok as the framework is new) and some limitations due to the fact that some browsers could not correctly apply 3dmatrices. One of the hugest limitation on my opinion is blurring of the text during z-translate of the elements. This means that we simply can not use perspective transitions if our elements contain text.
I was trying to find workaround and as a result came up with the following solution:
1) do actual transition in z-direction
2) scale projection of the surface back to its original size
3) resize our element to fit needed projection size
4) resize font
here is the codepen link
Famo.us is a great framework to create really cool UI’s with 2d/3d animations of any kind. However I’ve noticed some bugs (which is ok as the framework is new) and some limitations due to the fact that some browsers could not correctly apply 3dmatrices. One of the hugest limitation on my opinion is blurring of the text during z-translate of the elements. This means that we simply can not use perspective transitions if our elements contain text.
I was trying to find workaround and as a result came up with the following solution:
1) do actual transition in z-direction
2) scale projection of the surface back to its original size
3) resize our element to fit needed projection size
4) resize font
here is the codepen link
define(function (require, exports, module) {
var Engine = require('famous/core/Engine');
var Surface = require('famous/core/Surface');
var Transform = require('famous/core/Transform');
var StateModifier = require('famous/modifiers/StateModifier');
var Transitionable = require('famous/transitions/Transitionable');
var perspective = 1000;
var fontValue = 100; //initially font-size is 100%
var surfSize = [100, 100];
var mainContext = Engine.createContext();
mainContext.setPerspective(perspective);
var transitionable = new Transitionable(0);
var mySurface = new Surface({
size: surfSize,
properties: {
backgroundColor: 'red',
textAlign: 'center',
color: 'white',
fontSize: fontValue + '%',
lineHeight: surfSize[1] + 'px'
},
content: 'Click Me'
});
var transitionModifier = new StateModifier({
origin: [.5, .5],
align: [.5, .5],
transform: Transform.translate(0, 0, 0.01)
});
mainContext.add(transitionModifier).add(mySurface);
function translateZ(dist, transition) {
transitionable.reset(0);
transitionable.set(dist, transition);
function prerender() {
var currentDist = transitionable.get();
//perspective formula: dist = perspective(1 - 1/scaleFactor)
var currentScale = 1 / (1 - currentDist / perspective);
var currentSize = [surfSize[0] * currentScale, surfSize[1] * currentScale];
var currentFontValue = fontValue * currentScale;
//f.e: bring closer => make projection scaleFactor times bigger
var transitionTransform = Transform.translate(0, 0, currentDist);
//scaling back to avoid text blurring
var scaleTransform = Transform.scale(1 / currentScale, 1 / currentScale, 1);
transitionModifier.setTransform(Transform.multiply(transitionTransform, scaleTransform));
mySurface.setSize(currentSize); //resize to get correct projection size
mySurface.setOptions({
properties: {
fontSize: currentFontValue + '%', //resizing font;
lineHeight: currentSize[1] + 'px' //align text;
}
})
if (currentDist === dist) {
Engine.removeListener('prerender', prerender);
}
}
Engine.on('prerender', prerender);
}
Engine.on('click', function () {
translateZ(750, { curve: 'easeOutBounce', duration: 2000 });
});
});
This approach could be extended to use ContainerSurfaces as a containers where you will set fontSize in %. ContainerSurface will propagate this property to its children.