微信小程序之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 ...
随机推荐
- node vue 微信公众号(四)配置环境 本地测试
1.去natap 配置端口号 //本地项目是8080端口,natapp就配置8080端口 2.ngrok配合vue-cli实现外网访问 1.去 https://ngrok.com/download 下 ...
- ArrayList去除重复元素(多种方法实现)
package other; import java.util.ArrayList; import java.util.HashSet; public class test4 { public sta ...
- SpringBoot学习笔记(五):SpringBoot集成lombok工具、SpringBoot集成Shiro安全框架
SpringBoot集成lombok工具 什么是lombok? 自动生成setget方法,构造函数,打印日志 官网:http://projectlombok.org/features/index. 平 ...
- rocketmq 延时消息
rocketmq 的延时消息不能支持任意延时,她定义了18 个延时等级,并且我们可以指定这18 个延时等级的延时时间. 发送消息的时候只需在消息中指定 当前消息的 延时等级即可,并且这个延时消息不是 ...
- LINQ学习系列-----3.1 查询非泛型集合和多个分组
一.查询非泛型集合 1.问题起源 LINQ to object在设计时,是配合IEnumerable<T>接口的泛型集合类型使用的,例如字典.数组.List<T>等,但是对于继 ...
- PAT甲级——A1067 Sort with Swap(0, i)
Given any permutation of the numbers {0, 1, 2,..., N−1}, it is easy to sort them in increasing order ...
- elasticsearch 中文API facets(⑩)
facets Elasticsearch提供完整的java API用来支持facets.在查询的过程中,将需要计数的facets添加到FacetBuilders中.然后将该FacetBuilders条 ...
- Linux实现自动登录
使用expect实现自动登录的脚本,网上有很多,可是都没有一个明白的说明,初学者一般都是照抄.收藏.可是为什么要这么写却不知其然.本文用一个最短的例子说明脚本的原理. 脚本代码如下: #!/usr/b ...
- Python基本数据类型之字典,集合,range
注: ange()是python的内置函数,用于创建整数的列表,可以生成递增或者递减的数列.ange也是python的内置函数,用于创造xrange对象用于迭代. 在python3中,range() ...
- C语言处理字符串及内存操作
字符串处理函数 1.字符串长度 strlen表示包含的字符的个数,size_t strlen(char cosnt *string), 返回的是size_t类型,它是无符号整数类型,在表达式中进行运算 ...