淘宝小程序中使用threeJs渲染3D场景demo

在做淘宝小程序的项目的时候需要有用到3d场景,然后就想到使用threeJs来做渲染,但是threeJs依据的dom元素在小程序里面是没有的,故而需要和web端的threeJs不一样的文件,一个兼容的threeJs文件

淘宝小程序中使用的threeJs下载地址

页面代码

html元素
<!-- 一个canvas元素,type类型设置为webgl 事件需要拖动添加拖拽事件 -->
<view class="init_cabvas"><canvas id="myCanvas" class="my_canvas" type="webgl" onTouchStart="touchStart" onTouchMove="touchMove" onTouchEnd="touchEnd"  />
</view>
JS代码
// 引入threeJS
import {createScopedThreejs} from './threejs';
//设置一些全局变量,可以在每个函数中使用这些变量let THREE,canvas,scene,geometry,material, mesh,camera,renderer,width, height,k, touchSX, touchSY, objs=[], touchObj, isMove = false, initrotationX = 0, initrotationY = 0, loadCanvas = false;Page({data: {THREE: {},canvas: {},showCanvas: true,isHidden: true},onLoad() {},onShow () {//在onShow事件里面通过my.createCanvas来获取canvas文件,并通过createScopedThreejs来获取THREE。my.createCanvas({id: 'myCanvas',success: (canvass) => {canvas = canvassTHREE = createScopedThreejs(canvass);scene = new THREE.Scene();//创建3D场景this.craeteBox()}})},craeteBox () {//创建21个box立方体对象for (let i = 0; i < 21; i++) {mesh = nullgeometry = nullmaterial = null/*** 创建网格模型,创建400、400、400的立方体*/geometry = new THREE.BoxGeometry(400, 400, 400); //创建一个立方体几何对象Geometrymaterial = new THREE.MeshLambertMaterial({color: 0xffffff * Math.random(),transparent: true,opacity: 1}); //材质对象Materialmesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh//21个立方体,一行7个,总共3行,设置每个box的x、y、z的position位置let x = 800 * (i % 7) - 2400;let y = 1000 - 1000 * Math.floor(i / 7);let z = 0;let deg1 = (i % 7) * 21.145z = -Math.cos(Math.PI * (Math.abs(63.435 - deg1) / 180) ) * 2683 + 1200mesh.position.x = x;mesh.position.y = y;mesh.position.z = z;let deg = Math.PI * (63.435 - deg1) / 180scene.add(mesh); //网格模型添加到场景中}/*** 光源设置*///点光源var point = new THREE.PointLight(0xffffff);point.position.set(0, 0, 2500); //点光源位置scene.add(point); //点光源添加到场景中//环境光var ambient = new THREE.AmbientLight(0x444444);scene.add(ambient);//添加三维坐标// var axes = new THREE.AxisHelper(2500);// scene.add(axes);/*** 相机设置*/width = canvas.width; //窗口宽度height = canvas.height; //窗口高度camera = new THREE.PerspectiveCamera( 45, width / height, 1, 10000 );camera.position.set(0, 0, 4000)renderer = new THREE.WebGLRenderer();renderer.setSize(width, height);//设置渲染区域尺寸renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色function render() {//渲染的时候相机位置从4000拉近到1200let z = camera.position.z;if (z <= 1200) {z = 1200;camera.position.set(0, 0, z)renderer.render(scene,camera)return} else {z = z - 100}camera.position.set(0, 0, z)renderer.render(scene,camera);//执行渲染操作//淘宝小程序暂不支持requestAnimationFrame直接调用,需要canvas.requestAnimationFrame来调用canvas.requestAnimationFrame(render)}render();},/*** canvas的点击事件*/touchStart (e) {if (loadCanvas) {return}isMove = falsetouchObj = etouchSX = e.changedTouches[0].xtouchSY = e.changedTouches[0].yinitrotationX = camera.rotation.xinitrotationY = camera.rotation.y},touchMove (e) {if (loadCanvas) {return}isMove = truelet x = e.changedTouches[0].x - touchSXlet y = e.changedTouches[0].y - touchSYx = x > 140 ? 140 : x;y = y > 140 ? 140 : y;x = x < -140 ? -140 : x;y = y < -140 ? -140 : y;camera.rotation.y = initrotationY + Math.PI * (x / 10) / 180camera.rotation.x = initrotationX + Math.PI * (y / 10) / 180renderer.render(scene,camera);},touchEnd (e) {if (loadCanvas) {return}if (!isMove) {loadCanvas = truelet intersects = getIntersects(touchObj)if (intersects.length != 0 && intersects[intersects.length - 1].object instanceof THREE.Mesh) {let selectObject = intersects[intersects.length - 1].object;let initX = camera.position.x;let initY = camera.position.y;let initZ = camera.position.z;let initlineZ = Math.abs(scene.children[3].position.z);let posX = selectObject.position.x;let posY = selectObject.position.y;let posZ = selectObject.position.z;let camRotx = camera.rotation.x;let camRoty = camera.rotation.y;renderCamera(initX, initY, posX, posY, initZ, initlineZ, posZ, false, 0, camRotx, camRoty)} else {let initX = camera.position.x;let initY = camera.position.y;let initZ = camera.position.z;let posX = 0;let posY = 0;let posZ = 0;let initlineZ = 1000;let camRotx = camera.rotation.x;let camRoty = camera.rotation.y;renderCamera(initX, initY, posX, posY, initZ, initlineZ, posZ, false, 0, camRotx, camRoty)}// 获取与射线相交的对象数组function getIntersects(event) {var mouse = new THREE.Vector2();//射线相交检测在不同的系统、不同的手机渲染的情况不一样,需要获取手机系统信息进行判断才行。let SystemInfoSync = my.getSystemInfoSync()let Cwidth = (canvas.width / 2 ) / (canvas.width / SystemInfoSync.windowWidth)let Cheight = (canvas.height / 2 ) / (canvas.height / SystemInfoSync.windowHeight)mouse.x = (event.changedTouches[0].x - (Cwidth)) / (Cwidth)mouse.y = -(event.changedTouches[0].y - (Cheight)) / (Cheight)var vector = new THREE.Vector3(mouse.x, mouse.y,0.5).unproject(camera);var raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());var intersects = raycaster.intersectObjects(scene.children, true);return intersects}function changeMaterial(object) {var material = new THREE.MeshLambertMaterial({color: 0xffffff * Math.random(),transparent: object.material.transparent ? false : true,opacity: 0.8});object.material = material;}//渲染点击的元素,来进行移动,分成15步进行渲染。function renderCamera (initX, initY, posX, posY, initZ, initlineZ, posZ, init, index, initRotX, initRotY) {let x = camera.position.x;let y = camera.position.y;let z = camera.position.z;let chaX = (posX - initX) / 15let chaY = (posY - initY) / 15let chaZ = (initZ - (initlineZ - Math.abs(posZ) + 200)) / 15camera.position.set(x + chaX, y + chaY, z - chaZ);let nowRotX = camera.rotation.xlet nowRotY = camera.rotation.ylet initRotXx = initRotX / 15let initRotXy = initRotY / 15if (init) {initRotXx = (0 - initRotX) / 15initRotXy = (0 - initRotY) / 15} else {initRotXx = (initRotX - 0) / 15initRotXy = (initRotY - 0) / 15}camera.rotation.set(nowRotX - initRotXx, nowRotY - initRotXy, 0)renderer.render(scene,camera);++indexif (index >= 15) {loadCanvas = falsereturn} else {canvas.requestAnimationFrame(function () {renderCamera(initX, initY, posX, posY, initZ, initlineZ, posZ, init, index, initRotX, initRotY)})}}}}
});

