Use mootools Fx to zoom background-size

Problem

I'm trying to use mooTools Fx to zoom the background image of a div. I followed david welshs article To make custom transformations. My mooTools/js skills are just quite basic, so

Also I am wondering if there is a possibility to incorporate to use a sine transitions for example (though it doesn't look like).

Here's what I tried: http://jsfiddle.net/q2GQ7/

Javascript:

$$('#program a').each(function(item, index){
    item.store('BackgroundZoomer', new Fx({ duration: 250}));
});
$$('#program a').each(function(item, index){
    item.retrieve('BackgroundZoomer').set = function(value) {
    var style = 200+value + "px " +200+value + "px";
    this.setStyle('background-size', style);
    };
});
$$('#program a').each(function(item, index){
    addEvents({
      'mouseenter': function(){   
            item.retrieve('BackgroundZoomer').start(0, 200); },
        'mouseleave': function(){
            item.retrieve('BackgroundZoomer').cancel();}
    });
});
Problem courtesy of: Patrick

Solution

Since this looked like fun, I wrote some code in the MooTools way[tm] to get you started. I don't normally do this as it's contrary to SO style but I miss working with MooTools. so meh...

http://jsfiddle.net/dimitar/dNd3H/

(function(){
    'use strict';

    var Fx = this.Fx;

    // keep the set override private
    Fx.Background = new Class({
        Extends: Fx,
        initialize: function(element, options){
            this.element = element;
            this.parent(options);
        },
        set: function(value, u){
            u = this.options.unit;
            this.element.setStyle('background-size', [value, u, ' ', value, u].join(''));
            return this;
        }
    });

    document.getElements('#program a').each(function(item) {
        item.store('fxb', new Fx.Background(item, {
            duration: 250,
            link: 'cancel',
            unit: '%' // change to px or em 
        }));
    });

    document.id('program').addEvents({
        'mouseover:relay(a)': function(){
            // 100% to 200%
            this.retrieve('fxb').start(100,200);
        },
        'mouseout:relay(a)': function(){
            // 200% back to 100%
            this.retrieve('fxb').start(200,100);
        }
    });
}.call(this));

Explanation:

  • Closure. good practice.
  • Creating a subclass that extends Fx but expects a new argument, the element--similar to how Fx.Morph and Fx.Tween work. Benefits are: available via Fx object anywhere. Can access normal options object, therefore it will be possible to use unit etc in the set. scope will be correctly bound to Fx instance, NOT the element like in David's demo.
  • Instantiate a new class for the elements

Look at Fx.Tween.js source. Normally your classes extend Fx.Tween, this fix is kind of an anti-pattern / hack, Fx instantiation direct is not common at all :) You really should just extend the Fx.CSS.Parser and Element.Styles properties instead to be able to read / parse what you need and Fx will just work like with any other property.

  • add a single event to parent via delegation.
Solution courtesy of: Dimitar Christoff

Discussion

There is currently no discussion for this recipe.

This recipe can be found in it's original form on Stack Over Flow.