Extending moo.fx with custom effect (fx.Flash)

Posted by Dmytro Shteflyuk on under JavaScript

Several days ago my best friend Alexey Kovyrin asked me to help him to create flashing effect on HTML page. I gave him advice to create this effect using moo.fx library. I wanted to show how to extend it, but I couldn’t keep from creating this effect myself.

moo.fx is a superlightweight, ultratiny, megasmall javascript effects library, written with prototype.js. It’s easily to extend it with custom effect and in this post I will show you how you can do this. In this article I’ll show how to create flashing effect: element’s background will smoothly change from one color to another and go back to first color (maybe several times).

To extend fx.Base you can use following construction:

1
2
3
fx.Flash = Class.create();
Object.extend(Object.extend(fx.Flash.prototype, fx.Base.prototype), {  
// ...

Now we need to decide in which format initial colors will be passed. I think the most simple to user is to pass color values in #RRGGBB format, the most popular format in web-design. We need to parse this format to get separate color’s parts (reg, green and blue), therefor it’s necessary to create function that makes hexadecimal => decimal conversion. To assign background color to the element while flashing reverse function is required.

1
2
3
4
5
6
7
8
9
10
11
12
hD: "0123456789ABCDEF",

d2h: function(d) {
    var h = this.hD.substr(d & 15, 1);
    while (d > 15) { d >>= 4; h = this.hD.substr(d & 15, 1) + h; }
    if (h.length == 1) h = "0" + h;
    return h;
},
   
h2d: function(h) {
    return parseInt(h, 16);
}

Now we are ready to develop constructor (method initialize()):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
initialize: function(el, options) {
    this.el = $(el);

    var color_from = (options && options.color_from) || "#ffffff";
    var color_to = (options && options.color_to) || "#ff0000";
    var color_f = this.h2d(color_from.substr(1));
    var color_t = this.h2d(color_to.substr(1));
   
    var _options = {
        red: [color_f >> 16, color_t >> 16],
        green: [(color_f >> 8) & 255, (color_t >> 8) & 255],
        blue: [color_f & 255, color_t & 255],
        count: 1
    };
    Object.extend(_options, options || {});
    if (_options.onComplete) _options.flashOnComplete = _options.onComplete;
    this.setOptions(_options);
}

This function can accept following options:

  • duration – duration in milliseconds of changing color from first to second or vice versa. For example, if you pass count = 3, complete effect execution time will be 3 * 2 * duration (default is 500).
  • onComplete – a function that will get called upon effect completion.
  • transition – transition type. (default is fx.sinoidal)
  • color_from – beginning color (default is #ffffff)
  • color_to – ending color (default is #ff0000)
  • count – flashes count (default is 1)

Effect dependents on onComplete function therefor this parameters is saved to another options variable flashOnComplete.

Function increase() is called during effect. In this function we can calculate current color based on internal variable this.now:

1
2
3
4
5
6
increase: function() {
    var r = this.d2h(this.now * (this.options.red[0] - this.options.red[1]) / 255 + this.options.red[1]);
    var g = this.d2h(this.now * (this.options.green[0] - this.options.green[1]) / 255 + this.options.green[1]);
    var b = this.d2h(this.now * (this.options.blue[0] - this.options.blue[1]) / 255 + this.options.blue[1]);
    this.el.style.backgroundColor = "#" + r + g + b;
}

To call effect function toggle() used. OnComplete is used to repeat effect from ending to beginnig color. It also decrements current count value to make it possible to repeat effect count times.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
toggle: function() {
    if (this.flashCount == undefined) this.flashCount = this.options.count;
    this.options.onComplete = this.onComplete.bind(this);
    this.custom(255, 0);
},

onComplete: function() {
    this.flashCount--;
    if (this.flashCount == 0)
    {
        this.flashCount = undefined;
        this.options.onComplete = this.options.flashOnComplete;
    } else
        this.options.onComplete = this.toggle.bind(this);
    this.custom(0, 255);
}

Thats all. You can download source file here. Samples are shown below this.

This is sample text. Click the link below to view fx.Flash effect in action.
1
var sample1 = new fx.Flash("sample-area", {color_from:"#ffffe3", color_to:"#007f00", count:3, transition:fx.circ, duration:300});

Show effect #1

1
var sample2 = new fx.Flash("sample-area", {color_from:"#ffffe3", color_to:"#7f0000", count:1, duration:600});

Show effect #2

5 Responses to this entry

Subscribe to comments with RSS

said on April 29th, 2006 at 11:23 · Permalink

Огромное спасибо за такое элегантное решение моей проблемы! Как мне показалось, начальство больше оценило этот эффект, чем 3000+ строк кода, которые были написаны в проекте за последние полторы недели :-)

said on May 25th, 2006 at 22:23 · Permalink

ИМХО, используя script.aculo.us делать такие еффекты еще проще. Там тоже уже есть готовый абстрактный класс Effect расширяя который можно писать свои эффекты. А можно, используя опять-таки инструменты этой библиотеки, делать связки эффектов, использовая лишь базоыве (core) эффекты. Можно получить очень разнообразные вариации.

Вообщем, рекомендую обратить внимание.

Да, script.aculo.us не только про эффекты, поэтому она занимает побольше. Но, можно подключить модули пофайлово, и тогда тоже немного места займет. А можно использовать всю библиотеку и делать вообще кучу всего в “одну строку” :)

Amit
said on October 3rd, 2006 at 23:34 · Permalink

hi,
can u send and argument to the onComplete which will perform another function each time?
for exaple:
//javascript
var myFunction;
function AjaxMe(which, what, whatToDo){
new Ajax(which, {postBody: ‘sleep=0’, update: $(what), onComplete: myFunction}).request();}
//html
Toggle me
thanks for your help
amit

Pasha
said on December 24th, 2006 at 14:27 · Permalink

Да-да, хотелось бы услышать от автора, что он думает по поводу script.aculo.us.

said on December 24th, 2006 at 15:10 · Permalink

script.aculo.us – отличная библиотека для использования в больших проектах, сильно завязанных на всяких эффектах. Если разрабатывается маленькое приложение, или большое, но в котором нужно в паре мест добавить симпатичные эффекты – зачем тягать здоровенную библиотеку? :-)

Вообще сейчас moo.fx вырос до mootools, и это уже не просто библиотека с парой эффектов, а реальная альтернатива prototype+script.aculo.us.

Comments are closed

Comments for this entry are closed for a while. If you have anything to say – use a contact form. Thank you for your patience.