Original on http://blog.berniesumption.com/software/animator

Библиотека анимации под JavaScript: Animator.js

Просмотр animator.js на GitHub

Франция-флаг значок Французкая версия Vicky Rotarova

Animator.js библиотека которую я написал еще в 2006 году для обработки анимации на веб-страницах. Какое-то время это было хорошее опережение: Это была первая библиотека с функцией CSS морфинга - возможность плавного перехода между двумя стилями, определенных как классы CSS.

Мир JavaScript изменился на много с тех пор. Animator.js теперь включен в большинство основных структур JavaScript, либо путем непосредственного переноса кода (Animator.js выпущен под лицензией BSD, которая позволяет людям делать это), либо путем заимствования методов. В частности, CSS анимации дают лучшие результаты и используют меньше мощности процессора. Для современной библиотеки, которая выставляет CSS анимации через подобный API, я рекомендую jQuery.Transit.

Я сохраняю эту страницу здесь из за исторического интереса, потому что это написано в учебнике о стиле, который будет уместен, если вы хотите узнать, как создавать анимацию programatic на любом языке.

Благодаря Тима Стоуна, Каспар Фишера, Clint Priesta и других разработчиковов , которые способствовали обратным связям.

Предпосылки и мотивация

Я удалил этот раздел , поскольку в нем содержатся критические замечания других библиотек JavaScript, которые были верны в 2006 году, но не сегодня. Я также воспользовался возможностью разглагольствовать на тему объектно-ориентированного наследования, которая являлась темой, которую я исследовал более подробно в статье Наследование Зло и должно быть уничтожено - Берни Сампшон, 2010

Лучший способ анимации

Аниматор это объект, который генерирует ряд чисел между нулем и единицей. Ноль представляет собой начало анимации, один конец.

Проверь это:

// This object controls the progress of the animation
ex1 = new Animator()
// the Animator's subjects define its behaviour
ex1.addSubject(updateButton);
function updateButton(value) {
    var button = document.getElementById("ex1Button");
    button.innerHTML = "Progress: " + Math.round(value * 100) + "%";
}
// now click below: each click to the button calls ex1.toggle()

Animator выше был оставлен с параметрами по умолчанию, вот пример, который использует более сложную конфигурацию:

ex2 = new Animator({
    duration: 1200,
    interval: 400,
    onComplete: function() {
        document.getElementById("ex2Target").innerHTML += "Bing! ";
    }
})
ex2.addSubject(updateButton);
function updateButton(value) {
    document.getElementById("ex2Target").innerHTML += " Badda ";
}

Анимационные стили элементов

