微信小程序之threejs全景
最近在开发小程序,身心疲惫,原因是功能和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全景的更多相关文章
- 微信小程序开发(3) 热门电影
在这篇微信小程序开发教程中,我们将介绍如何使用微信小程序开发热门电影及预览功能. 本文主要分为两个部分,小程序主体部分及电影主页和详情页页面部分 一.小程序主体部分 一个小程序主体部分由三个文件组成, ...
- 微信小程序开发心得
微信小程序也已出来有一段时间了,最近写了几款微信小程序项目,今天来说说感受. 首先开发一款微信小程序,最主要的就是针对于公司来运营的,因为,在申请appid(微信小程序ID号)时候,需要填写相关的公司 ...
- 微信小程序体验(2):驴妈妈景区门票即买即游
驴妈妈因为出色的运营能力,被腾讯选为首批小程序内测单位.驴妈妈的技术开发团队在很短的时间内完成了开发任务,并积极参与到张小龙团队的内测问题反馈.驴妈妈认为,移动互联网时代,微信是巨大的流量入口,也是旅 ...
- 微信小程序(微信应用号)组件讲解
这篇文章主要讲解微信小程序的组件. 首先,讲解新建项目.现在有句话:招聘三天以上微信小程序开发,这个估计只能去挖微信的工程师了.技术新,既然讲解,那我们就从开始建项目讲解. 打开微信web开发者工具, ...
- 神技!微信小程序(应用号)抢先入门教程(附最新案例DEMO-豆瓣电影)持续更新
微信小程序 Demo(豆瓣电影) 由于时间的关系,没有办法写一个完整的说明,后续配合一些视频资料,请持续关注 官方文档:https://mp.weixin.qq.com/debug/wxadoc/de ...
- 通过微信小程序看前端
前言 2016年9月22日凌晨,微信官方通过“微信公开课”公众号发布了关于微信小程序(微信应用号)的内测通知.整个朋友圈瞬间便像炸开了锅似的,各种揣测.介绍性文章在一夜里诞生.而真正收到内测邀请的公众 ...
- 快速了解微信小程序的使用,一个根据小程序的框架开发的todos app
微信官方已经开放微信小程序的官方文档和开发者工具.前两天都是在看相关的新闻来了解小程序该如何开发,这两天官方的文档出来之后,赶紧翻看了几眼,重点了解了一下文档中框架与组件这两个部分,然后根据简易教程, ...
- 来自于微信小程序的一封简讯
9月21晚间,微信向部分公众号发出公众平台-微信应用号(小程序)的内测邀请,向来较为低调的微信在这一晚没人再忽视它了. 来自个人博客:Damonare的个人博客 一夜之间火了的微信应用号你真的知道吗? ...
- 微信小程序前端源码逻辑和工作流
看完微信小程序的前端代码真的让我热血沸腾啊,代码逻辑和设计一目了然,没有多余的东西,真的是大道至简. 废话不多说,直接分析前端代码.个人观点,难免有疏漏,仅供参考. 文件基本结构: 先看入口app.j ...
随机推荐
- Ignite-Spark
2017.12.02 Ignite-Spark 讲ppt的时候还是很紧张 PPT地址 https://files.cnblogs.com/files/swobble/Spark.pptx
- 平衡树模板【splay的实现】
[平衡树splay实现] 无注释代码 #include<bits/stdc++.h> using namespace std; typedef long long LL; ,MAXN=1e ...
- 莫烦PyTorch学习笔记(四)——回归
下面的代码说明个整个神经网络模拟回归的过程,代码含有详细注释,直接贴下来了 import torch from torch.autograd import Variable import torch. ...
- P1985 [USACO07OPEN]翻转棋
题目链接: 翻转棋 题目分析: 先状压/\(dfs\)枚举第一排状态,然后在每个\(1\)下面翻,即确定了第一排就确定了后面的状态 最后验证一下最后一排是不是全0即可 代码: #include< ...
- 上海第三产业增加值 占比GDP首破七成
上海第三产业增加值 占比GDP首破七成 2016年08月16日08:10 来源:新闻晨报 分享到: 不久前结束的ChinaJoy上,一家名为HYPEREAL的VR公司展台前,体验者的热情程度 ...
- 7 Serialize and Deserialize Binary Tree 序列化及反序列化二叉树
原题网址:http://www.lintcode.com/zh-cn/problem/serialize-and-deserialize-binary-tree/# 设计一个算法,并编写代码来序列化和 ...
- 转:Linux 文件IO理解
源地址http://blog.csdn.net/lonelyrains/article/details/6604851 linux文件IO操作有两套大类的操作方式:不带缓存的文件IO操作,带缓存的文件 ...
- 07_Spring事务处理
一.事务概述 数据库的事务: 事务是一组操作的执行单元,相对于数据库操作来讲,事务管理的是一组SQL指令,比如增加,修改,删除等.事务的一致性,要求,这个事务内的操作必须全部执行成功,如果在此过程种出 ...
- <每日一题>题目26:选择排序(冒泡排序改进版)
''' 选择排序:选择最小的,以此类推 ''' import random import cProfile def select_Sort(nums): for i in range(len(nums ...
- 启动zuul时候报错:The bean 'proxyRequestHelper', defined in class path resource [org/springframework/cloud/netflix/zuul
启动zuul时候报错:The bean 'proxyRequestHelper', defined in class path resource [org/springframework/cloud/ ...