【愚公系列】2022年09月 微信小程序-three.js绘制多维旋转正方体

举报
愚公搬代码 发表于 2022/09/30 22:34:19 2022/09/30
【摘要】 前言Three.js 是一款运行在浏览器中的 3D 引擎,你可以用它创建各种三维场景,包括了摄影机、光影、材质等各种对象。一个典型的 Three.js 程序至少要包括渲染器(Renderer)、场景(Scene)、照相机(Camera),以及你在场景中创建的物体。Three.js相关文档:http://docs.thingjs.com/ 一、Three.js的使用安装第三方包:npm i ...

前言

Three.js 是一款运行在浏览器中的 3D 引擎,你可以用它创建各种三维场景,包括了摄影机、光影、材质等各种对象。

一个典型的 Three.js 程序至少要包括渲染器(Renderer)、场景(Scene)、照相机(Camera),以及你在场景中创建的物体。

Three.js相关文档:http://docs.thingjs.com/
在这里插入图片描述

一、Three.js的使用

安装第三方包:npm i --save threejs-miniprogram

1.多维旋转正方体的绘制

<view style="display:inline-block;">
  <button size="mini" type="primary" class="btn" data-action="Walking" bindtap="play"></button>
  <button size="mini" type="primary" class="btn"  data-action="WalkJump" bindtap="play"></button>
  <button size="mini" type="primary" class="btn"  data-action="Sitting" bindtap="play"></button>
  <button size="mini" type="primary" class="btn"  data-action="Standing" bindtap="play"></button>
</view>
<canvas
  type="webgl"
  id="webgl"
  style="width: 100%; height: 450px;"
  bindtouchstart="touchStart"
  bindtouchmove="touchMove"
  bindtouchend="touchEnd"
></canvas>
import { createScopedThreejs } from 'threejs-miniprogram'

const { renderCubes } = require('../../../lib/test-cases/cubes')

const app = getApp()

Page({
  data: {},
  onLoad: function () {
    wx.createSelectorQuery()
      .select('#webgl')
      .node()
      .exec((res) => {
        const canvas = res[0].node
        this.canvas = canvas
        const THREE = createScopedThreejs(canvas)
        
        renderCubes(canvas, THREE)
      })
  },
  play(e){
    let action = e.currentTarget.dataset.action
    this.fadeToAction(action)
  },
  touchStart(e) {
    this.canvas.dispatchTouchEvent({...e, type:'touchstart'})
  },
  touchMove(e) {
    this.canvas.dispatchTouchEvent({...e, type:'touchmove'})
  },
  touchEnd(e) {
    this.canvas.dispatchTouchEvent({...e, type:'touchend'})
  }
})

二、多维旋转正方体相关js文件

export function renderCubes(canvas, THREE) {
  var container, stats;
  var camera, scene, raycaster, renderer;
  var mouse = new THREE.Vector2(), INTERSECTED;
  var radius = 100, theta = 0;
  init();
  animate();
  function init() {
    camera = new THREE.PerspectiveCamera(70, canvas.width / canvas.height, 1, 10000);
    scene = new THREE.Scene();
    scene.background = new THREE.Color(0xf0f0f0);
    var light = new THREE.DirectionalLight(0xffffff, 1);
    light.position.set(1, 1, 1).normalize();
    scene.add(light);
    var geometry = new THREE.BoxBufferGeometry(20, 20, 20);
    for (var i = 0; i < 2000; i++) {
      var object = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({ color: Math.random() * 0xffffff }));
      object.position.x = Math.random() * 800 - 400;
      object.position.y = Math.random() * 800 - 400;
      object.position.z = Math.random() * 800 - 400;
      object.rotation.x = Math.random() * 2 * Math.PI;
      object.rotation.y = Math.random() * 2 * Math.PI;
      object.rotation.z = Math.random() * 2 * Math.PI;
      object.scale.x = Math.random() + 0.5;
      object.scale.y = Math.random() + 0.5;
      object.scale.z = Math.random() + 0.5;
      scene.add(object);
    }
    raycaster = new THREE.Raycaster();
    renderer = new THREE.WebGLRenderer();
    renderer.setPixelRatio(wx.getSystemInfoSync().pixelRatio);
    renderer.setSize(canvas.width, canvas.height);
  }
  function animate() {
    canvas.requestAnimationFrame(animate);
    render();
  }
  function render() {
    theta += 0.5;
    camera.position.x = radius * Math.sin(THREE.Math.degToRad(theta));
    camera.position.y = radius * Math.sin(THREE.Math.degToRad(theta));
    camera.position.z = radius * Math.cos(THREE.Math.degToRad(theta));
    camera.lookAt(scene.position);
    camera.updateMatrixWorld();
    // find intersections
    raycaster.setFromCamera(mouse, camera);
    var intersects = raycaster.intersectObjects(scene.children);
    if (intersects.length > 0) {
      if (INTERSECTED != intersects[0].object) {
        if (INTERSECTED) INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex);
        INTERSECTED = intersects[0].object;
        INTERSECTED.currentHex = INTERSECTED.material.emissive.getHex();
        INTERSECTED.material.emissive.setHex(0xff0000);
      }
    } else {
      if (INTERSECTED) INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex);
      INTERSECTED = null;
    }
    renderer.render(scene, camera);
  }
}

三、效果图

在这里插入图片描述

四、总结

three.js画一个图形主要经历如下八个步骤:

  • 1.创建透视相机
  • 2.创建场景
  • 3.创建光源
  • 4.构造辅助网格
  • 5.创建加载器,加载模型文件
  • 6.创建渲染器,渲染场景
  • 7.创建控制器
  • 8.循环渲染场景
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。