npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

threejs-run

v1.1.11

Published

threejs-run

Readme

简介

前端快速开发3D模型应用。

快速开始

npm i threejs-run -S

快速应用

全局注入
import ThreejsRun from 'threejs-run';
app.use(ThreejsRun);
局部注入
import { ThreeNormal, ThreeGltf, ThreeGltfOperate } from 'threejs-run';

常规用法

// 需引入
import { ThreeNormal } from 'threejs-run';

构造

参数 | 类型 | 必填项 | 默认值 | 参考值 | 说明 ---- | ----- | ------ | ------ | ------ | :------ T | Object | √ | | | THREE。import * as THREE from 'three'; that | Object | √ | | | 页面的this。 dom | Object | √ | | | 模型元素。 scene_W | Number | √ | | | 模型元素宽。 scene_H | Number | √ | | | 模型元素高。 tools | Object | √ | | {OrbitControls, GLTFLoader} | 工具,外部注入需要使用的控件。

方法

参数 | 说明 ---- | :------ init({ initCamera, initLight, initControls, initWebGLRenderer, initMaterial, windowResize }) | 初始化模型。 cleanThree() | 清除THREE资源释放内存。 initClick(event, dom, materialClickChange) | 初始化射线,构建模型点击。

init方法

参数 | 类型 | 必填项 | 默认值 | 参考值 | 说明 ---- | ----- | ------ | ------ | ------ | :------ initCamera | Function | × | | | 初始化相机。可覆盖原生方法。 initLight | Function | × | | | 初始化灯光。 initControls | Function | × | | | 初始化控制器,用于控制器的操作。 initWebGLRenderer | Function | × | | | 初始化渲染器WebGLRenderer。 initMaterial | Function | × | | | 初始化素材,用于素材的操作。 windowResize | Function | × | | | 重写浏览器大小变化的控制函数。

cleanThree方法

beforeUnmount() {
  // 清除THREE资源释放内存
  this.threeD.cleanThree();
},
注:该方法会印象系统原本打开的window.onresize监听。调用该方法后window.onresize会失效,需重新开启监听。

initClick方法

参数 | 类型 | 必填项 | 默认值 | 参考值 | 说明 ---- | ----- | ------ | ------ | ------ | :------ event | Object | √ | | | event; dom | Object | √ | | | 模型元素。 materialClickChange | Function | √ | | | 处理点击的素材的回调方法;

示例

<template>
  <div id="app">
    <div class="three" ref="webglBox" id="webgl" style="width: 100%; height: 100%;"></div>
  </div>
</template>
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
import { ThreeNormal } from 'threejs-run';

export default {
  data() {
    return {
      // 3D的实体
      threeD: null,
      scene_W: 0,
      scene_H: 0,
    };
  },
  mounted() {
    this.init();
  },
  methods: {
    init() {
      this.$nextTick(() => {
        // 获取3D加载元素的dom
        const dom = document.getElementById('webgl');
        // width和height用来设置Three.js输出的Canvas画布尺寸(像素px)
        this.scene_W = this.$refs.webglBox.offsetWidth; //宽度
        this.scene_H = this.$refs.webglBox.offsetHeight; //高度
        // new一个3D类
        this.threeD = new ThreeNormal(THREE, this, dom, this.scene_W, this.scene_H, {
          OrbitControls
        });
        // 初始化
        this.threeD.init({
          initMaterial: (scene) => {
            // 创建坐标轴线段的几何体
            const axesHelper = new THREE.AxesHelper(50); // 参数为长度
            scene.add(axesHelper);
            const geometry = new THREE.BoxGeometry( 1, 1, 1 );
            const material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
            const cube = new THREE.Mesh( geometry, material );
            scene.add( cube );
          }
        });
      });
    },
  }
};

GLTF用法

该模块变更了引入,由原来的ThreeI, ThreeO,变更为ThreeGltf, ThreeGltfOperate。

构造

参数 | 类型 | 必填项 | 默认值 | 参考值 | 说明 ---- | ----- | ------ | ------ | ------ | :------ T | Object | √ | | | THREE。import * as THREE from 'three'; that | Object | √ | | | 页面的this。 dom | Object | √ | | | 模型元素。 url | Object | √ | | | 模型文件的基础地址,资源放置在静态目录,vue3的目录为public。 scene_W | Number | √ | | | 模型元素宽。 scene_H | Number | √ | | | 模型元素高。

url参数

参数 | 类型 | 必填项 | 默认值 | 参考值 | 说明 ---- | ----- | ------ | ------ | ------ | :------ baseUrl | String | √ | | | import.meta.env.BASE_URL。前端根目录。 gltfUrl | String | √ | | | 模型文件地址:'3d/mx.glb'。 dracoUrl | String | √ | | | 构造器文件地址:'draco/'。

