Новый уровень заряженных анимаций с помощью GreenSock Animation Platform

Всем Салют!

Меня зовут Алексей

Я веселый Front-end разработчик
Я создаю сайты, люблю

"заряженные" анимации

творю чудеса в

преподаю в

Зачем?

  1. Анимация отлично может передать смысл
  2. Можете направлять своих пользователей
  3. В противном случае мы не используем полный потенциал веба
  4. Запоминаемость вашего сайта
  5. Это весело! ( не забываем про веселье :)

Как?

Что такое GreenSock?

GSAP, представляет собой JavaScript фреймворк для анимации элементов DOM (и не только...)

Воспринимайте GSAP как швейцарский армейский нож JavaScript анимаций ... только круче. 

За что я       GSAP?

Почему я        GSAP

  • Кроссбраузерность!
  • Производительность
  • Простой синтаксис - помните слайд со сравнением?
  • Лучшее решение для анимации SVG
  • Очень широкий набор возможностей
  • Никаких зависимостей (другие библиотеки и т. п.)

Кроссбраузерность

Детальнее на CSS-Tricks.

Chrome

IE & Edge

Safari (zoomed)

Firefox

Решает другие проблемы c Transform-Origin

IT'S A

MAGIC

Производительность

Синтаксис

const tlReveal = gsap.timeline({
    defaults: {duration: 0.6, ease: 'power2.out'}
  });

tlReveal
  .from(section.subtitle, {duration: 0.3, opacity: 0, y: 20})
  .from(section.shape.children(), {
    duration: 0.5,
      opacity: 0,
      rotation: -10,
      stagger: 0.1,
      transformOrigin: "50% 50%"
  }, '-=0.3')

Решение для анимации SVG

Набор возможностей

Меняем любое CSS свойство(а) и не только

gsap.to('#logo', {duration: 3, left:"440px", ease:"bounce.easeOut"});
gsap.from(logo, {opacity:0, left:"300px"});
gsap.from([logo, '.nav'], {opacity:1, x:300});

Но мы же здесь говорим про новый уровень "заряженных" анимации?

Что нового и восхитительного в #GSAP 3

1. Меньше размер библиотеки!

Ядро было полностью перестроено с нуля под современные ES модули.

2. Унифицированный синтаксис

//OLD - duration was 2nd parameter
TweenMax.to(".class", 1, {x:100});
TweenLite.to(".class", 1, {x:100});

//OLD
var tl = new TimelineMax({repeat:2, repeatDelay:1});
tl.to(".class", 2, {x:100});
//simple tween like the old TweenMax.to(...)
gsap.to(".class", {duration:1, x:100});

//create a timeline and add a tween
var tl = gsap.timeline({repeat:2, repeatDelay:1});
tl.to(".class", {duration:2, x:100});

БЫЛО

СТАЛО

60 кб  VS  112 кб

3. Унифицированный синтаксис stagger

//simple stagger
TweenMax.staggerTo(".class", 1, {
  x: "+=100",
}, 0.5);

БЫЛО

//simple stagger
gsap.to(".class", {
  x: "+=100",
  duration: 1,
  stagger: 0.5 //space each element's animation out by 0.5 seconds
});

СТАЛО

4. Defaults

//old way, without timeline defaults
var tl = new TimelineMax();
  tl.to(obj1, 2, {ease: Power2.easeInOut, rotation: -180})
    .to(obj2, 2, {ease: Power2.easeInOut, rotation: -360})
    .to(obj3, 2, {ease: Power2.easeInOut, rotation: -180});

//new way, with timeline defaults
var tl = gsap.timeline({defaults:{ease: "power2.inOut", duration: 2}});
  tl.to(obj1, {rotation: -180}) //child tweens will inherit the duration and from the parent timeline!
    .to(obj2, {rotation: -360})
    .to(obj1, {rotation: -180});

5. Новый плагин MotionPathPlugin

5. Новый плагин ScrollTrigger #

const tlReveal = gsap.timeline({
  defaults: {duration: 2, ease: 'power3.out'},
  scrollTrigger: {
    trigger: section,
    pin: true,   // pin the trigger element while active
    markers: true,
    start: `top+=10px 80%`,
    toggleClass: "active"
  },
});

tlReveal.from(items, {
    y: 34,
    opacity: 0,
    stagger: 0.04,
  });

Крутые штуки для сложных анимаций

  1. Stagger

  2. Движение вдоль кривой

  3. Сложные SVG анимации

  4. Анимации по скролу

  5. WebGL

  6. Draw SVG - отрисовка фигур или их контура

  7. MorphSVG - изменение формы

Здесь нам помогут:

gsap.timeline()

repeat •  yoyo •  stagger

gsap.to(".box", {
  duration: 1,
  scale: 0.1,
  y: 40,
  ease: "power1.inOut",
  stagger: {
    grid: [7,15],
    from: "random",
    axis: "x",
    amount: 1.5
  }
});

Stagger

gsap.to(".box", {
  duration: 1,
  scale: 0.1,
  y: 40,
  ease: "power1.inOut",
  stagger: 0.5
});

Stagger

Реальные истории

stagger

timeline и stagger

const tlRevealAwards = gsap.timeline(revealOptDef);

tlRevealAwards
  .from(awards.line, {scaleX: 0, transformOrigin: "0% 50%"})
  .addLabel('stars')

awards.stars.each((i, stars) => {
  tlRevealAwards
  .from($(stars).children(), {
    duration: 0.6, yPercent: 100, stagger: 0.08
  }, 'stars-=0.3')
})
tlRevealAwards
  .from(awards.awards, {duration: 0.8, yPercent: 100, stagger: 0.08}, '-=0.6')
  .addLabel('awards')
  .from([awards.subtitle, ...awards.text], {
    duration: 0.8, y: 20, opacity: 0, stagger: 0.05}, 
  'awards-=0.8')
  .from(awards.shape, {duration: 0.8, opacity: 0, y: 40}, 'awards-=0.8')
;

Пример - движение по кривой

Пример - движение по кривой

let distanse = 0.016;
let progressOffset = (1 - length * distanse) / 2;

navItemsLevel1.forEach((el) => {
  let tl = new gsap.timeline({paused: true});

  tl
    .to(el, {
    duration: 10,
    ease: "power1.inOut",
    motionPath: {
      path: navPath,
      align: navPath,
      alignOrigin: [0, 0.5],
      start: 0.81,
      end: 0.21
    }
  });
  progressOffset += distanse;

  tl.progress(progressOffset);
  tl.pause();
}

Пример - движение по кривой

let distanse = 0.016;
let offset = distanse;

navItems.forEach((el) => {
  let tl = el.dataset.tl;
  
  let itemOffset = tl.progress() + offset;
  
  gsap.to(tl, {duration: 0.2, progress: itemOffset });
}

Пример - движение по кривой

анимировать WebGL

let scrollTlHero = gsap.timeline({});
let scrollTlBlaster = gsap.timeline({defaults: {duration: 1}});

scrollTlHero
  .to(tlRotate, {duration: 1, progress: 1})
  .to(blaster.circle, {duration: 1, rotation: 180}, 0)
;
scrollTlBlaster
  .addLabel('scaleUp')
  .to(blaster.circle, {duration: 0.2, autoAlpha: 0}, 'scaleUp')
  .to(tlToViewer, {duration: 1.5, progress: 1}, 'scaleUp')
  .to(blasterModel, {duration: 0.7, fade: 0.8}, 'scaleUp')
  .to(blaster.wrap, {duration: 0.7, opacity: 0.3}, 'scaleUp')

scrollTlBlaster
  .addLabel('scaleDown')
  .to(tlPhoteToViewer, {duration: 1.5, progress: 1}, 'scaleDown')
  .to(blasterModel, {duration: 1, fade: 1}, 'scaleDown')
  .to(blaster.wrap, {duration: 1, opacity: 1}, 'scaleDown')
  .to(blaster.wrap, {duration: 1.5, xPercent: 18.5}, 'scaleDown')
  .to(blasterModel.scene.scale, {duration: 1, 'x': 1.1, 'y': 1.1, 'z': 1.1}, 'scaleDown+=0.2')
  .to(blasterModel.scene.position, {duration: 0.5, 'y': 6}, 'scaleDown')

on mouse move

listCol.on("mousemove", function(e	){
  let t = listCol[0].getBoundingClientRect();

  let k = (list.height() + t.top) / $(window).height();
  let mousePos = (e.pageY - t.top) * k;

  TweenMax.to(list, .6, {
    y: -mousePos, ease: Power2.easeOut
  });
  TweenMax.to(flyText, .6, {
    y: mousePos/1.5, ease: Power2.easeOut
  })

});

БОНУС

Возможность анимировать псевдо элементы

const rule = CSSRulePlugin.getRule(".title:after");

let tl = gsap.timeline();

tl.to(rule, {duration: 1.8, cssRule: {scaleY: 0}})

Отличный набор Callbacks

gsap.to(loadingPercentage, {  delay:0.5, onUpdate: countPercent});

function countPercent() {
  let newPercent = (tween.progress()*100).toFixed();

  $(loadingPercentage).text(newPercent);
}

Можем анимировать любое свойство любого объекта

Flip Plugin

И конечно создавать милоту :)

Это GreenSock

Используйте GSAP

Заряжайте анимации  с помощью GSAP

Спасибо за внимание!

=

Made with Slides.com