前言
公司的一个3D编辑器项目,要在three模型上加一些补间动画。做了一些调研,最终选择了gsap,其丰富的缓动函数,强大的动画效果和兼容性,更适合公司的需求。
查看gsap文档,发现所有的例子都是针对dom元素的,按照其方式直接绑定three模型,动画并不生效,也没有找到相关的文章。开发过程中多次尝试,发现需要将动画绑定在模型上的属性上,还有一些特殊的设置,在此简单记录一下。
功能实现
前期准备
import * as THREE from 'three'
// 创建场景、相机和渲染器
const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000)
const renderer = new THREE.WebGLRenderer({
antialias: true
})
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
// 创建立方体
const geometry = new THREE.BoxGeometry(1,1,1)
const material = new THREE.MeshBasicMaterial({color: 0x00ff00})
const cube = new THREE.Mesh(geometry, material)
cube.position.set(0,0,0)
scene.add(cube)
// 设置相机
camera.position.set(4,3,6);
camera.lookAt( 0, 0, 0 );
// 渲染场景
const animate = () => {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate()
此时可以看到效果如下
立方体已经显示出来,但是重叠的部分会将边角模糊掉,看起来更像是一个平面的不规则多边形,所以我们补充下细节,使模型更立体一些
细节补充
- 添加辅助线,显示X、Y、Z轴,可以明显的感受3D空间
- 添加轨道控制器,可以转动相机进行轨道运动,查看立方体的各个角度
- 修改立方体材质以及添加环境光和平行光,使立方体看起来棱角分明 更直观
修改立方体材质
修改立方体的材质为标准网格材质,基础网格材质不受光照影响,不会形成阴影面
// const material = new THREE.MeshBasicMaterial({color: 0x00ff00})
const material = new THREE.MeshStandardMaterial({color: 0x00ff00})
其他细节添加
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls'
// 创建轴辅助线
const xAxisHelper = new THREE.AxesHelper(10);
scene.add(xAxisHelper);
// 添加轨道控制器
const controls = new OrbitControls(camera, renderer.domElement)
// 设置带阻尼
controls.enableDamping = true
// 设置带阻尼的系数
controls.dampingFactor = 0.1 //数字越小,滑动后的惯性时间越长
// 添加环境光
const light = new THREE.AmbientLight( 0x404040 );
scene.add( light );
// 添加平行光
const directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
directionalLight.position.set(5,10,8)
scene.add( directionalLight );
看下效果:
只添加平行光 这个角度的效果是一样的。但是我们转动相机会发现,平行光没有照到的地方,物体不会发光
至此,前期准备全部完成。接下来,就可以进行动画效果设置了
动画实现
位置移动
import {gsap} from 'gsap'
gsap.to(cube.position, {duration: 2, x: 1})
效果:
沿轴旋转
gsap.to(cube.rotation, {duration: 2, z: 90*(Math.PI / 180)})
效果:
缩放
gsap.to(cube.scale, {duration: 2, x: 2, y:2, z:2})
效果:
以上动画,设置到对应的属性上即可生效。颜色和透明度需要特殊处理下
颜色变化
gsap.to(cube.material, {
duration: 2,
keyframes: {
"0%": {color: 'rgba(0,255,0)'},
"100%": {color: 'rgba(255,255,0)'},
},
onUpdate: () => {
cube.material.color = new THREE.Color(cube.material.color)
}
})
效果:
透明度过渡
three模型需要设置transparent属性值为true 才可以进行透明度设置
gsap.to(cube.material, {
duration: 2,
opacity: 0.2,
transparent: true,
onUpdate: () => {
cube.material.needsUpdate = true;
}
})
效果:
gsap动画的简单实现基本完成,项目中还涉及到缓动函数的添加、多个动画的叠加、以及补间动画的控制等等,有机会再记录