方法

参数 | 说明 ---- | :------ init({ GLTFLoader, DRACOLoader, OrbitControls, initCamera, initMaterial }) | 初始化模型。 cleanThree() | 清除THREE资源释放内存。 initClick(event, dom, materialClickChange) | 初始化射线,构建模型点击。

init方法

参数 | 类型 | 必填项 | 默认值 | 参考值 | 说明 ---- | ----- | ------ | ------ | ------ | :------ GLTFLoader | Object | √ | | | GLTF加载器。import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; DRACOLoader | Object | √ | | | 解码器。import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader"; OrbitControls | Object | √ | | | 相机控件轨道控制器。import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; initCamera | Function | × | | | 初始化相机。可覆盖原生方法。; initMaterial | Function | × | | | 初始化素材,用于素材的操作。 windowResize | Function | × | | | 重写浏览器大小变化的控制函数。

cleanThree方法

beforeUnmount() {
  // 清除THREE资源释放内存
  this.threeD.cleanThree();
},
注:该方法会印象系统原本打开的window.onresize监听。调用该方法后window.onresize会失效,需重新开启监听。

initClick方法

参数 | 类型 | 必填项 | 默认值 | 参考值 | 说明 ---- | ----- | ------ | ------ | ------ | :------ event | Object | √ | | | event; dom | Object | √ | | | 模型元素。 materialClickChange | Function | √ | | | 处理点击的素材的回调方法;

示例

<template>
  <div id="app">
    <div class="three" ref="webglBox" id="webgl" style="width: 100%; height: 100%;"></div>
  </div>
</template>
import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
import { ThreeGltf } from 'threejs-run';

export default {
  data() {
    return {
      // 3D的实体
      threeD: null,
      scene_W: 0,
      scene_H: 0,
      // 点击监听函数
      threeDMousedown: null,
    };
  },
  beforeUnmount() {
    window.removeEventListener('mousedown', this.threeDMousedown);
  },
  activated() {
    if (this.threeDMousedown !== null) {
      window.addEventListener("mousedown", this.threeDMousedown, false);
    }
  },
  deactivated() {
    window.removeEventListener('mousedown', this.threeDMousedown);
  },
  mounted() {
    this.init();
  },
  methods: {
    // 初始化
    init() {
      this.$nextTick(() => {
        // 获取3D加载元素的dom
        const dom = document.getElementById('webgl');
        // width和height用来设置Three.js输出的Canvas画布尺寸(像素px)
        this.scene_W = this.$refs.webglBox.offsetWidth; //宽度
        this.scene_H = this.$refs.webglBox.offsetHeight; //高度
        // new一个3D类
        this.threeD = new ThreeGltf(THREE, this, dom, {
          baseUrl: import.meta.env.BASE_URL,
          gltfUrl: '3d/test.glb',
          dracoUrl: 'draco/',
        }, this.scene_W, this.scene_H);
        // 初始化
        this.threeD.init({GLTFLoader, DRACOLoader, OrbitControls,
          initCamera: () => {
            // console.log(this.scene_W, this.scene_H);
            // 30:视场角度, width / height:Canvas画布宽高比, 1:近裁截面, 3000:远裁截面
            this.threeD.camera = new THREE.PerspectiveCamera(17, this.scene_W / this.scene_H, 1, 1000);
            // 根据需要设置相机位置具体值
            // this.camera.position.set(0, 0, 0);
            this.threeD.camera.position.set(this.scene_W/8, this.scene_W/15, 0);
            //相机观察目标指向Threejs 3D空间中某个位置
            // this.camera.lookAt(0, 0, 0);//指向mesh对应的位置
            this.threeD.camera.lookAt(new THREE.Vector3( 0, 0, 0 ));//指向mesh对应的位置
          },
          initMaterial: (gltf) => {
            // 递归遍历所有模型节点批量修改材质
            gltf.scene.traverse( ( child ) => {});
          }
        });
        // 增加点击监听
        this.threeDMousedown = event => this.threeD.initClick(event, dom,
          // 处理点击的素材
          (raycaster) => {
            // 射线交叉计算拾取模型
            const intersects = raycaster.intersectObjects(this.material.list);
            if (intersects.length > 0) {
              // 处理点击事件
              // intersects[0] 包含了第一个交点
              const child = intersects[0].object;
              // 隐藏的素材不触发点击事件
              if (!child.visible) {
                return
              }
              // .....
            }
          }
        )
        window.addEventListener("mousedown", this.threeDMousedown, false);
      });
    },
  }
};