最近在开发小程序,身心疲惫,原因是功能和app相同,我裂开了。

各种封装组件,各种写页面,不过有个好处是以前写的h5拿来改一下标签,基本上还是ok的,就剩下最后几个功能,其中就有一个VR全景功能。

移动端倒是好做,上次做了大概2天就搞定了,原理就是threejs用css3做图片的旋转,具体例子可以参照https://threejs.org/examples/css3d_panorama.html不过多描述,下面进入今天的主角:在微信小程序中使用threejs实现VR全景功能。

刚开始想到这个功能,我是拒绝的,这简直就是要了我的头发啊,没办法,谁叫我走上开发这条不归路呢,自己选的路,秃头也要走完。。

那就硬着头皮开始吧,先百度搜了一下在小程序中使用threejs,找到一篇比较干货的文章https://developers.weixin.qq.com/community/develop/article/doc/00066c4b230b085051592292f5bc13,这篇文章作者把threejs给提炼出来了一个小程序版本,

照着他的demo先把canvas给搞出来先。然后再实现全景,怎么实现也是头疼的事情,怎么,我不会写,还不会改吗?

先看看以前h5的实现方式,采用CSS3DRenderer来实现,问题来了,小程序里面不支持dom的createElement,那咋整嘛,只有换思路了,继续研究threejs的demo,第一个版本思路出来了,说了太多废话,直接来代码了:

<view style="height: 100%; width: 100%;">
<canvas type="webgl" id="c" style="width: 100%; height:100%;" bindtouchstart="touchStart" bindtouchmove="touchMove" bindtouchend="touchEnd" bindtouchcancel="touchCancel" bindlongtap="longTap" bindtap="tap"></canvas>
</view>
import * as THREE from '../../lib/threejs/three.weapp.min.js'
import { OrbitControls } from '../../lib/threejs/OrbitControls' Page({
data: {},
onLoad: function () {
wx.createSelectorQuery()
.select('#c')
.node()
.exec((res) => {
// 创建canvas对象
const canvas = THREE.global.registerCanvas(res[0].node)
// 记录canvas的id,好在page销毁的时候释放canvas
this.setData({ canvasId: canvas._canvasId }) const camera = new THREE.PerspectiveCamera(75, canvas.width / canvas.height, 1, 2000);
camera.position.z = 500;
const scene = new THREE.Scene();
scene.background = new THREE.Color(0xAAAAAA);
const renderer = new THREE.WebGLRenderer({ antialias: true }); const controls = new OrbitControls(camera, renderer.domElement); camera.position.set(200, 200, 500);
controls.update();
const geometry = new THREE.SphereBufferGeometry( 500, 60, 40 ).toNonIndexed();
geometry.scale( - 1, 1, 1 ); var texture = new THREE.TextureLoader().load( 'http://www.yanhuangxueyuan.com/threejs/examples/textures/2294472375_24a3b8ef46_o.jpg' ); // canvas中文文档作者的图,侵删
texture.minFilter = THREE.LinearFilter;
texture.format = THREE.RGBFormat;
var material = new THREE.MeshBasicMaterial( { map: texture } );
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh); function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(canvas.width, canvas.height);
}
function render() {
canvas.requestAnimationFrame(render);
controls.update();
renderer.render(scene, camera);
} render() })
},
onUnload: function () {
// 释放canvas
THREE.global.unregisterCanvas(this.data.canvasId)
},
touchStart(e) {
console.log('canvas', e)
THREE.global.touchEventHandlerFactory('canvas', 'touchstart')(e)
},
touchMove(e) {
console.log('canvas', e)
THREE.global.touchEventHandlerFactory('canvas', 'touchmove')(e)
},
touchEnd(e) {
console.log('canvas', e)
THREE.global.touchEventHandlerFactory('canvas', 'touchend')(e)
}
})

嗨呀,以上代码我是看都看不懂,那咋办嘛,你挑的嘛偶像。莫有办法,只有百度查具体每个关键字的意思,这里也就不多讲了,因为我也不知道。这种方法有个问题就是,图片只支持一张的图片,而且这个图片是要用全景相机照出来的,限制比较多,怎么办嘛,肯定不能用这个方法呀,不然这个成本就没法估算了。

