Ionic OkCupid Side Menu

A few months ago, I was perusing the OkCupid iOS app (let's pretend that it wasn't to get a girlfriend) and I came across an interesting Side Menu transition animation where the content increased in scale and decreased in opacity based on the open ratio of the menu.

Based on the overall design of the OkCupid app, I had a suspiscion that it was created using Ionic and I was curious as to how the effect was achieved. I was expecting to block off my Monday night, order-in some food, and slam together some sort of concoction alone in my place but to my utter disappointment, there was already something out there. All it took was a single Google search to discover that Ionic already had a delegate service called $ionicSideMenuDelegate with several methods, the most important of which being the .getOpenRatio() method. It returns a number between 0 and 1 representing the percentage of how open the side menu is in relation to it's closed state.

So, if .getOpenRatio() is invoked on a closed side menu, it will return 0. Vice versa, if it is invoked on a side menu that is 100% open, it will return 1. Note that this only applies to the left side menu. A right side menu denotes ratio from 0 to -1.

With this method, suddenly mapping CSS transforms to side menu width becomes easy-peasy. In the example codepen, I've created a directive that sets a $watch on the returned value of .getOpenRatio() (based on this Codepen) that in turn invokes a callback passed through an attribute on the element.

.directive('animateRatio', function($timeout, $ionicSideMenuDelegate) {

  return {
    restrict: 'A',
    scope: {
      animateRatio: '=',
    link: function (scope, element, attr) {

      $timeout(function () {
        scope.$watch(function () {
          return $ionicSideMenuDelegate.getOpenRatio();
        function (ratio) {
          scope.animateRatio(element[0], ratio);


The callbacks are passed using the animate-ratio attribute and defined in an outside controller. This was done to allow for easier customization; however, I'd recommend placing then in a factory if you plan on reusing some of the animations across several views.

  $scope.fadeIn = function(element, ratio) { = = 'scale(' + transitionIn(ratio) + ')'; = transitionIn(ratio);

  $scope.slideUp = function(element, ratio) { = = 'translateY(' + transitionFromTo(ratio, 100, 0) + '%' + ')';

Once you've defined how you'd like the element to stylistically change based on the side menu open ratio, simply attach via the animate-ratio attribute.

<img src="img/cooper.jpg" animate-ratio="fadeIn"/>  

I've also included a few helper functions to help customize the ratio.

  var transitionIn = function(ratio) {
    return Math.abs(ratio);

  var transitionOut = function(ratio) {
    return (1- Math.abs(ratio));

  var transitionFromTo = function(ratio, from, to) {
    return from - (Math.abs(ratio) * (from - to));

Feel free to gander at the full example on GitHub and if you'd like to learn more about $ionicSideMenuDelegate, check out the documentation.