Skip to content

补间动画Tween应用

代码

js
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js';
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
// 导入 tween
import  * as TWEEN from 'three/examples/jsm/libs/tween.module.js';

const scene = new THREE.Scene();

const camera = new THREE.PerspectiveCamera(
  45,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
)

const renderer = new THREE.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)

camera.position.z = 15;
camera.position.y = 2;
camera.position.x = 2;
camera.lookAt(0, 0, 0)

const axesHelper = new THREE.AxesHelper(5);
scene.add(axesHelper);

const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;

function animate() {
  requestAnimationFrame(animate)
  controls.update()
  renderer.render(scene, camera)

  // 更新 tween
  TWEEN.update()
}

animate()

window.addEventListener('resize', () => {
  renderer.setSize(window.innerWidth, innerHeight)
  camera.aspect = window.innerWidth / window.innerHeight
  camera.updateProjectionMatrix()
})

let eventObj = {
  Fullscreen: function () {
    document.body.requestFullscreen()
  },
  ExitFullscreen: function () {
    document.exitFullscreen()
  }
}

const gui = new GUI()
gui.add(eventObj, 'Fullscreen').name('全屏')
gui.add(eventObj, 'ExitFullscreen').name('退出全屏')

// 创建球
const sphere1 = new THREE.Mesh(
  new THREE.SphereGeometry(1, 32, 32),
  new THREE.MeshBasicMaterial({ color: 0x00ff00 })
)
sphere1.position.x = -4
scene.add(sphere1)

// 创建补间动画
const tween = new TWEEN.Tween(sphere1.position)
tween.to({ x: 4 }, 2000).onUpdate(() => {
  // console.log(sphere1.position.x)
})

// tween.onUpdate(() => {
//   console.log(sphere1.position.x)
// })

// 循环往复
// tween.yoyo(true)

// 延时1秒运行
tween.delay(1000)

// 设置缓动函数
tween.easing(TWEEN.Easing.Quadratic.InOut)

// 循环无数次
// tween.repeat(Infinity)
// 循环2次
tween.repeat(2) 

const tween2 = new TWEEN.Tween(sphere1.position)
tween2.to({ y: 4 }, 2000)

// 动画间的链接 动画1 链接 动画2
tween.chain(tween2)
// 动画间的链接 动画2 链接 动画1
tween2.chain(tween)

tween2.start()

// 启动补间动画
tween.start()

tween.onStart(() => {
  console.log('动画开始')
})

tween.onComplete(() => {

  console.log('动画结束')
})

tween.onStop(() => {
  console.log('动画停止')
})

tween.onUpdate(() => {
  console.log('动画更新')
})

let params = {
  stop: function () {
    tween.stop()
  }
}
gui.add(params, 'stop').name('停止动画')

Released under the MIT License.