注意: 需要引入three.js,只支持Gbl文件的模型
<!-- #ifdef APP-PLUS || H5 -->
????<view class="threeViewBox">
????????<view id="threeView" :prop="isGlbUrl" :change:prop="three.updateIsGlbUrl"></view>
????</view>
<!-- #endif -->
使用到renderjs,因為app不支持docment的操作
<script module="three" lang="renderjs">
????import * as THREE from "three";// OrbitControls 是對 Threejs 的三維場景進行縮放、平移、旋轉(zhuǎn)操作
????import {OrbitControls} from "three/examples/jsm/controls/OrbitControls.js";// 導(dǎo)入 glb 格式模型,若要導(dǎo)入其他格式模型,可嘗試在 loaders 目錄下加載其他文件
????import {GLTFLoader} from "three/examples/jsm/loaders/GLTFLoader.js";
????var renderer;
????var scene;
????var camera;
????var controls;
????var mixer = null;
????var clock = null;
????export default {
????????name: "ThreeContainer",
????????????data() {
????????????????????return {
????????????????????????????glbUrl: '',
????????????????????????schedule: false,}
????????????},
????????mounted() {
????????????????setTimeout(() => {
????????????????????this.updateIsGlbUrl()
? ? ? ? ? ? ? ? ?}, 0);
????????????????this.initThree(); //加載場景this.leadModel(); //導(dǎo)入模型
????????????????this.createControls(); //控制模型的縮放、平移、旋轉(zhuǎn)操作
????????},
????methods: {
????????updateIsGlbUrl(newValue, oldValue) {
????????????if (newValue) {
????????????????this.glbUrl = newValue
????????????}
????????},
????????createControls() {
??????????? controls = new OrbitControls(camera, renderer.domElement)
????????},
// 導(dǎo)入模型
leadModel() {
let self = this // let {original} = JSON.parse(localStorage.getItem('collectionDetailData'))
// 導(dǎo)入本地或者服務(wù)器上的模型都可以
loader.load(this.glbUrl, function(gltf) {
????if (gltf.animations.length > 0) {
????????mixer = new THREE.AnimationMixer(gltf.scene);
????????let AnimationAction = mixer.clipAction(gltf.animations[0]);
????????scene.add(gltf.scene);
????????AnimationAction.play();
????}
????gltf.scene.traverse(function(child) {
????????if (child.isMesh) {
????????????child.material.emissive = child.material.color; child.material.emissiveMap = child.material.map;
????}
});
????scene.add(gltf.scene);
},
function(params) {
????this.schedule = Math.floor(params.loaded / params.total * 100);
});
},
initThree() {
????const element = document.getElementById('threeView') /* 創(chuàng)建場景對象Scene */
????scene = new THREE.Scene(); // 環(huán)境光0x404040
????var ambient = new THREE.AmbientLight(0xffffff, -0.4);
????scene.add(ambient); // // 平行光# 35434d
????const directionalLight = new THREE.DirectionalLight(0xffffff, 0.1);
????scene.add(directionalLight); //點光
????const light = new THREE.PointLight(0xffffff, 0.1);
????light.position.set(50, 100, 0);
????scene.add(light); //相機設(shè)置
????// var width = element.clientWidth; // 窗口寬度
????// var height = element.clientHeight;
????// 高度 var width = 414; // 窗口寬度
????var height = 370; // 高度
????var k = width / height; // 窗口寬高比
????var s = 1000; // 三維場景顯示范圍控制系數(shù),系數(shù)越大,顯示的范圍越大 // 創(chuàng)建相機對象(正射投影)
????camera = new THREE.PerspectiveCamera(45, k, 1, 1000);
????camera.position.set(0, 0, 40); //設(shè)置相機的擺放位置
????camera.lookAt(new THREE.Vector3(0, 0, 0)); // 控制相機的焦點(鏡頭)位置,決定相機的朝向(取值為3維坐標(biāo)對象-????THREE.Vector3(x,y,z))
????/* 創(chuàng)建渲染器對象 */
????renderer = new THREE.WebGLRenderer({
????antialias: true,
???????alpha: true, //設(shè)置透明,為true時,背景顏色需要注釋掉 precision: "highp",
????});
????renderer.outputEncoding = THREE.sRGBEncoding; renderer.setSize(width, height); // 設(shè)置渲染區(qū)域尺? ?
????// renderer.setClearColor("#F2F2F4", 1); // 設(shè)置背景顏色
? ? ? element.appendChild(renderer.domElement); // body元素中插入canvas對象 // 執(zhí)行渲染操作,指定場景,相機作為參數(shù)
????renderer.render(scene, camera);
????clock = new THREE.Clock(); this.render(); },
????// 動畫
????render() {
????????let that = this;
????????if (mixer !== null) {
????????????mixer.update(clock.getDelta());
????????}
????????requestAnimationFrame(function() {
????????that.render();
????????});
????????renderer.render(scene, camera); //執(zhí)行渲染操作 }, } }
</script>