Большую часть времени вы хотите оживлять один или больше свойств стиля элемента. Есть по существу только три вида значения CSS-те , которые численно масштабированы (например , 10px ), те , которые масштабируются со значением RGB цвета (как #RRGGBB ), и те, которые не имеют шкалы (как bold/italic .) Animator предоставляет три вспомогательных класса для каждого из этих видов свойств, и между ними они могут оживить любой стиль CSS.

// animate margin-left from 0 to 100 px
ex3 = new Animator().addSubject(
    new NumericalStyleSubject(
        "ex3Button",
        "margin-left",
        0,
        100));

прямо

// animate background-color from white to black
ex4 = new Animator().addSubject(
    new ColorStyleSubject(
        "ex4Button",
        "background-color",
        "#FFFFFF",
        "#F4C"));

// animating both - note how calls to addSubject() can be chained:
ex5 = new Animator()
    .addSubject(
        new NumericalStyleSubject(
            "ex5Button",
            "margin-left",
            0,
            100))
    .addSubject(
        new ColorStyleSubject(
            "ex5Button",
            "background-color",
            "#FFFFFF",
            "#F4C"))
    .addSubject(
        new DiscreteStyleSubject(
            "ex5Button", "font-weight",
            "normal",
            "bold",
            0.5));
// also, check out the last subject, which causes font-weight to
//switch from normal to bold half way through the animation

Если вы когда - либо использовали moofx или Scriptaculous, то вы, вероятно, думаете, что это является довольно громоздким, и вы были бы правы. Animator имеет убийственную особенность, которая удаляет многословие, но прежде чем мы перейдем к этому, вот еще пара вещей которые ты можешь сделать:

Более сложные эффекты

Что делать, если у вас есть несколько элементов, которые вы хотите оживить таким же образом? В этом случае, ye;yj передать массив элементов в Subject конструктор. Там нет никакого способа, чтобы добавлять и удалять элементы из Subject после того, как он был построен-если вы хотите , чтобы сделать это, используйте один Subject для каждого элемента и использовать addSubject() и removeSubject() на Animator .

// Applying the same effect to different elements is easy
ex6 = new Animator().addSubject(
    new NumericalStyleSubject(
        ["dot1", "dot2", "dot3"],
        "margin-right",
        10,
        50));

В предыдущих примерах, каждый субъект сослался на тот же элемент. Это не должно быть так:

// applying different effects to different elements is possible
ex7 = new Animator()
    .addSubject(
        new ColorStyleSubject(
            "ex5ButtonA",
            "background-color",
            "#FF9",
            "#9F9"))
    .addSubject(
        new NumericalStyleSubject(
            "ex5ButtonB",
            "padding",
            "5px",
            "15px"));

Непрозрачность получает специальную обработку. Поскольку IE не поддерживает стандарт "непрозрачности" стилей CSS, NumericalStyleSubject преобразует его в соответствующий фильтр.

ex8 = new Animator().addSubject(
    new NumericalStyleSubject(
        "ex8Button",
        "opacity",
        1,
        0.25));

Управление анимацией

При нажатии на кнопку образца в этой статье, вы вызаваете toggle() на объекте аниматора. Есть еще несколько функций управления:

play()
0%
stop()
reverse()
seekTo(0.5)
seekFromTo(0.25, 0.75)

Преимуществом использования seekTo() является то, что вы избегаете резких скачков в состоянии, когда находитесь на полпути в анимации.

Переходы

Переход это функция, которая принимает состояние (число между 0 и 1) и возвращает другое число в диапазоне от 0 до 1. Это может быть использовано для имитации ускорения, замедления и более сложных эффектов. Вы можете передать в переходе к Animator конструктор объекта с именем transition.

Объект Animator.tx предоставляет несколько готовых переходов:

Иногда вы хотите, точно настроить вышеуказанные переходы. Если вы посмотрите на исходный код, где создаются объект Animator.tx, вы увидите, что эти функции все сделаны для четыре заводских функций:

Animator.makeEaseIn()

// make a transition that gradually accelerates. pass in 1 for smooth
// gravitational acceleration, higher values for an exaggerated effect
ex9 = new Animator({
    transition: Animator.makeEaseIn(3),
    duration: 1000
});
ex9.addSubject(
    new NumericalStyleSubject(
        "ex9Button",
        "margin-left",
        0,
        200));

Animator.makeElastic()

// make a transition that, like an object with momentum being
// attracted to a target point, goes past the target then returns
ex10 = new Animator({
    transition: Animator.makeElastic(3),
    duration: 2000
});
ex10.addSubject(
    new NumericalStyleSubject(
        "ex10Button",
        "margin-left",
        0,
        200));

 

Animator.makeBounce()

// make a transition that, like a ball falling to floor, reaches
// the target and bounces back again
ex11 = new Animator({
    transition: Animator.makeBounce(3),
    duration: 2000
});
ex11.addSubject(
    new NumericalStyleSubject(
        "ex11Button",
        "margin-left",
        0,
        200));

Animator.makeADSR()

Конверт Sustain Release Attack Decay является методом, который я перенял от производства музыки. Это очень полезно для анимации, которые начинаются и заканчиваются на ту же величину.

// This example shows you what an ADSR envelope looks like, but is
// otherwise useless the first three arguments are the boundary
// points of the 4 phases. The last is the sustain level.
// All should be between 0 and 1.
ex12 = new Animator({
    transition: Animator.makeADSR(0.25, 0.5, 0.75, 0.5),
    duration: 2000
});
ex12.addSubject(
    new NumericalStyleSubject(
        "ex12Button",
        'margin-left',
        0,
        400));

Практическое применение ADSR является проведение анимации в определенном состоянии на некоторое время, как в этом желтом выцветанию примере

// This yellow fade is emphasised by holding it at full yellow
// for the first half of the animation
ex13= new Animator({
    transition: Animator.makeADSR(0, 0, 0.5, 1),
    duration: 1500
});
ex13.addSubject(
    new ColorStyleSubject(
        "ex13Button",
        "background-color",
        "#FFFFFF",
        "#FFFF00"));

Пользовательские функции

Конечно, вы можете написать свои собственные функции, которые делают любой вид перехода:

function setupEx14() {
    var wobbles = parseInt(prompt(
        "Enter a number of wobbles (try between 1 and 5)", ""));
    if (!wobbles) {
        alert("Sorry, I didn't understand that, have 2 wobbles.");
        wobbles = 2;
    }
    // do some kind of crazy trigonometric stuff. I don't even
    // know what it all means, I just went crazy with the Math
    // functions
    ex14Tx = function(pos) {
        return ((-Math.cos(pos*Math.PI*((1+(2*wobbles))*pos))/2) + 0.5);
    }
    ex14 = new Animator({
        transition: ex14Tx,
        duration: 2000
    });
    ex14.addSubject(
        new NumericalStyleSubject(
            "ex14Button",
            "margin-left",
            0,
            100));
    ex14.play();
};

Убийственная особенность

Я хотел бы объяснить, как аниматор работает под капотом, прежде чем показать эту функцию.

Как я уже говорил, это все немного многословно в данный момент, и большая часть кода в приведенных выше примерах просто шаблонная. То, что нам нужно, это какой-то язык, который позволяет нам определить стиль, который мы хотим анимировать объект в нужную сторону. Ой, подождите секунду, мы уже получили одно: CSS. Стиль CSS содержит всю информацию, необходимую для определения состояния анимации:

ex15 = new Animator().addSubject(
    new CSSStyleSubject(
        "ex15Button",
        "width: 12em; background-color: rgb(256, 256, 256); font-style: normal",
        "width: 40em; background-color: #F39; font-style: italic"));
// note how you can use any unit, not just 'px'.

CSSStyleSubject является оберткой остальных трех Subject с. Он разбирает два набора правил CSS и для каждой декларации, создает NumericalStyleSubject , если он выглядит как число, или ColorStyleSubject если это выглядит как цвет, или DiscreteStyleSubject иначе. DiscreteStyleSubject s создаются с порогом 0,5, другими словами , изменения стиля от нормали к курсивом на полпути через анимации.

Удобно то, что вы можете также передать в именах CSS классов значения наборов правил:

ex16 = new Animator().addSubject(new CSSStyleSubject(
    "ex16Button",
    "small white",
    "big blue bendy"));
// the classes small, big, white, blue and bendy are
// defined in this page's source.

Когда вы создаете анимации из классов CSS, то легко потерять след того, что делает ваш объект аниматор. Animator.inspect()это метод который возвращает строку , которая описывает аниматор.

Это очень хорошо, но мы все еще можем удалить еще немного хлама. Большую часть времени, тот элемент, который вы хотите оживить уже будет в своем первоначальном стиле. Если это так, то вы можете опустить один из наборов правил в начальное состояние которое будет выведено из элементов текущего стиля. При этом используется getComputedStyle (или Element.currentStyle в IE) , таким образом , отражается фактический стиль элемента после применения правил CSS в таблицах стилей.

ex17 = new Animator().addSubject(
    new CSSStyleSubject(
        "ex17Button",
        "width: 300px; background-color: #F39"));

Наконец, есть один последний бит синтаксического сахара, чтобы сделать его легко применить эффектом. Animator.apply(element, style, options) функция является оберткой создание единого CSSStyleSubject . Второй аргумент стиля исчезает, чтобы использовать и третий необязательный набор параметров конструктора для Animator объекта. Если вы хотите указать полное значение для стилей, передать в массив двух элементов в качестве второго параметра.

ex18 = Animator.apply("ex18Button", "greenish"); // ta da!

О идтем дальше, есть еще одна особенность ...

По многочисленным просьбам ... Несколько человек просили легкий путь к цепи нескольких анимаций вместе. AnimatorChain это объект , который ведет себя похожим образом вроде Animator , но оборачивает несколько других Animator объектов и заставляет их играть в последовательности.

var animators = [];
for (var i=0; i<3; i++) {
    animators[i] = Animator.apply("ex18blob-" + i), "blobEnd";
}
ex19 = new AnimatorChain(animators);
// the AnimatorChain object has toggle(), play(), reverse()
// and seekTo(state) functions just like Animator objects,
// so you can often use them where code expects an Animator

Ну, вот и все. Наслаждайтесь использованием Animator.js, и не стесняйтесь оставлять свои комментарии и отзывы ниже.