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

Apr 29
2006 10:54 (Программирование, PHP) · English (13,370 views)

Несколько дней назад мой лучший друг Алексей Ковырин попросил меня помочь ему написать эффект вспышки для страницы HTML. Я посоветовал реализовать эффект с помощью библиотеки moo.fx. Хотелось просто показать, как расширять библиотеку, но я не удержался, и написал эффект сам.

moo.fx - это очень легкая, суперлегкая, мегалегкая библиотека эффектов javascript, написанная с использованием prototype.js. Еее легко расширять собственными эффектами, и в этой заметке я покажу, как это можно сделать. В статье показано, как можно создать эффект вспышки: фон элемента плавно изменяется от одного цвета до другого и обратно к первому цвету (возможно несколько раз).

Для того, чтобы расширить fx.Base, можно использовать следующую конструкцию:

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

Теперь необходимо определиться, в каком формате будут передаваться начальные цвета. Я решил, что наиболее простым для пользователя будет передать цвета в формате #RRGGBB, наиболее популярном в веб-дизайне. Необходимо разобрать эту строку, чтобы получить отдельные составляющие цвета (красный, зеленый и синий), потому нужно написать функцию, осуществляющую преобразование из шестнадцатеричной в десятичную систему счисления. Для установки цвета фона элемента необходима функция, осуществляющая обратное преобразование.

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);
}

Теперь можно реализовать конструктор (метод initialize()):

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);
}

Эта функция может принимать следующие опции:

  • duration - длительность в миллисекундах изменения цвета от начального до конечного или наоборот. Например, если передать count = 3, общая длительность выполнения эффекта будет 3 * 2 * duration (по умолчанию 500).
  • onComplete - функция, которая будет вызвана после окончания эффекта.
  • transition - тип изменения значения цвета. (по умолчанию fx.sinoidal)
  • color_from - начальный цвет (по умолчанию #ffffff)
  • color_to - конечный цвет (по умолчанию #ff0000)
  • count - количество вспышек (по умолчанию 1)

Эффект зависит от функции onComplete, потому параметр сохраняется в другой опции flashOnComplete.

Функция increase() вызывается в течение выполнения эффекта. В ней мы можем вычислить текущее значение цвета на основе внутренней переменной this.now:

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;
}

Для вызова эффекта используется функция toggle(). OnComplete используется для повторения эффекта от конечного до начального цвета. В ней также уменьшается значение текущее счетчика, чтобы эффект повторялся count раз.

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);
}

Вот и все. Вы можете скачать исходный код здесь. Примеры работы показаны ниже.

Это просто текст. Нажмите на ссылку ниже, чтобы посмотреть эффект fx.Flash в действии.
var sample1 = new fx.Flash("sample-area", {color_from:"#ffffe3", color_to:"#007f00", count:3, transition:fx.circ, duration:300});

Показать эффект #1

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

Показать эффект #2

5 отзывов на 'Extending moo.fx with custom effect (fx.Flash)'

Подписаться на комментарии по RSS или TrackBack на 'Extending moo.fx with custom effect (fx.Flash)'.

1
сказал 29.04.2006 в 11.23

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

2
сказал 25.05.2006 в 22.23

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

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

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

3
Amit
сказал 03.10.2006 в 23.34

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

4
Pasha
сказал 24.12.2006 в 14.27

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

5
сказал 24.12.2006 в 15.10

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

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

Оставить отзыв

Вы можете использовать простые теги форматирования HTML (вроде <a>, <ul> and others). Чтобы вставить пример код, используйте <code lang="php">$a = "hello";</code> (поддерживаемые языки: ruby, php, yaml, html, csharp, javascript). Также Вы можете использовать <code>$a = "hello";</code>, синтаксис не будет подсвечен. Если вы не хотите использовать тег <code>, замените символ < на &lt;.

Отправить

 
Copyright © 2005 - 2008, Dmytro Shteflyuk