THREEJS 在 uni-app 中使用(微信小程序)

THREEJS 在 uni-app 中使用 (微信小程序)


threejs 导入

threejs 主要是用来开发web端的3D世界,源生包无法适配 微信小程序(会报 document.createElementNS 的错),需要使用 github 上经过大佬改写的 threejs 包。

https://github.com/yannliao/threejs-example-for-miniprogram

将源码下载到本地后,找到

1.threejs包: libs -> three.weapp.js2.glb模型加载器: jsm -> loaders -> GLTFLoader.js 3.控制器:jsm -> controls -> OrbitControls.js

将 以上三个文件 复制到自己的 uni-app 项目中 (任意路径下,这里我放在了自己的 utils 下,好像一般都会放到 libs 下)

在这里插入图片描述

// 注:OrbitControls.js 中使用到了 three.weapp.js, 所以,复制的时候请保证 import 的文件路径正确// 以下是 OrbitControls.js 文件import {	EventDispatcher,	MOUSE,	Quaternion,	Spherical,	TOUCH,	Vector2,	Vector3,	global as window} from "./three.weapp.js"; // 要保证能够 import 到 three.weapp.js

threejs 的使用

创建 model_show 页面,导入 threejs

<template>	<view>        <canvas			class='scene' id='scene' canvas-id="scene"  type="webgl"			:style="'width:'+mSceneWidth+'px; height:'+mSceneHeight+'px;'" 			@touchstart="touchStart" 			@touchmove="touchMove" 			@touchend="touchEnd">		</canvas>    </view></template><script>	// 导入 threejs	import * as THREE from '../../utils/three_utils/three.weapp.js'	import { OrbitControls } from '../../utils/three_utils/OrbitControls.js'	import GLTF from '../../utils/three_utils/GLTFLoader.js'        export default {        data() {            return {                mSceneWidth: 0, // 手机屏幕宽度                mSceneHeight: 0, // 手机屏幕高度                worldFocus: null, // 世界焦点(模型放置,相机围绕的中心)                mCanvasId: null,                mSence: null,                mCamera: null,                				renderAnimFrameId: null, // 渲染帧动画id            };        },        // 页面加载时        onLoad(option){            // 获取手机屏幕宽高            this.mSceneWidth = uni.getWindowInfo().windowWidth;            this.mSceneHeight = uni.getWindowInfo().windowHeight;            // 设置世界中心            this.worldFocus = new THREE.Vector3(0, 0, 0);        },        // 页面加载完毕后        onReady(){            // 获取 canvas 元素, 初始化 Three            uni.createSelectorQuery().select('#scene').node().exec((res) => {                // 获取 canvasId                this.mCanvasId = res[0].node._canvasId;                // 注册画布                const mCanvas = THREE.global.registerCanvas(this.mCanvasId, res[0].node);                // 开始初始化                this.init(mCanvas);            });		},        // 页面卸载时        onUnload() {        	// 清理渲染帧动画			THREE.global.canvas && THREE.global.canvas.cancelAnimationFrame(this.renderAnimFrameId);            // 清理canvas对象            THREE.global.unregisterCanvas(this.mCanvasId);            console.log("Unload");        },        methods: {            // 初始化            init(canvas) {                // 创建场景                this.mScene = new THREE.Scene();                this.mScene.background = new THREE.Color("#e6e6e6"); // 场景背景颜色                // 创建摄像机                this.mCamera = new THREE.PerspectiveCamera(75, this.mSceneWidth / this.mSceneHeight, 0.1, 100);                this.mCamera.position.set(0, 0, 20);                this.mCamera.lookAt(this.worldFocus);                // 创建光线                const light1 = new THREE.HemisphereLight(0xffffff, 0x444444); // 半球光(天空颜色,地面颜色,光照强度)                light1.position.set(0, 20, 0);                this.mScene.add(light1);                const light2 = new THREE.DirectionalLight(0xffffff); // 平行光(颜色, 光照强度)                light2.position.set(0, 0, 20);                this.mScene.add(light2);                // 创建渲染器                const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });                renderer.setSize(this.mSceneWidth, this.mSceneHeight);                // 创建控制器                const controls = new OrbitControls(this.mCamera, renderer.domElement);                controls.target.set(this.worldFocus.x, this.worldFocus.y, this.worldFocus.z);// 摄像机围绕旋转的中心                controls.enablePan = false; // 禁止摄像机平移                controls.enableDamping = true; // 设置阻尼,需要在 update 调用                controls.dampingFactor = 0.09;                // 创建 glb 加载器                let GLTFloader = GLTF(THREE)                const loader = new GLTFloader();                // 异步加载模型                // 微信小程序不允许加载本地模型,必须通过 https 获取                loader.load("https://threejs.org/examples/models/gltf/Stork.glb", (gltf) => {                    const model = gltf.scene;                    model.position.set( 0, 0, 0 );// 设置模型位置                    model.scale.set( 0.1, 0.1, 0.1 );// 设置模型大小                    this.mScene.add( model );                    // 模型加载到场景后,开启渲染                    render();                });                // 渲染(闭包)                var render = () => {                	// 帧动画                    this.renderAnimFrameId = canvas.requestAnimationFrame(render);                    //光源跟随相机                    var vector = this.mCamera.position.clone();                    light2.position.set(vector.x,vector.y,vector.z);                    // 控制器                    if (controls.enabled) controls.update();                    // 渲染场景                    renderer.render(this.mScene, this.mCamera);                };            },            // 触摸开始            touchStart(e){                THREE.global.touchEventHandlerFactory('canvas', 'touchstart')(e)            },            // 触摸移动中            touchMove(e){                THREE.global.touchEventHandlerFactory('canvas', 'touchmove')(e)            },            // 触摸结束            touchEnd(e){                THREE.global.touchEventHandlerFactory('canvas', 'touchend')(e)            },        }    }</script><style lang="scss"></style>

最终效果

在这里插入图片描述



来源:春哥技术博客,欢迎分享,转载请注明出处。(欢迎加春哥团队客服微信号:taike668)

本文地址:https://www.cgtblog.com/cgymlt/11172.html
上一篇:【uniapp小程序实战】—— 使用腾讯地      下一篇:uniapp判断h5/微信小程序/app端