前端动画框架GSAP框架随笔

672 阅读1分钟

gsap是目前非常流行的前端动画框架,可以非常轻松构造出复杂的动画效果,这里仅对我实际使用中的一些例子进行总结

官网

示例

文章种所使用代码的在线示例

基础用法

// 声明一个滚动控制器
let ctrl = new ScrollMagic.Controller({
  globalSceneOptions:{
    offset:-200
  }
})


// MORE+ 
Array.from(document.querySelectorAll(".more")).forEach((el,ix)=>{
  let moreLink = new TimelineMax();
  moreLink.from(el,{yPercent:300,opacity:0}) // 在timelineMax中 from是指从某种样式过渡到现在的样式
  new ScrollMagic.Scene({
    triggerElement:document.querySelectorAll("#app div.home")[0].children[ix+3],
    triggerHook:0.35,
    offset:200
  }).setTween(moreLink).addTo(ctrl)
})

// 同时控制两个元素的过渡动画

// 师资简介
init_swiper_teachear(){
  const vue = this
  class SwiperTeacher{
    now = 0
    max = vue.swiperTeacher.length-1
    imgDom = null;
    infosDom = null;
    numListDom = null
    constructor () {
      vue.$nextTick(()=>{this.getDom()})
    }
    next(){
      return new Promise(async (resolve) => {
        if(this.now === this.max) vue.goNext('ADVANTAGE');

        const imgEnd = gsap.to(this.imgDom[this.imgDom.length - 1 -this.now],{xPercent:-100,ease:'power2.out'})
        const infosEnd = gsap.to(this.infosDom[0],{xPercent:(this.now+1) * 100,ease:'power2.out'})

        await imgEnd
        await infosEnd
        this.now+=1
        resolve()
      })
    }
    pre(){
      return new Promise(async (resolve) => {
        if(this.now===0){resolve();return}
        this.now-=1
        const imgEnd = gsap.to(this.imgDom[this.imgDom.length - 1 - this.now],{xPercent:0,ease:'power2.out'})
        const infosEnd = gsap.to(this.infosDom[0],{xPercent:(this.now)*100,ease:'power2.out'})

        await imgEnd
        await infosEnd
        resolve()
      })
    }
    async go(ix){
      const needGo = ix-this.now
      if(needGo===0) return;
      if(needGo<0){
        for(let i = 0;i<-needGo;i++){await this.pre()}
      }else{
        for(let i = 0;i<needGo;i++){await this.next()}
      }
    }
    getDom(){
      this.imgDom = document.querySelectorAll('.introductionOfTeachers .sliderContent .imgContent .img')
      this.infosDom = document.querySelectorAll('.introductionOfTeachers .sliderContent .infoContent')
      this.numListDom = document.querySelectorAll('.introductionOfTeachers .point-teacher .numList')
    }
  }

  let control =  new SwiperTeacher()
  control = new Proxy(control,{
    set (target, p, value) {
      if(p==='now'){
        control.numListDom.forEach((el,ix)=>{
          el.classList.remove('active')
          if(ix===value){el.classList.add('active')}
        })
      }
      target[p] = value
      return true
    }
  })
  this.$refs['sliderRight-teacher'].addEventListener('click',async ()=>{await control.next()})
  this.$refs['sliderLeft-teacher'].addEventListener('click',async ()=>{await control.pre()})
  this.$nextTick(()=>{this.$refs['numList-teacher'].forEach((el,ix)=>{el.addEventListener('click',async ()=>{await control.go(ix)})})})
  let randomTeacher = new TimelineMax()
  randomTeacher.from('div.introductionOfTeachers .sliderContent',{
    yPercent:100,
    opacity:0,
    onStart(){
      vue.swiperTeacher = vue.randomArr(vue.raw_teacher_data,5)
      control.now = 0
    }
  })
  randomTeacher.from('div.introductionOfTeachers .point-teacher',{
    yPercent:100,
    opacity:0
  })
  new ScrollMagic.Scene({triggerElement:'div.introductionOfTeachers',triggerHook:0.35}).setTween(randomTeacher).addTo(ctrl)
}

// 对某个按钮的过渡动画经行处理 通过添加一层元素来经行动画 高阶函数来处理抖动

// 选择院校和新闻大按钮
init_design_button(){
  Array.from(document.querySelectorAll('div.selectInstitution .listContent .designButton,div.news .listContent .designButton')).forEach((el,ix)=>{
    class onceFunction{
      constructor (bg) {
        this.bg = bg
        this.end = false
      }
      main(){
        this.bg.style.backgroundColor = '#e06730'
        this.bg.style.visibility = 'unset'
        gsap.from(this.bg,{scaleX:0}).then(()=>{this.end = true})
      }
      move(){
        this.main()
        this.move = ()=>{}
      }
      leave(){
        if(this.end){
          this.bg.style.visibility = 'hidden'
          this.move =()=>{
            this.main()
            this.move = ()=>{}
          }
        }
      }
    }
    const o = new onceFunction(el.childNodes[0].childNodes[0])
    el.addEventListener('mousemove', ()=>{o.move()})
    el.addEventListener('mouseleave',()=>{o.leave()})
    if(ix===0||ix===3){
      o.move()
    }
  })
}