前言
本专栏是基于uniapp实现手机端各种小功能的程序,并且基于各种通讯协议如http、websocekt等,实现手机端作为客户端(或者是手持机、PDA等),与服务端进行数据通讯的实例开发。
发文平台
稀土掘金
环境配置
- 系统:windows
- 平台:visual studio code、HBuilderX(uniapp开发)
- 语言:javascript、html、vue
- 库:three.js
概述
本文研究一下在uniapp中,如何添加threejs来显示三维图形,尤其是在app端实现3D图形显示。 参考链接:
1、threejs官网: threejs.org/
2、uniapp官网: uniapp.dcloud.net.cn/
1、uniapp中添加threejs的方案
uniapp提供了一种功能,叫做renderjs,renderjs的主要功能如下:
- 大幅降低逻辑层和视图层的通讯损耗,提供高性能视图交互能力
- 在视图层操作dom,运行 for web 的 js库
更具体的介绍请参考uniapp官网介绍:
uniapp.dcloud.net.cn/tutorial/re…
本文会基于uniapp提供的renderjs功能,来实现threejs库的添加与使用。
首先,我们使用HBuilderX创建一个uniapp项目,打开默认的index页面,删除默认的代码,首先我们添加UI代码:
<template>
<view class="container">
<view class="head-line">
<text>行星演示</text>
</view>
<view class="three-view">
<!-- 此view处渲染3D图形 -->
</view>
</view>
</template>
如上图,非常简单,我们创建一个view元素,用于容纳threejs来渲染。
接下来就是要添加threejs代码,但是我们不能在默认的script中直接编写,而是要新建一个script代码块,如下:
<script module="test3d" lang="renderjs">
export default{
data() {
return {
}
},
onLoad() {
},
methods: {
}
}
</script>
注意,上面的script块,我们为其指定了lang为renderjs。
2、threejs代码
先导入库:
import * as THREE from 'three';
注意,要先安装threejs库,可以使用npm安装:
npm install three
threejs的代码与在其他地方编写是一致的,在此处,我们需要写在methods模块下,我们可以创建一个方法:init。
init(){
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.querySelector('.three-view').appendChild(renderer.domElement);
//
//
const geometry = new THREE.SphereGeometry( 1.5, 32, 16,0,Math.PI*2,0,Math.PI );
group = new THREE.Group();
//线材质
const lineMaterial = new THREE.LineBasicMaterial( {
color: '#55aaff',
transparent: true,
opacity: 0.5 ,
});
//光材质
group.add(new THREE.LineSegments(geometry,lineMaterial));
const meshMaterial = new THREE.MeshPhongMaterial( {
color: '#25b0f5',
emissive: '#072534',
side: THREE.DoubleSide,
flatShading: true ,
});
group.add(new THREE.Mesh( geometry, meshMaterial ) );
scene.add(group);
//
// 从上方照射的白色平行光,强度为 0.5。
const lights = [];
lights[ 0 ] = new THREE.DirectionalLight( 0xffffff, 3 );
lights[ 1 ] = new THREE.DirectionalLight( 0xffffff, 3 );
lights[ 2 ] = new THREE.DirectionalLight( 0xffffff, 3 );
lights[ 0 ].position.set( 0, 200, 0 );
lights[ 1 ].position.set( 100, 200, 100 );
lights[ 2 ].position.set( - 100, - 200, - 100 );
scene.add( lights[ 0 ] );
scene.add( lights[ 1 ] );
scene.add( lights[ 2 ] );
//
const controls = new OrbitControls( camera, renderer.domElement );
camera.position.z = 5;
controls.update();
}
然后,我们创建一个动画方法:
animate(){
group.rotation.x += 0.005;
group.rotation.y += 0.005;
requestAnimationFrame(() => this.animate());
renderer.render(scene, camera);
}
上面的两个方法创建好后,我们可以在页面的创建周期内调用:
created(){
setTimeout(()=> {
this.init();
this.animate();
},500);
}
可以看下网页端的演示效果:
看下手机端的动态演示:
视频链接: