three.js实现酷炫散点模型

简介: three.js实现酷炫散点模型

1.效果图展示


由于文件大小限制,仅能展示少部分特效,本文中共7中变换,如球体,立方体,管道,波浪,反重力,重力等效果。

bf71f20327ec48dabe69ac4a64d14c8d.gif

image.gif

8d71a27463ce4a38b3b91553ce54a9c9.png

2.功能


项目需求是基于数据库分析出来的离散相关性的散点图,主要是为了追求良好的展示效果。

使用了three.js编写的。我是用的vue2,源码放在最后。

3.使用步骤


第一步


网上找到three.js源码,放到public目录下,在index.html中引入

public/index.html中的body中放入以下代码
<script type="text/javascript">
      document.write(
        unescape("%3Cscript src='./static/js/three.js'%3E%3C/script%3E")
      );
 </script>

第二步


将文章末尾的实现以上功能的源码放入项目中(任意位置)

第三步


在.vue文件中使用

<template>
  <div class="demo">
    <div id="ff3"></div>
  </div>
</template>
<script>
const fd = () => {
  setTimeout(() => {
    import('./main02')
  }, 100)
}
export default {
  inject: ['reload'],
  data () {
    return {
    }
  },
  mounted () {
    fd()
  },
  beforeDestroy () {
    this.$router.go(0)
  }
}
</script>

至此,完成,如果需要three.js源码的可以留言邮箱。

4.使用技巧说明


4.1.控制球的数量


image.png

4.2 控制外围网格的形状


image.png

4.3 控制初始的形态


image.png

4.4 让其停止切换


image.png

4.5 设置切换每种形态的顺序


image.png

4.6 控制切换动画的种类


image.png

4.7 控制镜头的位移


image.png

4.8 控制镜头的方向(和上面不要混淆,这个不是位移是方向)


image.png

暂时就想到这些,three.js的使用不想正经写代码,他是有着固定的结构,只需修修改改即可。如有问题可评论区交流

源码:


var _createClass = function () {function defineProperties(target, props) {for (var i = 0; i < props.length; i++) {var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);}}return function (Constructor, protoProps, staticProps) {if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;};}();function _classCallCheck(instance, Constructor) {if (!(instance instanceof Constructor)) {throw new TypeError("Cannot call a class as a function");}}var Roxik = function () {
  function Roxik() {_classCallCheck(this, Roxik);
    this.models = [];
    this.initialize();
    this.animate();
  }_createClass(Roxik, [{ key: "initialize", value: function initialize()
    {
      this.initializeEngine();
      this.initializeCamera();
      this.initializeLights();
      this.initializeMaterials();
      this.initializeObjects();
      this.initializeFilters();
      this.initializeListeners();
    } }, { key: "initializeEngine", value: function initializeEngine()
    {
      this.scene = new THREE.Scene();
      this.scene.background = new THREE.Color(0xfefefe);
      this.renderer = new THREE.WebGLRenderer({ antialias: true });
      this.renderer.setSize(window.innerWidth, window.innerHeight);
      document.body.appendChild(this.renderer.domElement);
    } }, { key: "initializeCamera", value: function initializeCamera()
    {
      this.camera = new THREE.PerspectiveCamera(
      55,
      window.innerWidth / window.innerHeight,
      0.001,
      1000);
      this.camera.position.x = 2;
      this.camera.position.y = 2;
      this.camera.position.z = -2;
      this.cameraController = new CameraController();
      this.cameraController.camera = this.camera;
    } }, { key: "initializeLights", value: function initializeLights()
    {
      this.ambientLight = new THREE.DirectionalLight(0x9090aa);
      this.ambientLight.position.set(-10, 10, -10).normalize();
      this.scene.add(this.ambientLight);
      var light = new THREE.HemisphereLight(0xffffff, 0x444444);
      light.position.set(1, 1, 1);
      this.scene.add(light);
    } }, { key: "initializeMaterials", value: function initializeMaterials()
    {
      var colors = [
      0x97350b,
      0x266ea5,
      0x00847f,
      0x2f818e,
      0x08917c,
      0x08917c,
      0x6b458c,
      0x7a4526];
      this.sphereMaterial = [];
      for (var i = 0; i < 8; i++) {
        var mat = new THREE.MeshLambertMaterial({ color: colors[i] });
        this.sphereMaterial.push(mat);
      }
      this.cubeMaterial = new THREE.MeshBasicMaterial({ color: 0xdddddd });
      this.cubeMaterial.wireframe = true;
    } }, { key: "initializeObjects", value: function initializeObjects()
    {
      var bet = 0.7;
      var offset = (8 - 1) * bet * 0.5;
      var geometry = new THREE.IcosahedronBufferGeometry(0.3, 2);
      for (var i = 0; i < 8; i++) {
        for (var j = 0; j < 8; j++) {
          for (var k = 0; k < 8; k++) {
            var m = this.sphereMaterial[Math.floor(Math.random() * 8)];
            var s = new THREE.Mesh(geometry, m);
            s.position.set(i * bet - offset, j * bet - offset, k * bet - offset);
            this.models.push(s);
            this.scene.add(s);
          }
        }
      }
      this.cube = new THREE.CubeGeometry(18, 18, 18, 4, 4, 4);
      this.cubeMesh = new THREE.Mesh(this.cube, this.cubeMaterial);
      this.scene.add(this.cubeMesh);
      this.cameraController.models = this.models;
      this.motionController = new MotionController();
      this.motionController.models = this.models;
      this.motionController.changeScene(this.motionController.CYLINDER);
    } }, { key: "initializeFilters", value: function initializeFilters()
    {} }, { key: "initializeListeners", value: function initializeListeners()
    {
      window.addEventListener("resize", this.updateDimensions.bind(this));
      document.addEventListener("keydown", this.keydownHandler.bind(this));
    } }, { key: "animate", value: function animate()
    {
      requestAnimationFrame(this.animate.bind(this));
      this.cameraController.step();
      this.motionController.step();
      this.renderer.render(this.scene, this.camera);
    } }, { key: "updateDimensions", value: function updateDimensions()
    {
      var width = window.innerWidth;
      var height = window.innerHeight;
      this.renderer.setSize(width, height);
      this.camera.aspect = width / height;
      this.camera.updateProjectionMatrix();
    } }, { key: "keydownHandler", value: function keydownHandler(
    event) {
      var keyCode = event.which;
      switch (keyCode) {
        case 49:
        case 97:
          this.motionController.changeScene(this.motionController.CYLINDER);
          break;
        case 50:
        case 98:
          this.motionController.changeScene(this.motionController.SPHERE);
          break;
        case 51:
        case 99:
          this.motionController.changeScene(this.motionController.CUBE);
          break;
        case 52:
        case 100:
          this.motionController.changeScene(this.motionController.TUBE);
          break;
        case 53:
        case 101:
          this.motionController.changeScene(this.motionController.WAVE);
          break;
        case 54:
        case 102:
          this.motionController.changeScene(this.motionController.GRAVITY);
          break;
        case 55:
        case 103:
          this.motionController.changeScene(this.motionController.ANTIGRAVITY);
          break;}
    } }]);return Roxik;}();var
CameraController = function () {
  function CameraController() {_classCallCheck(this, CameraController);
    this.camera = null;
    this.models = [];
    this.frame = 1000;
    this.sceneLimit = 90;
    this.tm;
    this.target = new THREE.Vector3(0, 0, 0);
    this.cs = 0;
    this.gy = 0;
    this.l = 0;
    this.bl = 6;
    this.ts = 0;
    this.r = 0;
    this.rp = 0.03;
  }_createClass(CameraController, [{ key: "step", value: function step()
    {
      if (++this.frame > this.sceneLimit) {
        this.frame = 0;
        this.sceneLimit = Math.floor(Math.random() * 60 + 30);
        this.tm = this.models[Math.floor(Math.random() * this.models.length)];
        this.ts = 0;
        this.cs = 0;
        this.gy = Math.random() * 8 - 4;
        this.rp = Math.random() * 0.06 - 0.03;
        this.bl = Math.random() * 4 + 7;
      }
      if (this.ts < 0.05) {
        this.ts += 0.005;
      }
      if (this.cs < 0.5) {
        this.cs += 0.005;
      }
      this.target.x += (this.tm.position.x - this.target.x) * this.ts;
      this.target.y += (this.tm.position.y - this.target.y) * this.ts;
      this.target.z += (this.tm.position.z - this.target.z) * this.ts;
      this.camera.lookAt(this.target);
      this.r += this.rp;
      this.l += (this.bl - this.l) * 0.1;
      this.camera.position.x +=
      (Math.cos(this.r) * this.l +
      this.tm.position.x -
      this.camera.position.x) *
      this.cs;
      this.camera.position.y +=
      (this.tm.position.y + this.gy - this.camera.position.y) * this.cs;
      this.camera.position.z +=
      (Math.sin(this.r) * this.l +
      this.tm.position.z -
      this.camera.position.z) *
      this.cs;
    } }]);return CameraController;}();var
