1. 自动轮播动画

1.1. 迭代器循环任务

const task = [
  {
    type: 'target',
    x: -500,
    y: 0,
    z: 500,
    time: 1000
  },
  {
    type: 'scale',
    x: -500,
    y: 0,
    z: 500,
    time: 2000
  },
  {
    type: 'target',
    x: -500,
    y: 0,
    z: 500,
    time: 3000
  },
  {
    type: 'scale',
    x: -500,
    y: 0,
    z: 500,
    time: 4000
  }
]

function* generatorEach(arr) {
  for (let [index, value] of arr.entries()) {
    yield setTimeout(() => {
      console.log([index, value]);
      const { done } = each.next();
      if (done) {
        each = generatorEach(task);
        each.next();
      }
    }, value.time)
  }
}

let each = generatorEach(task);
each.next();

1.2. 实际案例

import gsap from 'gsap'
import { camera } from './three'
import { controls } from './controls'
import { task } from '../config/task'
import { selectedValue } from './webWorker/index'

const task = [
  {
    type: 'gsap',
    target: controls.target,
    obj: {
      x: -600,
      y: 0,
      z: 500
    },
    duration: 4
  },
  {
    type: 'gsap',
    target: camera,
    obj: {
      zoom: 20
    },
    duration: 3
  },
  {
    type: 'gsap',
    target: camera,
    obj: {
      zoom: 1
    },
    duration: 4
  },
  {
    type: 'gsap',
    target: controls.target,
    obj: {
      x: 50,
      y: 0,
      z: 0
    },
    duration: 4
  },
  {
    type: 'gsap',
    target: camera,
    obj: {
      zoom: 20
    },
    duration: 10
  },
  {
    type: 'rotate',
    duration: 30
  },
  {
    type: 'gsap',
    target: camera,
    obj: {
      zoom: 1
    },
    duration: 10
  },
  {
    type: 'gsap',
    target: controls.target,
    obj: {
      x: 600,
      y: 0,
      z: 500
    },
    duration: 4
  },
  {
    type: 'gsap',
    target: camera,
    obj: {
      zoom: 20
    },
    duration: 10
  },
  {
    type: 'rotate',
    duration: 30
  },
  {
    type: 'gsap',
    target: camera,
    obj: {
      zoom: 1
    },
    duration: 10
  },
  {
    type: 'gsap',
    target: controls.target,
    obj: {
      x: 600,
      y: 0,
      z: -500
    },
    duration: 4
  },
  {
    type: 'gsap',
    target: camera,
    obj: {
      zoom: 20
    },
    duration: 10
  },
  {
    type: 'rotate',
    duration: 30
  },
  {
    type: 'gsap',
    target: camera,
    obj: {
      zoom: 1
    },
    duration: 10
  },
  {
    type: 'gsap',
    target: controls.target,
    obj: {
      x: -600,
      y: 0,
      z: -500
    },
    duration: 4
  },
  {
    type: 'gsap',
    target: camera,
    obj: {
      zoom: 20
    },
    duration: 10
  },
  {
    type: 'rotate',
    duration: 30
  },
  {
    type: 'gsap',
    target: camera,
    obj: {
      zoom: 1
    },
    duration: 10
  }
]

const gsapPromise = (property: any, obj: any, duration: number) => {
  return new Promise((resolve, reject) => {
    gsap.to(property, {
      ...obj,
      duration,
      repeat: 0,
      yoyo: true,
      onComplete: () => {
        resolve(1)
      }
    })
  })
}

const rotatePromise = (duration: number) => {
  return new Promise((resolve, reject) => {
    controls.autoRotate = true
    const timer = setTimeout(() => {
      controls.autoRotate = false
      clearTimeout(timer)
      resolve(1)
    }, duration * 1000)
  })
}

const switchFloorPromise = (target: string) => {
  return new Promise((resolve, reject) => {
    selectedValue.value = target
    const timer = setTimeout(() => {
      clearTimeout(timer)
      resolve(1)
    }, 2000)
  })
}

let taskGenerator: any = null

function* generatorEach(arr: any[]) {
  for (const [index, value] of arr.entries()) {
    yield (async () => {
      const { type, target, obj, duration } = value
      if (type === 'switch') {
        await switchFloorPromise(target)
      } else if (type === 'gsap') {
        await gsapPromise(target, obj, duration)
      } else if (type === 'rotate') {
        await rotatePromise(duration)
      }
      const { done } = taskGenerator.next()
      if (done) {
        taskGenerator = generatorEach(task)
        taskGenerator.next()
      }
    })()
  }
}

const animation = async () => {
  gsap.globalTimeline.play()
  controls.autoRotate = false
  taskGenerator = generatorEach(task)
  taskGenerator.next()
}

const rest = () => {
  controls.autoRotate = false
  gsap.globalTimeline.pause()
}

export { animation, rest }
Copyright © tomgou 2022 all right reserved,powered by Gitbook该文章修订时间: 2022-11-14 17:52:33

results matching ""

    No results matching ""