于是乎我开始探索第二种方法,还是采用6张图的方法,还是原来的配方,还是熟悉的味道。话不多少,上代码:

import * as THREE from './three.weapp.min.js'
import { OrbitControls } from './OrbitControls' Page({
data: {},
onLoad: function () {
wx.createSelectorQuery()
.select('#c')
.node()
.exec((res) => {
const canvas = THREE.global.registerCanvas(res[0].node) this.setData({ canvasId: canvas._canvasId }) const camera = new THREE.PerspectiveCamera(75, canvas.width / canvas.height, 1, 2000);
const scene = new THREE.Scene();
const renderer = new THREE.WebGLRenderer({ antialias: true }); const controls = new OrbitControls(camera, renderer.domElement);
// 控制镜头缩放,这里禁用了,因为是用正方体做的 除非能解决正方体的大小问题
controls.enableZoom = false
camera.position.set(-0.1, 2, -5);
controls.update(); var sides = ['右.jpg', '左.jpg','上.jpg', '下.jpg','前.jpg', '后.jpg']
var materials = [];
for (var i = 0; i < sides.length; i++) {
var side = sides[i];
var texture = new THREE.TextureLoader().load(side);
materials.push( new THREE.MeshBasicMaterial( { map: texture } ) );
}
     // 这里物体的长宽高,我始终不知道该是多少
var mesh = new THREE.Mesh( new THREE.BoxBufferGeometry( canvas.height, canvas.height, canvas.height ), materials );
mesh.geometry.scale( -1, 1, 1 ); scene.add(mesh); function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(canvas.width, canvas.height);
}
function render() {
canvas.requestAnimationFrame(render);
controls.update();
renderer.render(scene, camera);
} render() })
},
onUnload: function () {
THREE.global.unregisterCanvas(this.data.canvasId)
},
touchStart(e) {
console.log('canvas', e)
THREE.global.touchEventHandlerFactory('canvas', 'touchstart')(e)
},
touchMove(e) {
console.log('canvas', e)
THREE.global.touchEventHandlerFactory('canvas', 'touchmove')(e)
},
touchEnd(e) {
console.log('canvas', e)
THREE.global.touchEventHandlerFactory('canvas', 'touchend')(e)
}
})

这两种方法的区别就是,第二种采用6张图片(右左上下前后),6个面表示一个正方体,然后将视角拉到正方体内,就是一个全景效果,完美。

这里的写法也是参照的https://github.com/mrdoob/three.js/blob/master/examples/webgl_panorama_cube.html,具体其中的参数,我也不太清楚,反正编程全靠试(猜)。

贴下今天的成果吧:

这是最开始完成第二种方法时的初次效果,当我看到这个效果的时候,我就知道已经差不多快ok了。

这是最终实现的效果,哈哈还不错吧(勉强符合功能需求)

距离上一次写博客,又过去了4个月,这4个月感觉过得是真的快,然而文章依然是这么水...(这也太水了吧)

感谢threejs和https://developers.weixin.qq.com/community/develop/article/doc/00066c4b230b085051592292f5bc13文章的作者