3D需求场景样式demo展示

THREE.Raycaster射线检测在小程序里面IOS和安卓机兼容

射线检测在小程序里面会根据不同的手机、不同的系统,分辨率和宽高比不一样,返回的点击检测结果也不一样,需要进行不同的手机来做兼容。
射线检测手机兼容

小程序中使用threeJs渲染3D场景相关推荐

  1. 小程序中使用threejs

    webgl调试 起初使用threejs 在小程序里面调试,明明是按着官方的文档来,但是会发现开发者工具上面会提示getContext,经过一翻摸索,发现webgl调试只能在手机端调试. 总结:webg ...

  2. 微信3D小游戏系列一:在微信小游戏中使用threejs

    文章目录 环境配置 下载开发者工具 目录结构 引入Three.js 在小程序中运行 threejs 目标效果 小程序代码 环境配置 下载开发者工具 下载地址: https://developers.w ...

  3. 微信小程序中实现过滤器

    微信小程序中的过滤器 文章目录 微信小程序中的过滤器 前言 一.WXS 简介 1. 什么是wxs 2. wxs的应用场景 3. wxs和JavaScript的关系 4. wxs的特点 二.使用步骤 1 ...

  4. 浅谈高大上的微信小程序中渲染html内容—技术分享

    大部分Web应用的富文本内容都是以HTML字符串的形式存储的,通过HTML文档去展示HTML内容自然没有问题.但是,在微信小程序(下文简称为「小程序」)中,应当如何渲染这部分内容呢? 解决方案 wxP ...

  5. 在微信小程序中渲染HTML内容

    大部分Web应用的富文本内容都是以HTML字符串的形式存储的,通过HTML文档去展示HTML内容自然没有问题.但是,在微信小程序(下文简称为「小程序」)中,应当如何渲染这部分内容呢? 解决方案 wxP ...

  6. 微信小程序中嵌套html_在微信小程序中渲染HTML内容的方法示例

    大部分Web应用的富文本内容都是以HTML字符串的形式存储的,通过HTML文档去展示HTML内容自然没有问题.但是,在微信小程序(下文简称为「小程序」)中,应当如何渲染这部分内容呢? 解决方案 wxP ...

  7. 微信小程序中嵌套html_在微信小程序中渲染HTML内容3种解决方案及分析与问题解决...

    大部分Web应用的富文本内容都是以HTML字符串的形式存储的,通过HTML文档去展示HTML内容自然没有问题.但是,在微信小程序(下文简称为「小程序」)中,应当如何渲染这部分内容呢? 在微信小程序中渲 ...

  8. [贝聊科技]在微信小程序中渲染HTML内容

    大部分Web应用的富文本内容都是以HTML字符串的形式存储的,通过HTML文档去展示HTML内容自然没有问题.但是,在微信小程序(下文简称为「小程序」)中,应当如何渲染这部分内容呢? 解决方案 wxP ...

  9. 高大上的微信小程序中渲染html内容—技术分享

    大部分Web应用的富文本内容都是以HTML字符串的形式存储的,通过HTML文档去展示HTML内容自然没有问题.但是,在微信小程序(下文简称为「小程序」)中,应当如何渲染这部分内容呢? 解决方案 wxP ...