MotionController = function () {
  function MotionController() {_classCallCheck(this, MotionController);
    this.CYLINDER = 0;
    this.SPHERE = 1;
    this.CUBE = 2;
    this.TUBE = 3;
    this.WAVE = 4;
    this.GRAVITY = 5;
    this.ANTIGRAVITY = 6;
    this.models = [];
    this.scene = this.CYLINDER;
    this.sceneLimit = 100;
    this.frame = 0;
    this.cutoff = 0;
    this.r = 0.0;
    this.r0 = 0.0;
    this.rp = 0.0;
    this.rl = 0.0;
  }_createClass(MotionController, [{ key: "changeScene", value: function changeScene(
    scene) {var limit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : -1;
      this.cutoff = 0;
      this.scene = scene;
      this.frame = 0;
      if (limit < 0) {
        this.sceneLimit = Math.floor(Math.random() * 140 + 3);
      } else {
        this.sceneLimit = limit;
      }
      switch (this.scene) {
        case this.CYLINDER:
          this.cylinder();
          break;
        case this.SPHERE:
          this.sphere();
          break;
        case this.CUBE:
          this.cube();
          break;
        case this.TUBE:
          this.tube();
          break;
        case this.WAVE:
          this.wave();
          break;
        case this.GRAVITY:
          this.gravity();
          break;
        case this.ANTIGRAVITY:
          this.antigravity();
          break;}
    } }, { key: "cylinder", value: function cylinder()
    {
      var n = 0;
      var r = Math.PI * 2 / this.models.length;
      var d = r * Math.floor(Math.random() * 40 + 1);
      for (var i = 0; i < this.models.length; i++) {
        var m = this.models[i];
        m.speed = 0;
        m.accel = Math.random() * 0.05 + 0.022;
        m.animate = false;
        m.dest = new THREE.Vector3();
        if (i < this.models.length - 50) {
          m.dest.x = Math.cos(n) * 4;
          m.dest.y = i * 0.008 - (this.models.length - 50) * 0.004;
          m.dest.z = Math.sin(n) * 4;
        } else {
          m.dest.x = Math.random() * 14 - 7;
          m.dest.y = Math.random() * 14 - 7;
          m.dest.z = Math.random() * 14 - 7;
        }
        n = n + d;
      }
    } }, { key: "sphere", value: function sphere()
    {
      var s = 0;
      var c = 0;
      var r = Math.PI * 2 / this.models.length;
      var d = r * Math.floor(Math.random() * 40 + 1);
      var d2 = Math.random() * 5 + 3;
      for (var i = 0; i < this.models.length; i++) {
        var m = this.models[i];
        m.speed = 0;
        m.accel = Math.random() * 0.05 + 0.022;
        m.animate = false;
        m.dest = new THREE.Vector3();
        var d1 = Math.cos(s) * d2;
        if (Math.random() > 0.06) {
          m.dest.x = Math.cos(c) * d1;
          m.dest.y = Math.sin(s) * d2;
          m.dest.z = Math.sin(c) * d1;
        } else {
          m.dest.x = Math.random() * 7 - 7;
          m.dest.y = Math.random() * 7 - 7;
          m.dest.z = Math.random() * 7 - 7;
        }
        s = s + r;
        c = c + d;
      }
    } }, { key: "cube", value: function cube()
    {
      var a = Math.random() * 0.05 + 0.022;
      var n = 0;
      var l = 1;
      while (true) {
        if (l * l * l > this.models.length) {
          l--;
          break;
        }
        l++;
      }
      for (var i = 0; i < l; i++) {
        for (var j = 0; j < l; j++) {
          for (var k = 0; k < l; k++) {
            var m = this.models[n++];
            m.speed = 0;
            m.accel = a;
            m.animate = false;
            m.dest = new THREE.Vector3();
            m.dest.x = i * 0.8 + -(l - 1) * 0.8 * 0.5;
            m.dest.y = j * 0.8 + -(l - 1) * 0.8 * 0.5;
            m.dest.z = k * 0.8 + -(l - 1) * 0.8 * 0.5;
          }
        }
      }
    } }, { key: "tube", value: function tube()
    {
      var a = Math.random() * 0.05 + 0.022;
      var v = 0.02 + Math.random() * 0.025;
      var dx = -v * this.models.length * 0.44;
      var d = 1.2 + Math.random() * 1;
      for (var i = 0; i < this.models.length; i++) {
        var m = this.models[i];
        m.speed = 0;
        m.accel = a;
        m.animate = false;
        m.dest = new THREE.Vector3();
        if (Math.random() > 0.05) {
          m.dest.x = i * v + dx;
          m.dest.y = Math.random() * d - d * 0.5;
          m.dest.z = Math.random() * d - d * 0.5;
        } else {
          m.dest.x = Math.random() * 14 - 7;
          m.dest.y = Math.random() * 14 - 7;
          m.dest.z = Math.random() * 14 - 7;
        }
      }
    } }, { key: "wave", value: function wave()
    {
      var a = Math.random() * 0.05 + 0.022;
      var n = 0;
      var l = Math.floor(Math.sqrt(this.models.length));
      var d = -(l - 1) * 0.55 * 0.5;
      var r = 0;
      var t = Math.random() * 0.3 + 0.05;
      var s = Math.random() * 1 + 1;
      this.r = 0;
      this.r0 = 0;
      this.rl = Math.random() * 1 + 1;
      this.rp = Math.random() * 0.3 + 0.1;
      for (var i = 0; i < l; i++) {
        var ty = Math.cos(r) * s;
        r += t;
        for (var j = 0; j < l; j++) {
          n += 1;
          var m = this.models[n - 1];
          m.speed = 0;
          m.accel = a;
          m.animate = false;
          m.dest = new THREE.Vector3();
          m.dir = new THREE.Vector3();
          m.dir.x = m.dir.y = m.dir.z = 0;
          m.dest.x = i * 0.55 + d;
          m.dest.y = ty;
          m.dest.z = j * 0.55 + d;
        }
      }
      while (n < this.models.length) {
        var m = this.models[n];
        m.speed = 0;
        m.accel = a;
        m.animate = false;
        m.dest = new THREE.Vector3();
        m.dest.x = Math.random() * 14 - 7;
        m.dest.y = Math.random() * 14 - 7;
        m.dest.z = Math.random() * 14 - 7;
        n++;
      }
    } }, { key: "gravity", value: function gravity()
    {
      this.sceneLimit = 60;
      for (var i = 0; i < this.models.length; i++) {
        var m = this.models[i];
        m.dir = new THREE.Vector3();
        m.speed = 0;
        m.accel = 0.5;
        m.animate = false;
        m.dir.y = Math.random() * -0.2;
      }
    } }, { key: "antigravity", value: function antigravity()
    {
      for (var i = 0; i < this.models.length; i++) {
        var m = this.models[i];
        m.speed = 0;
        m.accel = 0.5;
        m.animate = false;
        m.dir = new THREE.Vector3();
        m.dir.x = Math.random() * 0.25 - 0.125;
        m.dir.y = Math.random() * 0.25 - 0.125;
        m.dir.z = Math.random() * 0.25 - 0.125;
      }
    } }, { key: "step", value: function step()
    {
      var m = null;
      switch (this.scene) {
        case this.CYLINDER:
        case this.SPHERE:
        case this.CUBE:
        case this.TUBE:
          for (var i = 0; i < this.cutoff; i++) {
            m = this.models[i];
            if (!m.animate) {
              if (m.speed < 0.8) {
                m.speed = m.speed + m.accel;
              }
              var c0 = m.dest.x - m.position.x;
              var c1 = m.dest.y - m.position.y;
              var c2 = m.dest.z - m.position.z;
              m.position.x = m.position.x + c0 * m.speed;
              m.position.y = m.position.y + c1 * m.speed;
              m.position.z = m.position.z + c2 * m.speed;
              if (
              Math.abs(c0) < 0.05 &&
              Math.abs(c1) < 0.05 &&
              Math.abs(c2) < 0.05)
              {
                m.animate = true;
                m.position.x = m.dest.x;
                m.position.y = m.dest.y;
                m.position.z = m.dest.z;
              }
            }
          }
          var _maxp = Math.floor(this.models.length / 40);
          this.cutoff += _maxp;
          if (this.cutoff > this.models.length) this.cutoff = this.models.length;
          break;
        case this.WAVE:
          var cos = 0;
          var max = Math.floor(Math.sqrt(this.models.length));
          var cc = 0;
          for (var _i = 0; _i < max; _i++) {
            cos = Math.cos(this.r) * this.rl;
            this.r = this.r + this.rp;
            for (var j = 0; j < max; j++) {
              m = this.models[cc++];
              m.dest.y = cos;
            }
          }
          this.r0 += 0.11;
          this.r = this.r0;
          for (var _i2 = 0; _i2 < this.cutoff; _i2++) {
            m = this.models[_i2];
            if (m.speed < 0.5) {
              m.speed += m.accel;
            }
            m.position.x = m.position.x + (m.dest.x - m.position.x) * m.speed;
            m.position.y = m.position.y + (m.dest.y - m.position.y) * m.speed;
            m.position.z = m.position.z + (m.dest.z - m.position.z) * m.speed;
          }
          var _maxp = Math.floor(this.models.length / 40);
          this.cutoff += _maxp;
          if (this.cutoff > this.models.length) this.cutoff = this.models.length;
          break;
        case this.GRAVITY:
          for (var _i3 = 0; _i3 < this.models.length; _i3++) {
            m = this.models[_i3];
            m.position.y = m.position.y + m.dir.y;
            m.dir.y = m.dir.y - 0.06;
            if (m.position.y < -9) {
              m.position.y = -9;
              m.dir.y = m.dir.y * -m.accel;
              m.accel = m.accel * 0.9;
            }
          }
          break;
        case this.ANTIGRAVITY:
          for (var _i4 = 0; _i4 < this.cutoff; _i4++) {
            m = this.models[_i4];
            m.position.x = m.position.x + m.dir.x;
            m.position.y = m.position.y + m.dir.y;
            m.position.z = m.position.z + m.dir.z;
          }
          this.cutoff += 30;
          if (this.cutoff > this.models.length) this.cutoff = this.models.length;
          break;}
      if (++this.frame > this.sceneLimit)
      this.changeScene(Math.floor(Math.random() * 7));
    } }]);return MotionController;}();
