Jump to content
Search Community

Are there any recommendations for organizing animation code?

Poylar test
Moderator Tag

Recommended Posts

Hi.

I think I write very confusing and not clear. Maybe you can give me some pointers that should be corrected.
For example, I have a preloader animation, I launch it and in the last seconds of its completion I want to launch the first screen animation, but if the preloader does not exist, then I immediately want to start the first screen animation with slightly different parameters. (No jerking fromTo)
I will be glad if you point out at least one mistake to me so that I can start writing better such code, because now it looks like spaghetti

 

import { gsap } from 'gsap'
import CustomEase from 'gsap/CustomEase'
import SplitText from 'gsap/SplitText'
import ScrollTrigger from 'gsap/ScrollTrigger'
import { breakpoints } from './MatchMedia'
gsap.registerPlugin(SplitText, ScrollTrigger, CustomEase)
const globalGap = getComputedStyle(document.body).getPropertyValue('--gap')
console.log(globalGap)
const textSplit = new SplitText('.hero__title', {
  type: 'chars, lines',
  charsClass: 'oh',
  linesClass: 'oh',
})
const { chars } = textSplit
function instaAnim() {
  const tl = gsap.timeline({
    scrollTrigger: {
      trigger: '.hero__content',
      start: 'top top',
      end: '70%',
      scrub: true,
    },
  })
  tl.to('.hero__content', {
    ease: 'Power.2',
    backgroundPositionY: '100%',
  })
}
function onLoadAnim() {
  const preloader = document.querySelector('.preloader')
  const preloaderLogo = document.querySelector('.preloader .logo__src')
  const heroContent = document.querySelector('.hero__content')
  const tl = gsap.timeline()
  console.log(preloader)
  if (!preloader) {
    tl.then(() => {
      animAfterLoaded(true)
    })
  }

  setTimeout(() => {
    if (preloader) {
      tl.to(preloader, {
        yPercent: -100,
        duration: 1,
        ease: CustomEase.create('cubic', '0.96, 0.02, 0.34, 0.99'),
      })
      tl.to(
        preloaderLogo,
        {
          duration: 1,
          yPercent: -100,
        },
        '<'
      )
      tl.fromTo(
        heroContent,
        {
          backgroundSize: '140%',
          backgroundPosition: 'top center',
        },
        {
          duration: 1,
          backgroundSize: '120%',
        },
        '='
      )
      tl.fromTo(
        chars,
        {
          y: 100,
        },
        {
          stagger: 0.01,
          y: 0,
        }
      )
      tl.then(() => {
        animAfterLoaded(isPreloader)
      })
    }
  }, 500)
}

const sidebarHeight = document
  .querySelector('.project-content__sidebar')
  ?.getBoundingClientRect().height
function servicesSticky() {
  const contentHeight = document.querySelector(
    '.project-content__gallery'
  )?.offsetHeight
  const tl = gsap.timeline({
    scrollTrigger: {
      trigger: '.project-content__sidebar ',
      start: '5% 5%',
      pin: true,
      end: `+=${contentHeight - sidebarHeight}`,
      scrub: true,
    },
  })
}

function chronology() {
  const tl = gsap.timeline({
    scrollTrigger: {
      trigger: '.about-slider-wrapper',
      start: 'top center',
      end: 'center center',
      markers: true,
    },
  })
  tl.to('.about-slider-line__active-line', {
    ease: CustomEase.create('cubic', '0.96, 0.02, 0.34, 0.99'),
    width:
      document.querySelector('.about-slider__slide')?.offsetWidth -
      parseInt(globalGap),
  })
}

function animAfterLoaded(isPreloader) {
  if (isPreloader) {
    const heroContent = document.querySelector('.hero__content')
    const tl = gsap.timeline()
    tl.fromTo('.page-heading__title', {})
    tl.fromTo(
      heroContent,
      {
        backgroundSize: '140%',
        backgroundPosition: 'top center',
      },
      {
        duration: 1,
        backgroundSize: '120%',
      },
      '='
    )
    tl.fromTo(
      chars,
      {
        y: 100,
      },
      {
        stagger: 0.01,
        y: 0,
      }
    )
  }
}

function textAnimation() {
  const titles = document.querySelectorAll('h2, .section-heading__desc')
  titles.forEach((title) => {
    const textSplit = new SplitText(title, {
      type: 'chars, lines',
      charsClass: 'oh',
      linesClass: 'oh',
    })
    const tl1 = gsap
      .timeline({
        scrollTrigger: {
          trigger: title,
          start: 'top 85%',
        },
      })
      .fromTo(
        textSplit.chars,
        {
          y: 200,
        },
        {
          duration: 0.8,
          y: 0,

          stagger: 0.01,
        }
      )
  })
}

window.addEventListener('load', () => {
  onLoadAnim()
  instaAnim()

  chronology()
  textAnimation()
  if (window.matchMedia(breakpoints.isDesktop).matches) {
    servicesSticky()
  }
})

 

Link to comment
Share on other sites

Writhing code clean a concise is an art on it self, this is not really something "do these things" and it will be fixed. It is something you'll learn over time or at least if you comeback to this code in a year or so you'll see what you would do differently and that is how you learn. 

 

What I could give you is 'where are the comments?' This Is how I like to structure my code if I know I will need to read some time later and still make sense of it.

 

See the Pen GREebPK by mvaneijgen (@mvaneijgen) on CodePen

 

 

Hope it helps and happy tweening! 

  • Like 2
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...