最新文章

  1. VUE的data数据对象
  2. day26 re正则表达式
  3. ossim-agent代理和要监控的服务器的配置
  4. MySql error 1010 无法删除数据库
  5. Python自动化办公——xlrd、xlwt读写Excel
  6. C#开发笔记之17-如何用C#深克隆一个对象(传统方案)?
  7. 微信短内容要来了!新功能已开启内测申请
  8. Python 2.x 即将终止支持,是时候和 Python 2 讲再见了
  9. java 英文数字下划线_为什么Java7开始在数字中使用下划线
  10. 【android原生态RPG游戏框架源码】
  11. mysql 导入导出 csv_mysql文件导入导出为csv格式
  12. Blender插件初始化范例
  13. 华三服务器bios中查看硬盘,H3C服务器升级BIOS
  14. 基于C++和EasyX 实现的《双人贪吃蛇》小游戏,你不找个小伙伴陪你一起玩吗?
  15. 04 用户权限管理 实验报告
  16. 如何展示实时音视频通话时正在说话用户的音浪
  17. Linux编码解码指令-base64
  18. 贪心算法or背包问题
  19. MiniGUI 体系结构之二
  20. Quick BI移动端:让数据在更多业务场景中流通

热门文章

  1. RH436之高级资源管理
  2. MC9S12XE bootloader开发
  3. 制造企业数字化工厂建设步骤的建议
  4. php中一级标题和二级标题,写论文中大标题,一级标题,二级标题分别指什么啊?...
  5. 超大屏4G双卡双待 酷派S6双色对比图赏
  6. Pytorch的nn.DataParallel详细解析
  7. 心理测评系统软件使用问题一
  8. 「Adobe国际认证」 Adobe Illustrator徽标设计
  9. ​​力扣——魔塔游戏​
  10. Data Whale第20期组队学习 Pandas学习—时序数据