var roxik = new Roxik();


相关文章
|
3天前
|
JavaScript 前端开发
深入理解Node.js中的异步编程模型
【10月更文挑战第39天】在Node.js的世界里,异步编程是核心所在,它如同自然界的水流,悄无声息却又无处不在。本文将带你探索Node.js中异步编程的概念、实践以及如何优雅地处理它,让你的代码像大自然的流水一样顺畅和高效。
|
1月前
|
Web App开发 JavaScript 前端开发
深入理解Node.js事件循环和异步编程模型
【10月更文挑战第9天】在JavaScript和Node.js中,事件循环和异步编程是实现高性能并发处理的基石。本文通过浅显易懂的语言和实际代码示例,带你一探究竟,了解事件循环的工作原理及其对Node.js异步编程的影响。从基础概念到实际应用,我们将一步步解锁Node.js背后的魔法,让你的后端开发技能更上一层楼!
|
2月前
|
JavaScript 前端开发 数据库
探索Node.js中的异步编程模型
【9月更文挑战第23天】在Node.js的世界里,异步编程是核心的魔法,它让这个平台能够处理高并发请求。本文将带你深入理解Node.js的异步编程模型,通过代码示例和直观的解释,我们将一起揭开异步编程的面纱。
47 16
|
1月前
|
Web App开发 JavaScript 前端开发
JavaScript Window - 浏览器对象模型
JavaScript Window - 浏览器对象模型
22 2
|
2月前
|
Web App开发 JavaScript 前端开发
探索Node.js中的异步编程模型
【9月更文挑战第21天】在现代Web开发中,Node.js以其非阻塞I/O和事件驱动的特性成为热门选择。本文将深入探讨Node.js的异步编程模型,揭示其背后的原理,并通过示例代码展示如何高效利用异步特性来处理并发任务。
|
2月前
|
JavaScript 前端开发 API
探索Node.js中的异步编程模型
【9月更文挑战第11天】在JavaScript的运行环境中,Node.js因其高效的异步处理能力而备受青睐。本文将深入浅出地介绍Node.js如何处理异步操作,包括回调函数、Promises和async/await等概念,并探讨它们对后端开发的意义。
45 5
|
3月前
|
JavaScript 前端开发
js之DOM 文档对象模型
js之DOM 文档对象模型
22 1
js之DOM 文档对象模型
|
3月前
|
机器学习/深度学习 存储 前端开发
实战揭秘:如何借助TensorFlow.js的强大力量,轻松将高效能的机器学习模型无缝集成到Web浏览器中,从而打造智能化的前端应用并优化用户体验
【8月更文挑战第31天】将机器学习模型集成到Web应用中,可让用户在浏览器内体验智能化功能。TensorFlow.js作为在客户端浏览器中运行的库,提供了强大支持。本文通过问答形式详细介绍如何使用TensorFlow.js将机器学习模型带入Web浏览器,并通过具体示例代码展示最佳实践。首先,需在HTML文件中引入TensorFlow.js库;接着,可通过加载预训练模型如MobileNet实现图像分类;然后,编写代码处理图像识别并显示结果;此外,还介绍了如何训练自定义模型及优化模型性能的方法,包括模型量化、剪枝和压缩等。
51 1
|
3月前
|
JavaScript 前端开发
JavaScript BOM 的概念(浏览器对象模型)
JavaScript BOM 的概念(浏览器对象模型)
47 1
|
3月前
|
编解码 缓存 算法
Three.js如何降低3D模型的大小以便更快加载
为加快600MB的3D模型在Three.js中的加载速度,可采用多种压缩方法:1) 减少顶点数,使用简化工具或LOD技术;2) 压缩纹理,降低分辨率或转为KTX2等格式;3) 采用高效文件格式如glTF 2.0及draco压缩;4) 合并材质减少数量;5) 利用Three.js内置优化如BufferGeometry;6) 按需分批加载模型;7) Web Workers后台处理;8) 多模型合并减少绘制;9) 使用Texture Atlas及专业优化工具。示例代码展示了使用GLTFLoader加载优化后的模型。
396 12