相关文章推荐
酷酷的羊肉串  ·  在canvas中根据鼠标的位置,获取当前点的 ...·  1 月前    · 
粗眉毛的薯片  ·  像素操作 - Web API | MDN·  1 月前    · 
开心的炒饭  ·  使用window.open()打开新窗口时携 ...·  1 年前    · 
迷茫的煎鸡蛋  ·  用electron打包前端应用初体验 - 知乎·  2 年前    · 
正直的番茄  ·  如何将Drawable转换为位图?·  2 年前    · 
拉风的闹钟  ·  wpf 关于 已多次设置属性content ...·  2 年前    · 
听话的棒棒糖  ·  java - Getting ...·  2 年前    · 
Code  ›  小程序中使用three.js | 微信开放社区
小程序 canvas
https://developers.weixin.qq.com/community/develop/article/doc/00066c4b230b085051592292f5bc13
英俊的铁板烧
2 年前

交流专区
服务市场
微信学堂
文档
小程序
  • 常用主页

    小程序

    小游戏

    企业微信

    微信支付

  • 服务市场
    微信学堂
    文档
登录
评论

置顶 小程序中使用three.js 精选 热门

Yann 2019-10-20
52289 浏览
63 评论

在小程序中使用three.js, 支持基本模型,OrbitControl, GTLFLoader, OBJLoader等。

小程序中使用three.js

目前小程序支持了webgl, 同时项目中有相关3D展示的需求,所以考虑将three.js移植到小程序中。
但是小程序里面没有浏览器相关的运行环境如 window,document等。要想在小程序中使用three.js需要使用相应的 移植版本 。 https://github.com/yannliao/three.js 实现了一个在 three.js 的基本移植版, 目前测试支持了 包含 BoxBufferGeometry, CircleBufferGeometry, ConeBufferGeometry, CylinderBufferGeometry, DodecahedronBufferGeometry 等基本模型,OrbitControl, GTLFLoader, OBJLoader等。

下载 https://github.com/yannliao/three.js 项目中build目录下的three.weapp.min.js到小程序相应目录,如:

在index.wxml中加入canvas组件, 其中需要手动绑定相应的事件,用于手势控制。

<view style="height: 100%; width: 100%;" bindtouchstart="documentTouchStart" bindtouchmove="documentTouchMove" bindtouchend="documentTouchEnd" >
    <canvas type="webgl" id="c" style="width: 100%; height:100%;" bindtouchstart="touchStart" bindtouchmove="touchMove" bindtouchend="touchEnd" bindtouchcancel="touchCancel" bindlongtap="longTap" bindtap="tap"></canvas>
</view>

在页面中引用three.js 和相应的Loader:

import * as THREE from '../../libs/three.weapp.min.js'
import { OrbitControls } from '../../jsm/loaders/OrbitControls'

在onLoad中获取canvas对象并注册到THREE.global中,THREE.global.registerCanvas可以传入id, 用于通过THREE.global.document.getElementById找到, 如果不传id默认使用canvas对象中的_canvasID, registerCanvas同时也会将该canvas选为当前使用canvas对象. 同时请在onUnload回调中注销canvas对象. 注意: THREE.global 中最多同时注册 5 个canvas对象, 并可以通过id找到. 注册的canvas对象, 会长驻内存, 如果不及时清理可能造成内存问题. THREE.global为three.js 的运行环境, 类似于浏览器中的window.

