微信小程序之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 ...
随机推荐
- leetcode-03-二叉树的锯齿层次遍历
题目描述: 方法一: # Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.va ...
- Python3基础笔记_字符串类型
# 1.Python转义字符 a = "sqwerdf" # 2.Python字符串运算符 ''' + 字符串连接 a + b 输出结果: HelloPython * 重复输出字符 ...
- HashMap四种遍历方式
public static void main(String[] args){ Map<String,String> map = new HashMap<String, String ...
- Linux的CentOS上如何安装nginx
1. 安装nginx前,首先要装好gcc和g++环境: 2. 在centOS上装nginx,需要PCRE.zlib和ssl的支持,出ssl外其他都需要从其官网上下载好,上传至服务器: 3. 接着将上传 ...
- <b> <i> 标记
<b></b> bold 加粗 <i></i> italic 斜线 : 对应Word文档的 I 斜体 <u></u>unde ...
- PAT甲级——A1079 Total Sales of Supply Chain
A supply chain is a network of retailers(零售商), distributors(经销商), and suppliers(供应商)-- everyone invo ...
- eclipse memory analyzer对系统内存溢出堆文件解析0(转)
前言 在平时工作过程中,有时会遇到OutOfMemoryError,我们知道遇到Error一般表明程序存在着严重问题,可能是灾难性的.所以找出是什么原因造成OutOfMemoryError非常重要.现 ...
- mybtais分批insert
这里自己写了个对集合按一批的数量进行分批操作的分页bean,见PagenationUtil如下: package com.util; import java.util.List ; /** * @au ...
- 03_springmvc整合mybatis
一.整合思路 springmvc+mybaits的系统架构: 第一步整合dao层:mybatis和spring整合:通过spring管理mapper接口,使用mapper的扫描器自动扫描mapper接 ...
- python3-常用模块之time
import time time模块主要是处理各种类型的时间 常用方法 1.time.sleep(secs) (线程)推迟指定的时间运行,单位为秒. 2.time.time() 获取当前时间戳 时间戳 ...