微信小程序之threejs全景的更多相关文章

  1. 微信小程序开发(3) 热门电影

    在这篇微信小程序开发教程中,我们将介绍如何使用微信小程序开发热门电影及预览功能. 本文主要分为两个部分,小程序主体部分及电影主页和详情页页面部分 一.小程序主体部分 一个小程序主体部分由三个文件组成, ...

  2. 微信小程序开发心得

    微信小程序也已出来有一段时间了,最近写了几款微信小程序项目,今天来说说感受. 首先开发一款微信小程序,最主要的就是针对于公司来运营的,因为,在申请appid(微信小程序ID号)时候,需要填写相关的公司 ...

  3. 微信小程序体验(2):驴妈妈景区门票即买即游

    驴妈妈因为出色的运营能力,被腾讯选为首批小程序内测单位.驴妈妈的技术开发团队在很短的时间内完成了开发任务,并积极参与到张小龙团队的内测问题反馈.驴妈妈认为,移动互联网时代,微信是巨大的流量入口,也是旅 ...

  4. 微信小程序(微信应用号)组件讲解

    这篇文章主要讲解微信小程序的组件. 首先,讲解新建项目.现在有句话:招聘三天以上微信小程序开发,这个估计只能去挖微信的工程师了.技术新,既然讲解,那我们就从开始建项目讲解. 打开微信web开发者工具, ...

  5. 神技!微信小程序(应用号)抢先入门教程(附最新案例DEMO-豆瓣电影)持续更新

    微信小程序 Demo(豆瓣电影) 由于时间的关系,没有办法写一个完整的说明,后续配合一些视频资料,请持续关注 官方文档:https://mp.weixin.qq.com/debug/wxadoc/de ...

  6. 通过微信小程序看前端

    前言 2016年9月22日凌晨,微信官方通过“微信公开课”公众号发布了关于微信小程序(微信应用号)的内测通知.整个朋友圈瞬间便像炸开了锅似的,各种揣测.介绍性文章在一夜里诞生.而真正收到内测邀请的公众 ...

  7. 快速了解微信小程序的使用,一个根据小程序的框架开发的todos app

    微信官方已经开放微信小程序的官方文档和开发者工具.前两天都是在看相关的新闻来了解小程序该如何开发,这两天官方的文档出来之后,赶紧翻看了几眼,重点了解了一下文档中框架与组件这两个部分,然后根据简易教程, ...

  8. 来自于微信小程序的一封简讯

    9月21晚间,微信向部分公众号发出公众平台-微信应用号(小程序)的内测邀请,向来较为低调的微信在这一晚没人再忽视它了. 来自个人博客:Damonare的个人博客 一夜之间火了的微信应用号你真的知道吗? ...

  9. 微信小程序前端源码逻辑和工作流

    看完微信小程序的前端代码真的让我热血沸腾啊,代码逻辑和设计一目了然,没有多余的东西,真的是大道至简. 废话不多说,直接分析前端代码.个人观点,难免有疏漏,仅供参考. 文件基本结构: 先看入口app.j ...

随机推荐

  1. git归纳总结

    1,git 是分布式版本控制:单个电脑就是一个完整的版本库,只需向中央服务器(远程服务器)提交修改的部分.在没有网络情况下也能正常想本机服务器提交代码管理版本,有网时再推送到远程服务器.   svn是 ...

  2. springboot与分布式(zookeeper+dubbo)

    docker安装zookeeper命令: docker pull zookeeper:3.4.14 docker启动zookeeper命令: docker run --name zk01 -p 218 ...

  3. 19-11-05-Night

    我就是不行. ZJ: 好像是因为郁闷了才咕掉的…… 33 Miemeng 30 00:01:34 40 00:01:46 0 00:01:22 70 00:01:46 不记得当时怎么想的 T1只会暴力 ...

  4. Django logging 的配置方法

    做开发离不开日志,以下是我在工作中写Django项目常用的logging配置. BASE_LOG_DIR = os.path.join(BASE_DIR, "log") LOGGI ...

  5. Tornado demo3 - tcpecho分析

    在这个demo中,主要是使用了Tornado中异步的TCP client和server来实现一个简单的echo效果(即客户端发送的message会从server端返回到client).代码的githu ...

  6. [转]WPF and Silverlight 学习笔记(二十五):使用CollectionView实现对绑定数据的排序、筛选、分组

    在第二十三节,我们使用CollectionView实现了对于绑定数据的导航,除导航功能外,还可以通过CollectionView对数据进行类似于DataView的排序.筛选等功能. 一.数据的排序: ...

  7. Elasticsearch系列(一)--入门

    Elasticsearch基于Lucene构建的开源搜索引擎,Java编写,提供restful API,支持横向拓展,能够完成海量数据处理. 应用场景: 1.海量数据分析引擎 2.站内搜索引擎 3.数 ...

  8. HZOI20190814 B 不等式

    不等式 题目大意:求解满足$L \leqslant(S×x)mod M\leqslant R$的x最小正整数解,无解输出-1 几种部分分: $L==R$,就是$ex_gcd$; 解在$1e6$以内:搜 ...

  9. JDK中有关23个经典设计模式的示例

    Creational patterns Abstract factory (recognizeable by creational methods returning an abstract/inte ...

  10. 工控安全入门(五)—— plc逆向初探

    之前我们学习了包括modbus.S7comm.DNP3等等工控领域的常用协议,从这篇开始,我们一步步开始,学习如何逆向真实的plc固件. 用到的固件为https://github.com/ameng9 ...