Page({
    data: {
        canvasId: ''
    onLoad: function () {
        wx.createSelectorQuery()
        .select('#c')
        .node()
        .exec((res) => {
            const canvas = THREE.global.registerCanvas(res[0].node)
            this.setData({ canvasId: canvas._canvasId })
            // const canvas = THREE.global.registerCanvas('id_123', res[0].node)
            // canvas代码
    onUnload: function () {
        THREE.global.unregisterCanvas(this.data.canvasId)
        // THREE.global.unregisterCanvas(res[0].node)
        // THREE.global.clearCanvas()

注册相关touch事件. 由于小程序架构原因, 需要手动绑定事件到THREE.global.canvas或者THREE.global.document上. 可以使用THREE.global.touchEventHandlerFactory('canvas', 'touchstart') 生成小程序的事件回调函数,触发默认canvas对象上的touch事件.

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)

编写three.js代码, 小程序运行环境中没有requestAnimationFrame, 目前可以使用canvas.requestAnimationFrame之后会将requestAnimationFrame注入到THREE.global中.

const camera = new THREE.PerspectiveCamera(70, canvas.width / canvas.height, 1




    
, 1000);
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);
// controls.enableDamping = true;
// controls.dampingFactor = 0.25;
// controls.enableZoom = false;
camera.position.set(200, 200, 500);
controls.update();
const geometry = new THREE.BoxBufferGeometry(200, 200, 200);
const texture = new THREE.TextureLoader().load('./pikachu.png');
const material = new THREE.MeshBasicMaterial({ map: texture });
// const material = new THREE.MeshBasicMaterial({ color: 0x44aa88 });
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
// renderer.setPixelRatio(wx.getSystemInfoSync().pixelRatio);
// renderer.setSize(canvas.width, canvas.height);
function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(canvas.width, canvas.height);
function render() {
    canvas.requestAnimationFrame(render);
    // mesh.rotation.x += 0.005;
    // mesh.rotation.y += 0.01;
    controls.update();
    renderer.render(scene, camera);
render()

完整示例:

index.js

import * as THREE from '../../libs/three.weapp.min.js'
import { OrbitControls } from '../../jsm/loaders/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(70, canvas.width / canvas.height, 1, 1000);
        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);
        // controls.enableDamping = true;
        // controls.dampingFactor = 0.25;
        // controls.enableZoom = false;
        camera.position.set(200, 200, 500);
        controls.update();
        const geometry = new THREE.BoxBufferGeometry(200, 200, 200);
        const texture = new THREE.TextureLoader().load('./pikachu.png');
        const material = new THREE.MeshBasicMaterial({ map: texture });
        // const material = new THREE.MeshBasicMaterial({ color: 0x44aa88 });
        const mesh = new THREE.Mesh(geometry, material);
        scene.add(mesh);
        // renderer.setPixelRatio(wx.getSystemInfoSync().pixelRatio);
        // renderer.setSize(canvas.width, canvas.height);
        function onWindowResize() {
          camera.aspect = window.innerWidth / window.innerHeight;
          camera.updateProjectionMatrix();
          renderer.setSize(canvas.width, canvas.height);
        function render() {
          canvas.requestAnimationFrame(render);
          // mesh.rotation.x += 0.005;
          // mesh.rotation.y += 0.01;
          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)
  touchCancel(e) {
    // console.log('canvas', e)
  longTap(e) {
    // console.log('canvas', e)
  tap(e) {
    // console.log('canvas', e)
  documentTouchStart(e) {
    // console.log('document',e)
  documentTouchMove(e) {
    // console.log('document',e)
  documentTouchEnd(e) {
    // console.log('document',e)

index.wxml

<view style="height: 100%; width: 100%;" bindtouchstart="documentTouchStart" bindtouchmove="documentTouchMove" bindtouchend="documentTouchEnd" >
    <canvas type="webgl" id="c" style="width: 100%; height:100%;" bindtouchstart="touchStart" bindtouchmove="touchMove" bindtouchend="touchEnd" bindtouchcancel="touchCancel" bindlongtap="longTap" bindtap="tap"></canvas>
</view>

全部示例在 https://github.com/yannliao/threejs-example

three.js 库 https://github.com/yannliao/three.js

loader 组件在 threejs-example 中的 jsm 目录中

欢迎提交PR和issue

最后一次编辑于 2019-10-20
点赞 20
收藏
分享

扫描小程序码分享

复制链接

删除文章后,文章内容和评论将一并被删除,且不可恢复。

删除 取消
评论
关闭

请选择投诉理由

  • 广告内容
  • 违法违规
  • 恶意灌水内容
  • 其他

63 个评论

  • 123
    123
    2020-08-19
    请 登录 后发表内容
    关闭

    新增或编辑超链接

    确认 取消
    关闭

    插入视频

    确认 取消
    发表

    小程序中怎么能使用three.js渲染视频纹理呢?

    你好,麻烦通过点击下方“反馈信息”按钮,提供出现问题的。

    待楼主反馈
    2020-08-19
    赞同 6
    回复
    关闭

    请选择投诉理由

    • 广告内容
    • 违法违规
    • 恶意灌水内容
    • 其他
  • 张先生
    张先生
    2022-08-30
    请 登录 后发表内容
    关闭

    新增或编辑超链接

    确认 取消
    关闭

    插入视频

    确认 取消
    发表

    全网最强小程序版Three引擎

    https://gitee.com/onekit-game/three-weixin-demo

    你好,麻烦通过点击下方“反馈信息”按钮,提供出现问题的。

    待楼主反馈
    2022-08-30
    赞同 3
    回复 3
    • 张先生
      张先生
      2022-10-12
      请 登录 后发表内容
      关闭

      新增或编辑超链接

      确认 取消
      关闭

      插入视频

      确认 取消
      发表
      【地址更新】 https://gitee.com/threejs

      你好,麻烦通过点击下方“反馈信息”按钮,提供出现问题的。

      待楼主反馈
      2022-10-12
      赞 2
      回复
      关闭

      请选择投诉理由

      • 广告内容
      • 违法违规
      • 恶意灌水内容
      • 其他
    • 专注于热爱
      专注于热爱
      2022-11-28
      请 登录 后发表内容
      关闭

      新增或编辑超链接

      确认 取消
      关闭

      插入视频

      确认 取消
      发表
      您好,能帮忙测试一下这个glb模型 https://demo-xiangmu.obs.cn-east-3.myhuaweicloud.com/luoyaongmuseum/11.glb ,用你的引擎在苹果手机和ipad上是否能正常显示?

      你好,麻烦通过点击下方“反馈信息”按钮,提供出现问题的。

      待楼主反馈
      2022-11-28
      赞
      回复
      关闭

      请选择投诉理由

      • 广告内容
      • 违法违规
      • 恶意灌水内容
      • 其他
    • 未来之门
      未来之门
      2022-12-07 回复 专注于热爱
      请 登录 后发表内容
      关闭

      新增或编辑超链接

      确认 取消
      关闭

      插入视频

      确认 取消
      发表
      感谢使用ThreeX。iOS/Android已测试可以显示(小程序WebGL问题,需要额外添加环境光和平行光)

      你好,麻烦通过点击下方“反馈信息”按钮,提供出现问题的。

      待楼主反馈
      2022-12-07
      赞 1
      回复
      关闭

      请选择投诉理由

      • 广告内容
      • 违法违规
      • 恶意灌水内容
      • 其他
    关闭

    请选择投诉理由

    • 广告内容
    • 违法违规
    • 恶意灌水内容
    • 其他
  • l.k
    l.k
    2021-05-17
    请 登录 后发表内容
    关闭

    新增或编辑超链接

    确认 取消
    关闭

    插入视频

    确认 取消
    发表

    微信工具是好的, 真机测试有问题

    你好,麻烦通过点击下方“反馈信息”按钮,提供出现问题的。

    待楼主反馈
    2021-05-17
    赞同 2
    回复 1
    • d
      d
      2022-01-26
      请 登录 后发表内容
      关闭

      新增或编辑超链接

      确认 取消
      关闭

      插入视频

      确认 取消
      发表
      你好 请问真机测试这个问题解决了吗?

      你好,麻烦通过点击下方“反馈信息”按钮,提供出现问题的。

      待楼主反馈
      2022-01-26
      赞
      回复
      关闭

      请选择投诉理由

      • 广告内容
      • 违法违规
      • 恶意灌水内容
      • 其他
    关闭

    请选择投诉理由

    • 广告内容
    • 违法违规
    • 恶意灌水内容
    • 其他
  • funcell
    funcell
    2020-06-19
    请 登录 后发表内容
    关闭

    新增或编辑超链接

    确认 取消
    关闭

    插入视频

    确认 取消
    发表

    楼主大佬你好!你说的“目前测试支持了 包含 BoxBufferGeometry, CircleBufferGeometry, ConeBufferGeometry, CylinderBufferGeometry, DodecahedronBufferGeometry 等基本模型,OrbitControl, GTLFLoader, OBJLoader等。”,这是在真机上测试都可以吗?还是只在电脑上可以?

    你好,麻烦通过点击下方“反馈信息”按钮,提供出现问题的。

    待楼主反馈
    2020-06-19
    赞同 2
    回复 1
    • 我终于可以有个昵称
      我终于可以有个昵称
      2020-10-28
      请 登录 后发表内容
      关闭

      新增或编辑超链接

      确认 取消
      关闭

      插入视频

      确认 取消
      发表
      我真机测试没法,只能在电脑上用

      你好,麻烦通过点击下方“反馈信息”按钮,提供出现问题的。

      待楼主反馈
      2020-10-28
      赞 1
      回复
      关闭

      请选择投诉理由

      • 广告内容
      • 违法违规
      • 恶意灌水内容
      • 其他
    关闭

    请选择投诉理由

    • 广告内容
    • 违法违规
    • 恶意灌水内容
    • 其他
  • 阿飞
    阿飞
    2020-05-20
    请 登录 后发表内容
    关闭

    新增或编辑超链接

    确认 取消
    关闭

    插入视频

    确认 取消
    发表

    搭建项目一直有问题 不是在小游戏里面搭建的吧 可以在小程序搭建吧 然后我感觉我用的两个js文件跟你们的就有差别 就很蛋疼, 有没有跟我情况一样的

    你好,麻烦通过点击下方“反馈信息”按钮,提供出现问题的。

    待楼主反馈
    2020-05-20
    赞同 1
    回复
    关闭

    请选择投诉理由

    • 广告内容
    • 违法违规
    • 恶意灌水内容
    • 其他
  • jd
    jd
    2020-02-27
    请 登录 后发表内容
    关闭

    新增或编辑超链接

    确认 取消
    关闭

    插入视频

    确认 取消
    发表

    请指教下,微信官方的那个threejs-miniprogram

    https://developers.weixin.qq.com/miniprogram/dev/extended/utils/threejs.html

    跟你这个有啥关系没有?

    你好,麻烦通过点击下方“反馈信息”按钮,提供出现问题的。

    待楼主反馈
    2020-02-27
    赞同 1
    回复 5
    • Yann
      Yann
      2020-02-29
      请 登录 后发表内容
      关闭

      新增或编辑超链接

      确认 取消
      关闭

      插入视频

      确认 取消
      发表
      没啥关系呢

      你好,麻烦通过点击下方“反馈信息”按钮,提供出现问题的。

      待楼主反馈
      2020-02-29
      赞 3
      回复
      关闭

      请选择投诉理由

      • 广告内容
      • 违法违规
      • 恶意灌水内容
      • 其他
    • Mr. Cao
      Mr. Cao
      2020-04-03 回复 Yann
      请 登录 后发表内容
      关闭

      新增或编辑超链接

      确认 取消
      关闭

      插入视频

      确认 取消
      发表
      您好请问可以加载fbx格式的文件吗

      你好,麻烦通过点击下方“反馈信息”按钮,提供出现问题的。

      待楼主反馈
      2020-04-03
      赞
      回复
      关闭

      请选择投诉理由

      • 广告内容
      • 违法违规
      • 恶意灌水内容
      • 其他
    • Gu
      Gu
      2021-07-30 回复 Yann
      请 登录 后发表内容
      关闭

      新增或编辑超链接

      确认 取消
      关闭

      插入视频

      确认 取消
      发表
      同问支持fbx格式文件吗

      你好,麻烦通过点击下方“反馈信息”按钮,提供出现问题的。

      待楼主反馈
      2021-07-30
      赞
      回复
      关闭

      请选择投诉理由

      • 广告内容
      • 违法违规
      • 恶意灌水内容
      • 其他
    • sheepcircle
      sheepcircle
      2021-11-04
      请 登录 后发表内容
      关闭

      新增或编辑超链接

      确认 取消
      关闭

      插入视频

      确认 取消
      发表
      可以FBX格式吗

      你好,麻烦通过点击下方“反馈信息”按钮,提供出现问题的。

      待楼主反馈
      2021-11-04
      赞
      回复
      关闭

      请选择投诉理由

      • 广告内容
      • 违法违规
      • 恶意灌水内容
      • 其他
    • 张先生
      张先生
      2022-10-12
      请 登录 后发表内容
      关闭

      新增或编辑超链接

      确认 取消
      关闭

      插入视频

      确认 取消
      发表
      官方几百年都不升级了

      你好,麻烦通过点击下方“反馈信息”按钮,提供出现问题的。

      待楼主反馈
      2022-10-12
      赞
      回复
      关闭

      请选择投诉理由

      • 广告内容
      • 违法违规
      • 恶意灌水内容
      • 其他
    关闭

    请选择投诉理由

    • 广告内容
    • 违法违规
    • 恶意灌水内容
    • 其他
  • 陈学新คิดถึง
    陈学新คิดถึง
    2019-10-21
    请 登录 后发表内容
    关闭

    新增或编辑超链接

    确认 取消
    关闭

    插入视频

    确认 取消
    发表

    贴图预览是黑色的,汗,求指教

    你好,麻烦通过点击下方“反馈信息”按钮,提供出现问题的。

    待楼主反馈
    2019-10-21
    赞同 1
    回复
    关闭

    请选择投诉理由

    • 广告内容
    • 违法违规
    • 恶意灌水内容
    • 其他
  • 👔
    👔
    01-29
    请 登录 后发表内容
    关闭

    新增或编辑超链接

    确认 取消
    关闭

    插入视频

    确认 取消
    发表

    您好 请问为什么找不到 OrbitControl,谢谢

    你好,麻烦通过点击下方“反馈信息”按钮,提供出现问题的。

    待楼主反馈
    01-29
    赞同
    回复 1
    • 👔
      👔
      01-29
      请 登录 后发表内容
      关闭

      新增或编辑超链接

      确认 取消
      关闭

      插入视频

      确认 取消
      发表
      找到了 谢谢

      你好,麻烦通过点击下方“反馈信息”按钮,提供出现问题的。

      待楼主反馈
      01-29
      赞
      回复
      关闭

      请选择投诉理由

      • 广告内容
      • 违法违规
      • 恶意灌水内容
      • 其他
    关闭

    请选择投诉理由

    • 广告内容
    • 违法违规
    • 恶意灌水内容
    • 其他
  • 冯钰清
    冯钰清
    2022-10-14
    请 登录 后发表内容
    关闭

    新增或编辑超链接

    确认 取消
    关闭

    插入视频

    确认 取消
    发表

    canvas.requestAnimationFrame 是怎么实现的呢?以及THREE.global 可以充当web里面的window又是怎么实现的

    你好,麻烦通过点击下方“反馈信息”按钮,提供出现问题的。

    待楼主反馈
    2022-10-14
    赞同
    回复
    关闭

    请选择投诉理由

    • 广告内容
    • 违法违规
    • 恶意灌水内容
    • 其他
  • xyz
    xyz
    2022-10-10
    请 登录 后发表内容
    关闭

    新增或编辑超链接

    确认 取消
    关闭

    插入视频

    确认 取消
    发表

    微信小程序很难用three.js或者其他webgl框架,获取canvas实例的NodesRef.node()这个api对基础库的要求是在2.7.0以上,直接导致大部分手机不兼容...

    你好,麻烦通过点击下方“反馈信息”按钮,提供出现问题的。

    待楼主反馈
    2022-10-10
    赞同
    回复 1
    • 张先生
      张先生
      2022-12-07
 
推荐文章
酷酷的羊肉串  ·  在canvas中根据鼠标的位置,获取当前点的RGB值_取canvas某个点颜色
1 月前
粗眉毛的薯片  ·  像素操作 - Web API | MDN
1 月前
开心的炒饭  ·  使用window.open()打开新窗口时携带数据(较长数据)_ 浏览器对url长度限制 _ 不同编码方式 - 字符与字节对应关系不同_window["filter"]-CSDN博客
1 年前
迷茫的煎鸡蛋  ·  用electron打包前端应用初体验 - 知乎
2 年前
正直的番茄  ·  如何将Drawable转换为位图?
2 年前
拉风的闹钟  ·  wpf 关于 已多次设置属性content 的报错_苦荞米的博客-CSDN博客
2 年前
听话的棒棒糖  ·  java - Getting android.app.ForegroundServiceStartNotAllowedException in Android 12 (SDK 31) - Stack Overflow
2 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号