React: примеры использования GSAP
Хочу поделиться с вами примерами использования GSAP .
Песочница:
Что такое GSAP ?
Если в двух словах, то GSAP (The GreenSock Animation Platform) — это набор инструментов для реализации анимации любого уровня сложности с помощью JavaScript .
Использование
cd react-gsap yarn add gsap
import < gsap >from 'gsap'
gsap.to('#logo', < duration: 1, x: 100 >) // or gsap.from("#logo", < duration: 1, x: 100 >) // or gsap.fromTo("#logo", < width: 0, height: 0 >, < duration: 1.5, width: 100, height: 200 >)
Методы gsap.to и gsap.from принимают 2 параметра:
- targets — анимируемый объект (или объекты). Это может быть один объект, массив объектов, ссылка на DOM-элемент или CSS-селектор типа ‘.myClass’ (в последнем случае GSAP использует метод document.querySelectorAll для получения ссылок на анимируемые объекты)
- vars — объект с настройками анимации ( opacity: 0.5, rotation: 45, duration: 1, onComplete: (message) => console.log(message), onCompleteParams: [‘потрачено’] и т.д.)
Метод gsap.fromTo принимает 3 параметра: targets , startVars , endVars .
Как организован проект?
Проект включает в себя 16 примеров, упакованных в одно приложение. Примеры условно можно можно разделить на простые и продвинутые. Переключение между примерами осуществляется с помощью селектора, реализованного с помощью хука useSelector из Downshift . По каждому примеру имеется краткое описание (см. ниже). Для того, чтобы эффект от прочтения статьи был максимальным рекомендую следующий алгоритм:
- хотя бы кратко знакомимся с материалами по ссылкам, приведенным выше
- читаем описание примера
- смотрим, как работает соответствующий компонент
- изучаем исходный код компонента
- воспроизводим компонент в своем приложении
Я старался комментировать ключевые моменты в коде компонентов, но вполне мог что-то упустить, поэтому приветствуется любая форма обратной связи.
Простые примеры
Применение анимации к одному (целевому) элементу
gsap требуется доступ к анимируемому DOM-элементу . Для предоставления такого доступа используется хук useRef . Разумеется, в момент анимирования элемент должен быть отрендерен, поэтому gsap должен запускаться в хуке useEffect :
export default function App() < // ссылка на элемент const el = useRef() // запускаем `gsap` после рендеринга useEffect(() =>< gsap.to(el.current, < // полный поворот rotation: '+=360' >) >) return ( > Square ) >
См. компонент AnimatingTargetElement .
Применение анимации ко всем потомкам
Для применения анимации к дочерним элементам (компонентам) используется вспомогательная функция utils.selector(el) , где el — предок анимируемых элементов:
const el = useRef() const q = gsap.utils.selector(el) useEffect(() => < // применяем анимацию ко всем потомкам элемента с CSS-классом `shape` gsap.to(q('.shape'), < x: 100 >) >, [])
См. компонент AnimatingAllDescendantElements .
Применение анимации к некоторым потомкам
Для применения анимации к некоторым дочерним элементам используется техника под названием перенаправление или передача ссылки (Ref Forwarding):
const el1 = useRef() const el2 = useRef() useEffect(() => < // ссылки на анимируемые элементы const squares = [el1.current, el2.current] gsap.to(squares, < x: 120, repeat: 3, repeatDelay: 1, yoyo: true >) >, [])
См. компонент AnimatingSomeDescendantElements .
Создание и управление состоянием анимации
Хук useRef может использоваться не только для получения доступа к DOM-элементу , но и для сохранения состояния между рендерингами компонента, такого как состояние анимации:
export default function App() < const el = useRef() const q = gsap.utils.selector(el) // состояние анимации const tl = useRef() useEffect(() =>< tl.current = gsap.timeline() // сначала анимируем квадрат .to(q(".square"), < rotate: 360 >) // затем анимируем круг .to(q(".circle"), < x: 100 >) >, []) return ( > Square Circle ) >
См. компонент ControllingAnimationTimeline .
Управление запуском анимации
По умолчанию хук useEffect запускается после первого и каждого последующего рендеринга. Вызов useEffect означает запуск анимации. Для управления запуском useEffect (и анимации) используется массив зависимостей, когда отсутствие массива означает запуск после первого и каждого последующего рендеринга, пустой массив — запуск только после первого рендеринга, массив с зависимостями — запуск после первого рендеринга и при каждом изменении (любой) зависимости:
// запускается только после первого рендеринга useEffect(() => < gsap.to(q(".square.red"), < rotation: "+=360" >) >, []) // запускается после первого рендеринга и после каждого изменения зависимости `someProp` useEffect(() => < gsap.to(q(".square.green"), < rotation: "+=360" >) >, [someProp]) // запускается после первого и каждого последующего рендеринга useEffect(() => < gsap.to(q(".square.blue"), < rotation: "+=360" >) >)
См. компонент ControllingAnimationStart .
Запуск анимации в ответ на изменение состояния
Пример запуска анимации в ответ на изменение пропа, передаваемого дочернему компоненту:
const Square = (< children, randomX >) => < const el = useRef() // запускается при каждом изменении пропа `randomX` useEffect(() =>< gsap.to(el.current, < x: randomX >) >, [randomX]) return ( > ) >
См. компонент AnimationStartPropChange .
Запуск анимации в ответ на действие пользователя
Пример запуска анимации в ответ на действие пользователя (наведение курсора на элемент):
// вызывается при наведении курсора const onEnter = (< currentTarget >) => < gsap.to(currentTarget, < backgroundColor: "#e77614" >) > // вызывается при "снятии" курсора const onLeave = (< currentTarget >) => < gsap.to(currentTarget, < backgroundColor: "#28a92b" >) > return ( onMouseLeave= > Square )
См. компонент AnimationStartUserAction .
Предотвращение «вспышек»
Во избежание вспышек (мигания или мерцания) вместо хука useEffect следует использовать хук useLayoutEffect . Как вы знаете, последний запускается синхронно, т.е. перед отрисовкой DOM :
useLayoutEffect(() => < // код выполняется только в том случае, // если `state` имеет значение `complete` if (state !== 'complete') return // анимируем дочерние компоненты // перед отрисовкой `DOM` gsap.fromTo( q('.square'), < opacity: 0 >, < opacity: 1, duration: 1, stagger: 0.33 >) >, [state])
См. компонент AnimationWithoutFlash .
Не забывайте об отключении анимации и удалении обработчиков событий при размонтировании компонента, особенно, если речь идет о длительной анимации, использовании плагинов вроде ScrollTrigger или изменении состояния компонента:
useEffect(() => < const anim1 = gsap.to('.box1', < rotation: '+=360' >) const anim2 = gsap.to('.box2', < scrollTrigger: < // . >>) const onMove = () => < // . >window.addEventListener('pointermove', onMove) // очистка при размонтировании компонента return () => < anim1.kill() anim2.scrollTrigger.kill() window.removeEventListener('pointermove', onMove) >>)
Продвинутые примеры
Взаимодействие компонентов
Порой требуется распределить жизненный цикл анимации ( timeline ) между несколькими компонентами. Также иногда анимация зависит от элементов, находящихся в разных компонентах.
Для решения подобных задач существует 2 подхода:
- передача timeline от родительского компонента дочерним через пропы
- передача колбека, вызываемого дочерними компонентами для добавления анимации в timeline
Передача timeline через пропы
function Square(< children, timeline, index >) < const el = useRef() // добавляем анимацию в `timeline` useEffect(() =>< timeline.to(el.current, < x: -100 >, index * 0.1) >, [timeline]) return > > function Circle(< children, timeline, index, rotation >) < const el = useRef() // добавляем анимацию в `timeline` useEffect(() =>< timeline.to(el.current, < rotate: rotation, x: 100 >, index * 0.1) >, [timeline, rotation]) return > > export default function App() < // жизненный цикл анимации const [tl, setTl] = useState(() =>gsap.timeline()) return ( <>* передаем `timeline` в качестве пропа */> index=>Square rotation= index=>Circle >) >
См. компонент PassingTimelineThroughProps .
Передача колбека для добавления анимации в timeline
function Square(< children, addAnimation, index >) < const el = useRef() // создаем анимацию и добавляем ее в `timeline` useEffect(() =>< const animation = gsap.to(el.current, < x: -100 >) addAnimation(animation, index) return () => animation.progress(0).kill() >, [addAnimation, index]) return > > function Circle(< children, addAnimation, index, rotation >) < const el = useRef() // создаем анимацию и добавляем ее в `timeline` useEffect(() =>< const animation = gsap.to(el.current, < rotate: rotation, x: 100 >) addAnimation(animation, index) return () => animation.progress(0).kill() >, [addAnimation, index, rotation]) return > > export default function App() < // жизненный цикл анимации const [tl, setTl] = useState(() =>gsap.timeline()) // передаем дочерним компонентам колбек // для добавления анимации в `timeline` const addAnimation = useCallback((animation, index) => < tl.add(animation, index * 0.1) >, [tl]) return ( <> index=>Square index= rotation="360">Circle >) >
См. компонент PassingCallbackThroughProps .
Передача timeline через контекст
Передавать timeline или колбек для добавления анимации в timeline не всегда удобно. Что если нам нужно передать timeline компоненту, глубоко вложенному в другие компоненты? В этом случае не обойтись без контекста.
const SelectedContext = createContext() function Square(< children, id >) < const el = useRef() const selected = useContext(SelectedContext) useEffect(() =>< gsap.to(el.current, < // сдвигаем элемент на `200px` влево, если его `id` // совпадает со значением `selected` из контекста x: selected === id ? 200 : 0 >) >, [selected, id]) return > > export default function App() < // любой компонент может читать значения из контекста, // независимо от уровня его вложенности // в данном случае мы передаем `2` в качестве начального значения return ( Square 1 Square 2 Square 3 ) >
См. компонент PassingTimelineThroughContext .
Императивное взаимодействие
Передача пропов или использование контекста в большинстве случаев работает хорошо, но эти механизмы приводят к повторной отрисовке компонентов, что может оказать негативное влияние на производительность при постоянном изменении значения, например, при отслеживании позиции курсора.
Для пропуска рендеринга мы можем использовать хук useImperativeHandle и создать API для компонента. Любое значение, возвращаемое хуком, будет передаваться компоненту в виде ссылки:
const Circle = forwardRef((props, ref) => < const el = useRef() useImperativeHandle(ref, () =>< // возвращаем `API` return < moveTo(x, y) < gsap.to(el.current, < x, y >) > > >, []) return > >) export default function App() < const circleRef = useRef() useEffect(() =>< // повторный рендеринг не запускается! circleRef.current.moveTo(300, 100) >, []) return ( <> /> >) >
См. компонент ImperativeHandleMousePosition .
Создание переиспользуемых анимаций
Создание переиспользуемых анимаций — отличный способ сохранения чистоты кода и уменьшения его количества. Простейшим способом это сделать является вызов функции для создания анимации:
const fadeIn = (target, args) => gsap.from(target, < opacity: 0, . args >) function App() < const el = useRef() useLayoutEffect(() =>< fadeIn(el.current, < x: 100 >) >, []) return >Square >
Более декларативный подход предполагает создание компонента-обертки для обработки анимации:
function FadeIn(< children, args >) < const el = useRef() useLayoutEffect(() =>< gsap.from(el.current.children, < opacity: 0, . args >) >, []) return > > function App() < return ( >> Square ) >
См. компонент ReusableAnimationWrapper .
Использование gsap.effects
Рекомендуемым способом создания переиспользуемых анимаций является метод registerEffect() :
function GsapEffect(< children, targetRef, effect, args >) < useLayoutEffect(() => < if (gsap.effects[effect]) < gsap.effects[effect](targetRef.current, args) >>, [effect]) return <> >> function App() < const el = useRef() return ( effect="spin"> >Square ) >
См. компонент ReusableAnimationRegisterEffect .
Выход из анимации
Как анимировать удаление элемента из DOM ? Одним из способов это сделать является изменение состояния компонента после завершения анимации:
function App() < const el = useRef() const [active, setActive] = useState(true) const remove = () => < gsap.to(el.current, < opacity: 0, onComplete: () =>setActive(false) >) > return ( < active ? >Square : null > ) >
См. компонент RemovingSingleElementFromDom .
Точно такой же подход применим в отношении нескольких элементов:
function App() < const [items, setItems] = useState([ < id: 0 >, < id: 1 >, < id: 2 >]) const removeItem = (value) => < setItems(prev =>prev.filter(item => item !== value)) > const remove = (item, target) => < gsap.to(target, < opacity: 0, onComplete: () =>removeItem(item) >) > return ( ( onClick= remove(item, e.currentTarget)>> Click Me ))> ) >
См. компонент RemovingMultipleElementsFromDom .
Кастомные хуки
Кастомные хуки позволяют извлекать логику анимации в переиспользуемые функции.
Вот как можно реализовать пример с registerEffect с помощью кастомного хука:
function useGsapEffect(target, effect, vars) < const [animation, setAnimation] = useState() useLayoutEffect(() =>< setAnimation(gsap.effects[effect](target.current, vars)) >, [effect]) return animation > function App() < const el = useRef() const animation = useGsapEffect(el, "spin") return >Square >
useSelector
Хук для выборки дочерних компонентов.
function useSelector() < const ref = useRef() const q = useMemo(() =>gsap.utils.selector(ref), []) return [q, ref] >
function App() < const [q, ref] = useSelector() useEffect(() =>< gsap.to(q(".square"), < x: 200 >) >, []) return ( > Square ) >
useArrayRef
Хук для добавления ссылок в массив.
function useArrayRef() < const refs = useRef([]) refs.current = [] return [refs, (ref) =>ref && refs.current.push(ref)] >
function App() < const [refs, setRef] = useArrayRef() useEffect(() =>< gsap.to(refs.current, < x: 200 >) >, []) return ( >Square 1 >Square 2 >Square 3 ) >
useStateRef
Данный хук решает проблему доступа к значениям состояния в колбеках. Он похож на useState , но возвращает третье значение — ссылку на текущее состояние.
function useStateRef(defaultValue) < const [state, setState] = useState(defaultValue) const ref = useRef(state) const dispatch = useCallback((value) =>< ref.current = typeof value === "function" ? value(ref.current) : value setState(ref.current) >, []) return [state, dispatch, ref] >
const [count, setCount, countRef] = useStateRef(5) const [gsapCount, setGsapCount] = useState(0) useEffect(() => < gsap.to(box.current, < x: 200, repeat: -1, onRepeat: () =>setGsapCount(countRef.current) >) >, [])
Пожалуй, это все, чем я хотел поделиться с вами в данной статье.
Что касается моего личного мнения о GSAP , то, пожалуй, это один из наиболее простых и вместе с тем продвинутых инструментов в своей категории. Теперь это мой первый (после CSS и SASS ) кандидат на реализацию анимации в веб-приложениях.
Благодарю за внимание и хорошего дня!
GreenSock Animation Platform (GSAP)
GSAP — это анимационная платформа, созданная в свое время для Action Script, теперь портирована и на JS.
Умеет анимировать свойства абсолютно любых объектов, удобный в использовании, легкий в весе и, что самое главное, очень шустрый. Тест скорости работы..
Так же нужно отметить кроссбраузерность ( работает во всех браузерах начиная от ИЕ6 ), абсолютную независимость от других фреймворков, возможность организации и управления timeline — компоновка анимаций в единное целое на усмотрение разработчика, небольшой вес ( к примеру, версия TweenLite.min весит на сегодняшний день 21kb ), удобный и интуитивно понятный API, отличная документация, подключаемые плагины ( изинг, кривые бизье, плагин для работы с Raphael, плагин cssRules ), а так же понятный и доступный туториал.
Быстрый старт
Простейший твин имеет такой вид:
TweenLite.to( element:object, time:int, params:object )
Где element – объект для манипуляций, time – длительность анимации, params – анимируемые параметры и установки.
По умолчанию GSAP оперирует с числовыми свойствами объектов. Попробуем изменить размеры изображения:
window.onload = function() < var element = document.getElementById( 'test' ); TweenLite.to( element, 2, < width: 500 >); >
CSS анимация
Для анимации css-свойств, дополнительно подключаем CSSPlugin и EaselPlugin для easing-еффекта:
Теперь можем анимировать любой числовое css-свойство, подвинем картинку:
window.onload = function()< var element = document.getElementById( 'test' ); TweenLite.to( element, 2, < css: < left: window.innerWidth * .5 - 125 >, ease: Power2.easeOut > ); >
А можно тоже самое сделать так:
window.onload = function()< var element = document.getElementById( 'test' ); TweenLite.to( element, 2, < css: < x: window.innerWidth * .5 - 125 >, ease: Power2.easeOut > ); >
Разница в том, что в первом случае изменяется свойство left элемента, а во втором для перемещения применяется CSS3 транcформация.
Вот еще пример трансформаций:
window.onload = function()< var element = document.getElementById( 'test' ); TweenLite.to( text, 2, < css: < skewX: 400, scaleX: .5, scaleY: .5, rotation: '180deg', transformOrigin: 'right center' >, ease: Power1.easeInOut > ); >
Сложность анимации ограничена фантазией и креативностью разработчика.
GSAP и canvas
Анимация на канве при помощи GSAP не особо отличается от вышеописанных примеров:
window.onload = function()< var canvas = document.getElementById( 'canvas' ), ctx = canvas.getContext( '2d' ), // это объект, параметры которого будут изменяться square = < width: 100, height: 100, top: 100, left: 100 >; canvas.width = window.innerWidth; canvas.height = window.innerHeight; ctx.fillStyle = '#ff0000'; // функция отрисовки в канву function draw()< ctx.clearRect( 0, 0, canvas.width, canvas.height ); ctx.save(); // отрисовываем квадрат по параметрам из анимируемого объекта ctx.translate( square.left - square.width * .5, square.top - square.height * .5 ); ctx.fillRect( 0, 0, square.width, square.height ); ctx.restore(); >; // начинаем анимировать объект TweenLite.to( square, 5, < left: canvas.width * .5, top: canvas.height * .5, width: 200, height: 200, onUpdate: draw >); >
Timeline
Ну и как же без него? Таймлайн позволяет объединить анимации в одно целое, и манипулировать им. Простыми словами выполняем монтаж фильма, а затем проигрываем его:
window.onload = function()< var canvas = document.getElementById( 'canvas' ), playBtn = document.getElementById( 'play' ), reverseBtn = document.getElementById( 'reverse' ), pauseBtn = document.getElementById( 'pause' ), ctx = canvas.getContext( '2d' ), // красный квадрат square = < width: 100, height: 100, top: 100, left: 100 >, // черный квадрат square2 = < width: 100, height: 100, top: 250, left: 100 >, // создаем timeline объект и ставим его на паузу timeline = new TimelineLite( < paused: true >); canvas.width = window.innerWidth; canvas.height = window.innerHeight; function draw()< ctx.clearRect( 0, 0, canvas.width, canvas.height ); // отрисовка красного квадрата ctx.fillStyle = '#ff0000'; ctx.save(); ctx.translate( square.left - square.width * .5, square.top - square.height * .5 ); ctx.fillRect( 0, 0, square.width, square.height ); ctx.restore(); // отрисовка черного квадрата ctx.fillStyle = '#000000'; ctx.save(); ctx.translate( square2.left - square2.width * .5, square2.top - square2.height * .5 ); ctx.fillRect( 0, 0, square2.width, square2.height ); ctx.restore(); >; draw(); // вставляем анимацию красного квадрата в начало timeline timeline.insert( TweenLite.to( square, 5, < left: canvas.width * .5, top: canvas.height * .5, width: 200, height: 200, onUpdate: draw >) ); // вставляем анимацию черного квадрата со сдвигом во времени равному 1 секунде, относительно начала timeline timeline.insert( TweenLite.to( square2, 5, < left: canvas.width * .5, top: canvas.height * .5, width: 200, height: 200, onUpdate: draw >), 1 ); // последний параметр – сдвиг по таймлайну // обработчики для кнопок playBtn.onclick = function()< timeline.play(); >; pauseBtn.onclick = function()< timeline.pause(); >; reverseBtn.onclick = function()< timeline.reverse(); >; >
В примерах использована версия TweenLite, есть еще версия TweenMax, в нее уже вшиты некоторые плагины ( например CSSPlugin и EaselPlugin ), а так же несколько расширен функционал – доступны такие фишки как yo-yo ( анимация вперед и обратно ), timeScale(), repeat() и т.п
Все это малая доля того что умеет платформа. Кроме описанных плагинов на сегодняшний день еще существует плагины для работы с цветом, кривыми Бизье, библиотекой Raphael, css-правилами, плагин для округления просчитываемых параметров, scrollTo – аналог плагина для jQuery, а так же довольно обширное API для timeline. Помимо этого обладает еще массой свойств, параметров и настроек ( наприемр callback-функции ). Все это отлично описано в API
В версиях для AS есть еще очень много плюшек.. ну что ж, ждем портации этих плюшек на JS 🙂
Материалы
- Нить потянулась с хабра раз и два
- Официальный сайт разработчиков ( на англ. )
- GSAP JS Tutorial ( на англ. )
- GSAP JS API ( на англ. )
- AJAX
- AJAX запрос
- Отмена AJAX-запроса
- CSS3 PIE
- Explorer Canvas
- html5shiv — HTML5 теги для IE
- IE и динамическая вставка canvas
- jQuery-Placeholder — замещающийся текст
- Modernizr — HTML5 и CSS3 уже сегодня
- PIE для скрытых или динамических элементов
- FancyBox — галерея и модальное окно
- Highslide JS — фотогалерея
- JCarouselLite. Прокрутка слайдов
- Spacegallery — эффектная 3D галерея
- Галерея jQuery ColorBox
- Галерея jQuery lightBox
- Галерея с неравномерным шагом
- Забавная галерея Tiny Circleslider
- Листалка слайдов Tiny Carousel
- Слайдер Coin Slider
- Слайдер jQuery Cycle
- Drag-n-Drop загрузка файлов
- jQuery UI Slider — ползунок выбора диапазона
- jQuery UI Slider — усложненный вариант выбора диапазона
- JScrollPane 2 — настраиваемый скроллбар
- JScrollPane. Делаем красивый скроллинг
- Masked Input Plugin
- Tiny Scrollbar — настраиваемый скроллбар
- UI resizable — изменение размеров
- ZeroClipboard — копируем в буфер
- Zoomy — лупа на jQuery
- Группируем инпуты
- Интерактивная SVG-карта на Raphael
- Плагин jQuery cloud-zoom (лупа)
- Плагин jQuery drag из набора Interface
- Плагин jQuery EasyDrag — проще не бывает
- Скрываем окно по клику снаружи
- CSS Multi Column
- Определение браузера и его версии
- Позиционирование блока по центру с учетом скрола
- Фиксированный блок с изменяющимся отступом сверху
- Кэширование Ajax-запросов
- Оптимизация DOM анимации
- Оптимизация jQuery.animate
- Почему jQuery лучше грузить с Google
- Программная анимация
- autoResize: textarea подстраивается под высоту текста
- cuText — нестандартный textarea на JQuery
- Фильтрация и проверка данных полей
- Изображения
- Блюр
- Вкладки и кнопка Back
- Выпадающее окошко с задержкой
- Диагональ к выпавшему меню
GSAP. Як працює JavaScript-бібліотека для анімацій
Вітаю! Мене звати Віктор, я front-end розробник на випробувальному терміні у компанії. Хочу поділитись зручною і потужною бібліотекою для анімацій — GSAP. Сподіваюся, що стаття буде цікавою для front-end розробників, які цікавляться вивченням нових для себе технологій.
Роль анімацій у вебі
Всі ми знаємо, як важлива анімація у сучасному вебі, вона допомагає якісніше подати інформацію, привертає на себе увагу і підштовхує досліджувати кожен анімований клаптик вебсайту.
У веброзробці існує кілька типів анімацій, що можуть бути застосовані на вебсайтах:
- CSS анімації;
- SVG анімації — вони використовують масштабовані векторні графічні об’єкти (SVG), щоб створити рухомі ефекти;
- JavaScript анімації — створюються за допомогою JavaScript-коду, який змінює властивості елементів HTML або SVG;
- WebGL анімації (Web Graphics Library) — це анімації, що використовують WebGL, щоб створити складні 3D-сцени та інші реалістичні ефекти.
Труднощі в роботі Front-end та анімацій
Частина фронтендерів мене зрозуміють. Бувало таке, що тобі дають дизайн, ти його уважно досліджуєш, в голові розкладаєш по поличках, з чого будеш починати, на що звернути особливу увагу.
І тут виявляєш вкладку у Figma з підписом Animations. І в голові тільки одне.
Переглядаючи всі анімації на дизайні, ти думаєш: «В цілому, якщо зліпити їх всі в один ролик, вийшов би непоганий мультфільм від Disney.»
У такі моментіи видно досвід дизайнера. Новачок буде малювати 3D-сцени до звичайних кнопок, а досвідчений дизайнер має знайти межі тих анімацій. Ще потрібно не забувати про вартість ресурсів браузера, які використовуються для їх відпрацювання.
Також я прихильник того, що дизайнер має уявляти в загальному, як працює розробка. Тобто, мінімальні знання html та CSS зайвими не будуть.
Хоча по суті, з сучасними бібліотеками можливо зробити будь-який ефект, але невідомо, чи браузер буде відображати його з 60 кадрами в секунду.
Варто зазначити, що 60 кадрів в секунду — це стандартна частота оновлення екрана. Так, бувають екрани з більшою частотою (120гц, 144гц, 240гц), проте браузери навчились обмежувати частоту до 60гц, хоча також цей ліміт можна прибрати.
Прихід анімаційних бібліотек у веброзробку
Прихід бібліотек для роботи з анімаціями у розробку дуже спростив життя фронтенд-розробникам. Оскільки важкі анімації затратно писати на чистому JS + CSS, то навіщо себе мучити, якщо можна прочитати документацію бібліотеки та зробити аналогічний код всього одним рядком.
Звичайно бібліотек по анімації існує безліч, для різних завдань і на будь-який смак. Існує також багато типів анімації: анімація при скролі сторінки, заклик до дії, переходи між сторінками або блоками, svg, canvas тощо.
Проте я вибрав таку бібліотеку, яка містить цілу платформу можливостей. Як ви вже здогадались з назві статті, мова буде йти про GSAP.
GSAP — GreenSock animation Platform
З домашньої сторінки GSAP — це JavaScript-анімація професійного рівня для сучасного Web.
Простою мовою, GSAP — це набір інструментів, які дозволяють створювати сценарій анімації. Компанія визначає себе трьома словами — швидкість, надійність і сумісність. Сумісність полягає в тому, що GSAP працює з React, Vue, Angular і ’ванільним’ JavaScript.
Налічується більш як 4 млн сайтів, на яких використовується GSAP, а саме в таких компаніях як Adobe, Amazon, YouTube, Samsung, Intel та багато інших.
У вкладці «Продукти» вказані плагіни для виконання різноманітних завдань, найпопулярніші це:
- Flip — використовується для роботи зі станами сторінки, коли перемальовується DOM;
- ScrollTrigger та ScrollSmoother — створюють приголомшливі анімації на основі скролу сторінки;
- InertialPlugin — вміщує в себе легку роботу з DragAndDrop;
- TextPlugin та SplitText — налаштування анімацій для текстів.
Підключення бібліотеки
Існує декілька способі отримати GSAP:
- Завантажити файли локально,
- CND,
- NPM,
- GitHub,
- CodePen.
За посиланням ви знайдете детальну інструкцію.
Синтаксис GSAP
У цьому розділі коротко пройдемось по основних методах та розглянемо прості приклади використання GSAP. Детальніше читайте в документації.
Щоб отримати максимальні можливості від GSAP, дуже важливо розуміти, що таке Tweens і Timelines: Tween — це механізм, що відповідає за анімацію, який приймає завдання (об’єкти, які ви хочете анімувати), тривалість та інші властивості.
1) gsap.to(): першим параметром метод приймає блок, до якого буде підключена анімація, а другим — об’єкт, в якому прописані параметри, які відпрацюють при завантаженні скрипта. Тобто якщо прописано , то елемент при завантаженні переміститься на 150 пікселів по осі X, що і показано на прикладі нижче.
2) gsap.from(): першим параметром метод приймає блок, а другим — об’єкт, в якому прописано, де значення мають починатись і рухатись до поточного стану блоку. Тобто в CSS ми пишемо, де блок має розміщуватись в кінці анімації.
3) gsap.fromTo() — першим параметром метод приймає блок, другим приймає об’єкт, звідки має починатись анімація (аналог gsap.from() ), третім приймає об’єкт, де вона повинна закінчитись (аналог gsap.to() ).
Timeline — це потужний інструмент для послідовності анімації, що діє як контейнер для tween та інших timeline, що робить простим керування ними в цілому та точне керування їхнім часом. Без timeline побудова складних послідовностей була б набагато важчою, оскільки для кожної анімації потрібно було б використовувати затримку.
Приклад з використанням звичайного gsap.to().
gsap.to("#id", );
gsap.to("#id", ); //1 секунда затримки
gsap.to("#id", ); // 2 секунди затримки
gsap.to("#id", ); // 3 сек затримки
А тепер розглянемо, як цей приклад буде виглядати з timeline, затримок писати не потрібно, оскільки анімації йдуть одна за одною.
var tl = gsap.timeline();
tl.to("#id", );
tl.to("#id", );
tl.to("#id", );
tl.to("#id", );
Найвідоміші аналоги
- Three.js 90.2к зірочок GitHub;
- Anime.js 44.8к зірочок GitHub;
- Scrollreveal.js 21.4к зірочок GitHub;
- Mo.js 17.9к зірочок GitHub.
Також розробники GSAP створили сторінку, на якій можна переглянути, як будуть працювати інші бібліотеки в порівнянні з GSAP з різним навантаженням (показано нижче). Результати, чесно кажучи, мене вразили.
На завершення
Загалом, GSAP — це потужна бібліотека для анімацій, яка дозволяє створювати вражаючі та динамічні анімаційні ефекти з великим переліком налаштувань.
Звичайно, я не зможу показати вам всі можливості GSAP у цій статті, це можуть зробити тільки розробники у своїй чудово написаній документації.
Стаття мала ідею познайомити вас з цікавою бібліотекою, якої не потрібно боятись, а навпаки — почати використовувати у своїх проєктах.
Також за останній рік збільшились вимоги до кандидатів на фронтенд, особливо для джунів. І часто рекрутери додають у розділ «Will be a plus» різні бібліотеки для анімацій. Гадаю, у близькому майбутньому їх знання буде обов’язковим.
Подобається Сподобалось 14
До обраного В обраному 9
GreenSock для начинающих: учебник по веб-анимации (часть 1)
Моя цель в этой статье — дать вам полное представление о GreenSock , также известном как GSAP (GreenSock Animation Platform), суперэффективном, профессиональном анимационном движке HTML5 для современной сети.
Это четвертая статья в серии Beyond CSS: библиотеки динамической анимации DOM .
Смотрите, как сделать ваш CSS движущимся, используя принципы перехода, преобразования и анимации
Вот несколько кратких советов для вас, товарищи по аниматорам CSSВот что я освещал в прошлых выпусках:
- Анимация DOM с помощью Anime.js затрагивает вопрос о том, как наилучшим образом использовать анимацию в Интернете и когда вы можете рассмотреть возможность использования библиотеки анимации JavaScript вместо анимации только с CSS. Затем он фокусируется на Anime.js, бесплатной и легкой библиотеке анимации JavaScript
- Забавные анимационные эффекты с KUTE.js знакомят вас с KUTE.js, бесплатной и многофункциональной библиотекой анимации JavaScript
- Сделайте ваш сайт интерактивным и увлекательным с Velocity.js (без jQuery) показывает, как использовать Velocity.js, надежную бесплатную библиотеку анимации с открытым исходным кодом, для создания качественных веб-анимаций.
GSAP имеет слишком много функций, чтобы поместиться в одной статье. Вот почему я выбрал статью из нескольких частей, посвященную различным областям библиотеки GreenSock.
- К концу этой первой части вы узнаете о возможностях и возможностях GreenSock, модели лицензирования, основных компонентах и базовом синтаксисе для анимации и разбивки элементов DOM.
- Во второй части я познакомлю вас с собственными временными возможностями GreenSock.
- Наконец, часть 3 будет посвящена некоторым мощным бонусным плагинам, которые GreenSock делает доступными для выполнения сложных задач анимации с помощью нескольких строк кода.
Если вы уже являетесь ниндзя GSAP, ознакомьтесь с анимационными каруселями начальной загрузки с библиотекой анимации GSAP, где Джордж Марцукус иллюстрирует эффективное использование GreenSock для анимации пользовательского интерфейса.
Без лишних слов, приготовьтесь, путешествие вот-вот начнется!
Что такое GreenSock и для чего он нужен?
GreenSock — это де-факто стандартная платформа анимации JavaScript, доступная сегодня.
Это зрелая библиотека JavaScript, которая берет свое начало в Flash-анимации. Это означает, что парни из GreenSock знают веб-анимацию наизнанку, библиотека существует уже давно и никуда не денется в ближайшее время.
GSAP включает в себя полный набор инструментов, утилит и плагинов, которые вы можете использовать для решения любых задач веб-анимации, от которых вы сталкиваетесь: от последовательной анимации SVG в разных браузерах до кодирования сложных анимационных последовательностей, перетаскивания элементов по экрану, разделения и скремблирования текста, и многое другое.
Чтобы упомянуть только три вещи, которые я особенно люблю в GreenSock:
- Хотя библиотека мега богата с точки зрения возможностей, кривая обучения относительно невелика, поскольку она использует интуитивно понятный и непротиворечивый синтаксис во всех своих различных реализациях и плагинах. Кроме того, он предлагает отличную документацию, учебные пособия и поддержку через форумы GSAP . Кроме того, сама библиотека постоянно обновляется и поддерживается. Все это важные факторы при создании проекта, который использует внешнюю библиотеку для выполнения каких-либо ключевых функций и взаимодействия с пользователем.
- Он модульный и легкий, что означает, что он не добавит раздувания в ваши веб-проекты
- Благодаря своей мощной временной шкале GSAP обеспечивает точный контроль времени не только отдельных анимаций, но и нескольких анимаций в рамках всего анимационного потока.
Основные инструменты GreenSock
Это основные модули GreenSock:
- TweenLite — основа GSAP, легкой и быстрой библиотеки анимации HTML5
- TweenMax — расширение TweenLite, которое помимо самого TweenLite включает в себя:
- TimelineLite
- TimelineMax
- CSSPlugin
- AttrPlugin
- RoundPropsPlugin
- DirectionalRotationPlugin
- BezierPlugin
- EasePack
Вы можете включить TweenLite в свой проект, а затем добавлять другие модули по мере необходимости. В качестве альтернативы вы можете включить TweenMax (подход, который я собираюсь использовать в этой серии из нескольких частей), которая объединяет все основные модули в один оптимизированный файл.
Также стоит отметить, что GSAP предлагает некоторые платные дополнения, такие как DrawSVGPlugin для создания анимированных эффектов рисования линий с помощью SVG, мощный MorphSVGPlugin для преобразования одной фигуры SVG в другую (даже не требуя, чтобы две фигуры имели одинаковое количество точек), и другие , Хотя для использования этих плагинов вы должны быть платным членом Club GreenSock, GSAP предоставляет вам бесплатную специальную версию на базе CodePen, чтобы вы могли опробовать их. Это классное предложение, которое я собираюсь в полной мере использовать позже в части 3 (и вы со мной).
Лицензия
GSAP не приняла бесплатную лицензию с открытым исходным кодом, такую как MIT, в основном по причинам, которые касаются поддержания высокого качества продукта и его финансовой устойчивости в долгосрочной перспективе.
GreenSock предоставляет две лицензии :
- Стандартная лицензия — использование библиотеки абсолютно бесплатно в цифровых продуктах, которые можно использовать бесплатно (даже если разработчикам платят за их создание)
- Business Green — эта лицензия включает в себя три уровня со средним уровнем, Shockingly Green , который является самым популярным. Будучи участником Shockingly Green, вы получите доступ ко всем бонусным плагинам и дополнениям, но без коммерческой лицензии.
Несмотря на несоблюдение MIT и аналогичных лицензий на бесплатное использование, позволяя вам заглянуть в его сырой код как в репозитории GitHub проекта, так и в ваших загрузках, GreenSock рекомендует вам учиться на коде своих разработчиков и их мастерстве в JavaScript-анимации, которая является одной из лучших особенностей философии открытого исходного кода.
Твининг с GreenSock
Простая анимация состоит из каких-то изменений, которые происходят со временем от точки А к точке Б. Аниматоры имеют специальное имя для состояний между А и В, т. Е. Анимацию движения.
TweenLite и TweenMax — два мощных инструмента анимации движения, которые GreenSock предоставляет в ваше распоряжение. Как я уже говорил выше, я собираюсь сосредоточиться на TweenMax здесь, но помните, что основной синтаксис одинаков в обеих библиотеках.
Чтобы загрузить GSAP в свой проект, добавьте этот перед закрывающим вашего HTML-документа:
script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.1/TweenMax.min.js">script>
Вы можете найти последнюю версию, доступную на CDN здесь: cdnjs.com .
Если вы используете npm , введите это в своем терминале:
npm install gsap
На CodePen вы найдете ссылку на GSAP TweenMax в поле быстрого добавления в настройках JavaScript:
Базовый Твин с GreenSock: Синтаксис
Простая анимация с GSAP выглядит так:
TweenMax.to('.my-element', 1, opacity: 0>);
Приведенный выше фрагмент анимирует элемент DOM с классом my-element от текущего значения непрозрачности по умолчанию до значения непрозрачности 0 в течение 1 секунды. Другими словами, в конце длительности анимации продолжительностью 1 секунда элемент больше не будет виден.
Давайте углубимся в детали.
TweenMax.to() сообщает браузеру, что вы используете метод to() библиотеки TweenMax (синтаксис для TweenLite такой же, только замените TweenMax на TweenLite). Этот метод нуждается в нескольких аргументах, разделенных запятыми:
- Элемент, который вы хотите анимировать (‘.my-element’)
- Продолжительность анимации (в данном случае 1 секунда)
- Объект vars <> , то есть свойства, которые вы хотите анимировать (в данном случае свойство opacity ). Эта последняя часть входит в фигурные скобки и принимает форму пар ключ / значение. Значение выражает конечное состояние анимации. Есть также другие свойства, которые вы можете использовать внутри vars object <> такие как функции обратного вызова, задержки и т. Д.
Как следует из его названия, метод to() анимирует изменяемые свойства от их значений по умолчанию до того, что вы хотите, чтобы эти значения были в конце анимации.
GSAP предлагает множество методов, но основными, кроме to() являются:
-
from() — позволяет вам определить начальные значения вашей анимации. Поэтому элемент будет анимироваться, начиная со значений, которые вы указываете внутри from() до значений по умолчанию, которые обычно задаются в ваших правилах CSS. Синтаксис выглядит так:
TweenMax.from('.my-element', 1, opacity: 0>);
TweenMax.fromTo('.my-element', 1, opacity: 1 // from state >, < opacity: 0 // to end state >);
Вот все три метода в действии, поскольку они применяются к свойствам поворота и перемещения:
GSAP отрывается от синтаксиса CSS, используя rotation вместо rotate .
Также обратите внимание, что для перевода элемента по оси X или Y GreenSock не использует transform: translateX() или transform: translateY() . Скорее, он использует x (как в живой демонстрации), y , xPercent и yPercent .
Хотя свойства x и y в основном основаны на пикселях, xPercent и yPercent используют процентные значения для перевода элементов по оси X и Y соответственно ( CSSPlugin docs ).
Наконец, имейте в виду, что для перевода элемента в координаты X или Y необходимо установить свойство CSS position элемента как relative или absolute .
Какие свойства CSS использует GSAP Animate?
С GreenSock все CSS анимируемые свойства у вас под рукой. Вы можете анимировать CSS-преобразования, как описано выше, а также другие сложные свойства, такие как box-shadow: 1px 1px 1px rgba(0,0,0,0.5) и border: 1px solid red . Просто не забудьте использовать camelCase везде, где стандартное имя свойства CSS использует тире (-), например, backgroundColor вместо background-color .
Использование метода GreenSock set()
Если вам необходимо установить некоторые свойства с определенными значениями перед их анимацией, вы можете сделать это либо в своем CSS, либо с помощью метода set() GreenSock. Этот последний вариант дает преимущество, заключающееся в хранении всего кода, связанного с анимацией, в одном месте, то есть в документе JavaScript.
Например, первый пример в живой демонстрации выше начинается с изображения, установленного в слегка наклонном положении. Этот первоначальный выбор не указан в документе CSS, но в документе JavaScript с использованием метода set() GSAP, например:
TweenMax.set(toElement, rotation: -45>);
Синтаксис такой же, как у обычной анимации, но без параметра продолжительности. Это гарантирует, что изменение происходит немедленно.
Создание последовательностей твинов с GreenSock
Вы можете создавать последовательности анимации с помощью GreenSock и координировать их взаимодействие, регулируя свойства duration и delay каждой анимации.
Например, в приведенном ниже примере кода нажатие кнопки « Уведомить меня» запускает следующую последовательность анимации:
- Появляется поле ввода
- Когда поле ввода становится длиннее, кнопка « Уведомить меня» исчезает
- Наконец, внутри поля ввода появляется маленькая кнопка « Отправить» .
Вот код GSAP для последовательности (код идет внутри обработчика щелчка для кнопки):
// input box appears and gets bigger TweenMax.to(emailInput, 0.5, < autoAlpha: 1, scale: 1 >); // the button being clicked disappears TweenMax.to(this, 1, < autoAlpha: 0 >); // the send button appears and gets bigger TweenMax.to(sendButton, 0.5, < autoAlpha: 1, scale: 1, delay: 0.5, ease: Back.easeOut.config(3) >);
Во фрагменте вы можете увидеть два новых свойства — autoAlpha и autoAlpha .
Вы можете использовать autoAlpha вместо opacity когда вам нужно убедиться, что элемент не только исчезает из вида, но и пользователи не могут взаимодействовать с ним. Фактически, autoAlpha добавляет visibility: hidden к opacity: 0 .
Свойство ease позволяет вам выбирать замедления для ваших анимаций, которые управляют скоростью изменения в течение всего периода анимации. Это важнейший компонент для естественной, реалистичной и плавной анимации, и GreenSock предлагает Ease Visualizer, чтобы дать вам огромный контроль над той легкостью, которая лучше всего подходит для вашей анимации.
После нескольких попыток я выбрал легкость Back.easeOut для этой конкретной анимации, но вы можете сыграть и придумать что-то другое.
Вот полная демонстрация на CodePen:
Потрясающие анимации с GreenSock
Ошеломляющий эффект состоит в применении одной и той же анимации к группе элементов. Однако анимация затрагивает каждый элемент подряд, то есть один элемент за раз, а не все элементы одновременно.
GSAP TweenMax предлагает staggerTo() , staggerFrom() и staggerFromTo() , которые работают аналогично методам, рассмотренным выше. Отличается только эффект ошеломления, и он требует дополнительного аргумента сразу после объекта vars <> для указания промежутка времени, который вы хотите пройти между каждым из них.
TweenMax.staggerFrom(alice, 0.5 rotation: 0, delay: 1.5, ease: Power4.easeIn >, 0.5);
В приведенном выше фрагменте каждый экземпляр Алисы будет поворачиваться от 0 градусов до значений, которые я установил в своем CSS, с полсекундами между каждым поворотом:
А вот демоверсия с использованием полного кода:
Взять под контроль своих подростков GSAP
У GreenSock есть несколько методов, которые позволят вам полностью контролировать своих подростков.
Те, которые я собираюсь рассмотреть здесь:
-
play() — воспроизводит анимацию из любой точки воспроизведения или из определенного времени:
// plays from the playhead's current location myAnimation.play(); // starts playing from 2 seconds into myAnimation // (all events and callbacks before then don't get fired) myAnimation.play(2); // starts playing from 2 seconds into myAnimation but // doesn't suppress events or callbacks in the initial // part of myAnimation (earlier than 2 seconds) myAnimation.play(2, false);
// pauses myAnimation in all its entirety myAnimation.pause(); // jumps 2 seconds into myAnimation and then pauses myAnimation.pause(2); // jumps 2 seconds into myAnimation then pauses but // doesn't suppress events/callbacks during the // initial phase of the tween (earlier than 2 seconds) myAnimation.pause(2, false);
// moves backwards from wherever the playhead currently is myAnimation.reverse(); // moves backwards from exactly 2 seconds into myAnimation myAnimation.reverse(2); // moves backwards from exactly 2 seconds into myAnimation // but doesn't suppress events/callbacks before then myAnimation.reverse(2, false);
// restarts myAnimation, bypassing any predefined delay myAnimation.restart(); // restarts myAnimation, including any predefined delay, // and doesn't suppress events/callbacks during // the initial move back to time:0 myAnimation.restart(true, false);
// resumes myAnimation from the playhead's current position myAnimation.resume(); // jumps to exactly 2 seconds into myAnimation // and then resumes playback: myAnimation.resume(2); // jumps to exactly 2 seconds into myAnimation // and resumes playback but doesn't suppress // events/callbacks during the initial move: myAnimation.resume(2, false);
Невозможно перечислить все доступные вам методы GSAP TweenLite и TweenMax . Поэтому я призываю вас проверить документы — они очень дружелюбны.
TweenMax yoyo, repeat и repeatDelay
Я хотел бы завершить эту первую статью, посвященную GreenSock, тремя полезными функциями, которые вы можете использовать в анимациях на основе TweenMax:
-
repeat — используйте это, если вы хотите, чтобы ваша анимация играла определенное количество раз или бесконечно. В последнем случае установите repeat в значение -1:
// the tween repeats 3 times on top of the default // time (4 times overall): TweenMax.to(element, 1, < opacity: 0, repeat: 3 >);
// the tween repeats 3 times on top of the default // time (4 times overall) with one a second delay // between each repetition: TweenMax.to(element, 1, < opacity: 0, repeat: 3, repeatDelay: 1 >);
// the tween repeats indefinitely with one second's delay // between each repetition. The element alternates // between being fully opaque and fully transparent: TweenMax.to(element, 1, < opacity: 0, repeat: -1, repeatDelay: 1 >);
Вывод
В этой первой части, посвященной библиотеке GreenSock, я рассказал о том, чем отличается GreenSock, его возможностями, основными компонентами и моделью лицензирования.
Я также познакомил вас с базовым синтаксисом GSAP для анимации элементов DOM с TweenMax с использованием нескольких живых демонстраций.
Однако, хотя вы можете создавать некоторые классные анимации, просто упорядочивая анимацию GSAP, у этого подхода есть пара недостатков:
- Если вы измените duration или delay анимации в анимации, скорее всего, большая часть анимации будет испорчена и нуждается в дальнейшей корректировке.
- Последовательность анимаций состоит из независимых анимаций, поэтому вы не можете приостановить, возобновить, отменить и т. Д. Всю последовательность в целом.
Чтобы предоставить вам дополнительный контроль, GSAP предлагает надежную и гибкую функциональность временной шкалы , о которой я расскажу во второй части, посвященной этой потрясающей библиотеке.
Вы использовали GreenSock в своей веб-анимации? Я хотел бы увидеть, что вы создали с ним.
Если вам интересны анимация и производительность на основе JavaScript, скринкаст JS with Performance: requestAnimationFrame доступен для всех участников SitePoint Premium.
Готовы к большей мощности GreenSock? Затем перейдите к части 2 и узнайте все об использовании временной шкалы GSAP.