Adding Frosted Glass Effect to your Ionic Framework App Last update: 2015-04-15

Adding Frosted Glass Effect to your Ionic Framework App

The frosted glass effect is a smart way to have an overlay above your content while still seeing that there is something in the background. If you are an iOS user, you will have noticed this effect in places like when you pull down your notifications.

Today I will show you how to add this cool effect to your Ionic App with the help of the Ionic Frosted Glass Ion.

Setup a simple App

As always we will start with a simple blank Ionic app. Then we install the custom ion with the help of bower, so run these commands:

ionic start devdactic-frost blank
cd devdactic-frost
bower install ionic-ion-frost --save

To use the Ion, we need to include it in our module so open your app.js and add it to our dependencies:

angular.module('starter', ['ionic','ionic.contrib.frost'])

Finally we have to load the needed files inside our index.html so open it and add the 2 lines after the cordova.js script:

<link href="lib/ionic-ion-frost/ionic.contrib.frost.css" rel="stylesheet">
<script src="lib/ionic-ion-frost/ionic.contrib.frost.js"></script>

Now everything is set up and we are ready to let our app get frosty!

Adding the Frosted Glass ion to our view

First of all we need to create a view which can be frosted. For this tutorial we will just have a simple header bar and a button to apply the frost effect. Go to your index.html and replace everything inside your body with this:

<ion-pane ng-controller="AppCtrl" id="myPane">
			<ion-header-bar class="bar-dark">
				<h1 class="title">My App</h1>
			</ion-header-bar>
			<ion-content class="has-header">
				<button class="button button-block button-balanced" ng-click="pushFrost()">Let it be frosty</button>
				<!-- Your content -->
			</ion-content>
</ion-pane>

<ion-pane ng-controller="OverlayCtrl" class="dark-overlay" ng-show="showOverlay">
			<ion-header-bar class="bar-clear">
				<button class="button button-block button-outline button-balanced" ng-click="hideFrost()">Hide me</button>
			</ion-header-bar>
			<ion-content class="has-header">
				<ion-list>
					<ion-item ng-repeat="item in items" class="dark-item">
						{{item.text}}
					</ion-item>
				</ion-list>
			</ion-content>
</ion-pane>

You might be wondering why there is no directive added anywhere which would indicate frosted glass. The reason is simple: we will add the effect on the fly later by clicking on the button! This will bring up a problem, but we will see that later.

For now, we just have one simple view with an id assigned so we can access it later from our controller, and another one which will act simply as the overlay or content we want to display above the frosted glass.

To have a good-looking effect, we need to add some css so open the style.css and insert these lines:

.dark-overlay {
  background-color: #222 !important;
  opacity: 0.8;
}
.dark-item {
  background-color: transparent !important;
  color: #fff !important;
  border-color: #444 !important;
}

The view is ready, now we just need to create our controller!

Adding the controller for our Frosted Glass

Our controller is already assigned to our view, let’s creat it by adding this to our app.js

.controller('AppCtrl', function($scope, $rootScope, $compile) {
  $scope.pushFrost = function() {
    var el = angular.element(document.getElementById('myPane'));
    el.attr('frost', '');
    el = $compile(el)($scope);
    $rootScope.showOverlay = true;
  };
})

In fact our controller has only one function, which is assigning the frost directive to our content pane. We do this by grabbing the object by his id and afterwards adding the frost directive and recompiling the object. Finally we set the rootScope.showOverlay to true so that our second created pane inside the view will be visible (which is our overlay).

You might have seen that this pane also has a controller, so let’s go ahead and create this controller also in our app.js. This controller will only have some items which will be displayed, so just some dummy data.

.controller('OverlayCtrl', function($scope, $rootScope, $compile) {
  $scope.items = [];
  for(var i = 0; i < 5; i++) {
    $scope.items.push({text: 'Whatever ' + (i+1) });
  }

  $scope.hideFrost = function() {
    $rootScope.showOverlay = false;
    var el = angular.element(document.getElementById('myPane'));

    // el.remove(); Removes the complete object

    // Another way, still not working
    // var safe = el.children();
    // el.empty();
    // el.html('<ion-pane ng-controller="UnderCtrl" id="myPane">');
    // el.children = safe;
    // el = $compile(el)($scope);

  };
});

So here I am confronted with a big problem: How to remove a directive from an element? I am sorry, but I found no way to achieve this. I would be super happy if someone of you could leave a comment on how to do this!

The problem is, the demo from Ionic for this effect just has the directive always added, but I guess most of the time you want to pull the effect up when some action takes place. So we need to find a way to dynamically add and remove a directive. I read many possible solutions, but none of them worked the way we need it here.

Anyway, you can start your app now and should get a cool looking frosted glass effect when you press the button.

Conclusion

If you know a completely different approach to this problem and I am just dumb at this point, please also leave me your thoughts here or on Twitter. I hope you still learned how to apply and use the custom Ion for frosted glass, and we will be able to solve this myth so I can update the post for later!

If this tutorial was helpful, follow me on twitter @schlimmson and leave a comment/ tweet it! Don’t forget to subscribe to my newsletter to receive new posts and info via mail!

So long, Saimon