AJAX Page Loads Using MooTools Fx.Explode

By  on  

Note: All credit for Fx.Explode goes to Jan Kassens.

One of the awesome pieces of code in MooTools Core Developer Jan Kassens' sandbox is his Fx.Explode functionality. When you click on any of the designated Fx.Explode elements, the elements "explode" off of the screen. Click again and they magically reappear. Don't believe me? Check out Kassens' example!

In speaking with Jan, his idea was to use this effect for page changes but never got around to it. I've completed this goal, albeit with some ugly code, but I think it's worth a look.

Kassens' MooTools Fx.Explode Class

/* created by legendary MooTools developer, Jan Kassens */
Fx.Explode = new Class({
	Extends: Fx.CSS,
	
	options: {
		grow: 0.5,
		expand: 1,
		transition: "expo:out",
		duration: 750
	},

	initialize: function(elements, options){
		this.elements = this.subject = $$(elements);
		this.parent(options);
		this.addEvent('complete', function(){
			this.clones.dispose();
			if (this.inverted) this.elements.setStyle('opacity', 1);
		}, true);
	},

	compute: function(from, to, delta){
		var now = {};
		for (var i in from){
			var iFrom = from[i], iTo = to[i], iNow = now[i] = {};
			for (var p in iFrom) iNow[p] = this.parent(iFrom[p], iTo[p], delta);
		}
		return now;
	},

	set: function(now){
		for (var i in now){
			var iNow = now[i];
			for (var p in iNow) this.render(this.clones[i], p, iNow[p], this.options.unit);
		}
		return this;
	},

	start: function(fromX, fromY, inverted){
		this.inverted = !!inverted;
		var from = {}, to = {};
		this.clones = $$(this.elements.map(function(el, i){
			var clone = el.clone();
			var coords = el.getCoordinates();
			clone.setStyles(coords).setStyle('position', 'absolute').inject(document.body);
			el.setStyle('visibility', 'hidden');
			
			var center = {
				x: coords.left + coords.width / 2,
				y: coords.top + coords.height / 2
			};
			
			var self = this;
			(function(prop, end){
				var parsed = self.prepare(clone, prop, end);
				if (self.inverted) {
					(from[i] = from[i] || {})[prop] = parsed.to;;
					(to[i] = to[i] || {})[prop] = parsed.from;
				} else {
					(from[i] = from[i] || {})[prop] = parsed.from;;
					(to[i] = to[i] || {})[prop] = parsed.to;
				}
				return arguments.callee;
			})
			('top', coords.top + (center.y - fromY) * this.options.expand - coords.height * this.options.grow / 2)
			('left', coords.left + (center.x - fromX) * this.options.expand - coords.width * this.options.grow / 2)
			('width', coords.width * (1 + this.options.grow))
			('height', coords.height * (1 + this.options.grow))
			('opacity', 0);
			
			return clone;
		}, this));
		return this.parent(from, to);
	}
});

My Usage / Example

var init = function (req) {
	var shown = true;
	var running = false;
	var explode = new Fx.Explode('#fx-contain *', {
		duration: 500,
		onComplete: function(){ running = false; }
	});
	var implode = new Fx.Explode('#fx-contain *', {
		onComplete: function(){ running = false; },
		transition: 'sine:in:out',
		duration: 500,
		grow: -1,
		expand: -.8
	});
	
	$$('#fx-contain a').each(function(el) {
		el.addEvent('click', function(e){
			e.stop();
			if (running) return;
			if (shown) explode.start(e.client.x, e.client.y);
			else implode.start(e.client.x, e.client.y, true);
			running = true;
			shown = !shown;
			req.send({
				url: el.get('href')
			});
		});
	});
};

/* making things happen */
window.addEvent('domready', function() {
	var req = new Request({
		method: 'get',
		data: {
			ajax: 1
		},
		onSuccess: function(response) {
			//fade in content
			$('fx-contain').set({
				html: response
			});
			init(req);
		}
	});
	init(req);
});

Like I said, my code isn't pretty but it works. Enjoy!

Recent Features

  • By
    Responsive Images: The Ultimate Guide

    Chances are that any Web designers using our Ghostlab browser testing app, which allows seamless testing across all devices simultaneously, will have worked with responsive design in some shape or form. And as today's websites and devices become ever more varied, a plethora of responsive images...

  • By
    5 Ways that CSS and JavaScript Interact That You May Not Know About

    CSS and JavaScript:  the lines seemingly get blurred by each browser release.  They have always done a very different job but in the end they are both front-end technologies so they need do need to work closely.  We have our .js files and our .css, but...

Incredible Demos

  • By
    Fade Images with MooTools LazyLoad

    I recently received an email from a MooTools developer asking a great question about my LazyLoad class: "I'm using your LazyLoad MooTools plugin (which is great, by the way). I have been trying to figure out how to modify it so that once an image scrolls into...

  • By
    Making the Firefox Logo from HTML

    When each new t-shirt means staving off laundry for yet another day, swag quickly becomes the most coveted perk at any tech company. Mozilla WebDev had pretty much everything going for it: brilliant people, interesting problems, awesome office. Everything except a t-shirt. That had to change. The basic...

Discussion

  1. I love it! Maybe you should try setting overflow to hidden so no horizontal scrollbar gets created :) But apart from that, really fun example!

  2. Fabian Beiner

    I don’t like it. It’s to “noisy”…

  3. I really like it, but I surely agree with Chris in what he said. And as for Fabian’s comment, the explode creates a kind of “noisy” effect, could it work as the data just disappear or fades out then the new data loads? I think it’d make it nicer, smoother, and more professional!

  4. emehrkay

    I remember when this was shown in the IRC room. I remember him saying that it would work better with text if the parent element had a set width. You should try it in your example to see if it makes a difference.

  5. cssProdigy

    Great effect. Looks a bit unnecessary and not as smooth as some other things i’ve seen using MooTools.
    Nice job!

  6. People just aren’t ready for it yet. They’re still getting used to content fading in and out and smoothly animated changing heights and widths!

    I’d love to see a professional site utilize this.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!