介绍
Three.js 是一个 3D JavaScript 库,我们经常使用它加载各种不同格式的模型。示例中的直升机模型出处飞机航空器模型-3D模型库-CG模型网-第1页
demo演示
源码
<template>
<div style="position: relative">
<div style="position:absolute;left:0;top:0;opacity:0.5;height: 35px;width: 100%;z-index: 9999;display: flex;justify-content: flex-start;align-items: center;padding: 0 20px">
<el-button size="mini" @click="play">启动动画</el-button>
<el-button size="mini" @click="stop">关闭动画</el-button>
</div>
<div ref="aircraft"></div>
</div>
</template>
<script lang="ts">
import {defineComponent, ref, onMounted, reactive, toRefs} from 'vue'
import {
Scene,
PerspectiveCamera,
WebGL1Renderer,
AmbientLight,
MeshBasicMaterial,
PlaneBufferGeometry,
Mesh,
GridHelper,
DoubleSide,
AnimationMixer,
Clock,
DirectionalLight,
AxesHelper, AnimationClip
} from 'three'
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader'
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import {AnimationAction} from "three/src/animation/AnimationAction";
export default defineComponent({
components:{
},
setup() {
const loading = ref(true)
const aircraft = ref<HTMLDivElement>()
const action = ref<AnimationAction>();
let state = reactive({
play: function () {
action.value && action.value.play()
},
stop: function () {
action.value && action.value.stop()
}
})
const init = () => {
const scene = new Scene()
/**
* 相机 PerspectiveCamera(视野大小, 视图的长宽比, 近景, 远景)
*/
const camera = new PerspectiveCamera(75, window.innerWidth/window.innerHeight, 1, 1000)
camera.position.set(0, 30, 30)
camera.lookAt(scene.position)
/**
* antialias消除锯齿
*/
const renderer = new WebGL1Renderer({antialias: true})
// 背景颜色
renderer.setClearColor(0xffffff)
// 设置设备像素比
renderer.setPixelRatio(window.devicePixelRatio)
renderer.setSize(window.innerWidth, window.innerHeight)
// 设置窗口的大小 适合在一些小地方显示
// renderer.setViewport(0, 0, 200, 200)
const animationMixer = new AnimationMixer(scene)
const clock = new Clock()
// 添加平面
const planeBufferGeometry = new PlaneBufferGeometry(100, 100)
const plane = new Mesh(planeBufferGeometry, new MeshBasicMaterial({color: 0xFFFFFF, side: DoubleSide}))
plane.rotation.x = Math.PI / 2
scene.add(plane)
// 添加一个网格
scene.add(new GridHelper(100, 100))
let fbxLoader = new FBXLoader()
fbxLoader.load('/model/FBX/AS365/AS365.FBX', function (fbx) {
fbx.scale.set(0.05, 0.05, 0.05)
fbx.position.set(1, 9, 1)
scene.add(fbx);
loading.value = false
const animations: AnimationClip = fbx.animations.find(animationsClip => animationsClip.name === 'Take 001')!
action.value = animationMixer.clipAction(animations)
})
// 添加环境灯光
scene.add(new AmbientLight(0xFFFFFF, 1))
const axesHelper = new AxesHelper( 5 );
scene.add( axesHelper );
// 平行光
const directionalLight = new DirectionalLight(0xffffff);
directionalLight.position.set(-100, 100, 30);
directionalLight.castShadow = true;
scene.add(directionalLight);
const directionalLight3 = new DirectionalLight(0xffffff);
directionalLight3.position.set(100, -100, -10);
directionalLight3.castShadow = true;
scene.add(directionalLight3);
aircraft.value?.appendChild(renderer.domElement)
window.addEventListener('resize', () => onWindowResize())
/**
* 轨道控制器 也就是鼠标转动等操作
*/
let orbitControls = new OrbitControls(camera, renderer.domElement)
// 放大缩小
// orbitControls.enableZoom = false
orbitControls.autoRotateSpeed = 1
renderScene()
function renderScene(){
requestAnimationFrame(renderScene)
animationMixer.update(clock.getDelta())
// const boxs = scene.getObjectByName('box') // 上面如果设置了name 就可以这样子取
renderer.render(scene, camera)
}
const onWindowResize = () => {
renderer.setSize(window.innerWidth, window.innerHeight)
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
}
}
onMounted(() => {
init()
})
return {
...toRefs(state),
aircraft,
loading
}
},
})
</script>
安装好依赖,复制源码,下载好相对应的模型就能使用。这里只是一个简单的demo。纯属学习记录。
我是Etc.End。如果文章对你有所帮助,能否帮我点个免费的赞和收藏😍。
👇 👇 👇 👇 👇 👇 👇 👇 👇 👇 👇 👇