diff --git a/src/VelocityBounce.js b/src/VelocityBounce.js new file mode 100644 index 00000000..c85aa254 --- /dev/null +++ b/src/VelocityBounce.js @@ -0,0 +1,15 @@ +var Velocity = require('velocity-animate'); + +// courtesy of https://github.com/julianshapiro/velocity/issues/283 +// We only use easeOutBounce (easeInBounce is just sort of nonsensical) +function bounce( p ) { + var pow2, + bounce = 4; + + while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} + return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); +} + +Velocity.Easings.easeOutBounce = function(p) { + return 1 - bounce(1 - p); +} diff --git a/src/skins/vector/views/molecules/EventTile.js b/src/skins/vector/views/molecules/EventTile.js index 322be444..1e4c9a63 100644 --- a/src/skins/vector/views/molecules/EventTile.js +++ b/src/skins/vector/views/molecules/EventTile.js @@ -29,6 +29,15 @@ var ContextualMenu = require('../../../../ContextualMenu'); var TextForEvent = require('matrix-react-sdk/lib/TextForEvent'); var Velociraptor = require('../../../../Velociraptor'); +require('../../../../VelocityBounce'); + +var bounce = false; +try { + if (global.localStorage) { + bounce = global.localStorage.getItem('avatar_bounce') == 'true'; + } +} catch (e) { +} var eventTileTypes = { 'm.room.message': 'molecules.MessageTile', @@ -137,8 +146,8 @@ module.exports = React.createClass({ // and then it will drop down to its resting position startStyles.push({ top: topOffset, left: '0px' }); enterTransitionOpts.push({ - duration: 300, - easing: 'easeOutCubic', + duration: bounce ? Math.min(Math.log(Math.abs(topOffset)) * 200, 3000) : 300, + easing: bounce ? 'easeOutBounce' : 'easeOutCubic', }); }