Vue.js2+Cesium1.103.0 十一、Three.js 炸裂效果

这篇具有很好参考价值的文章主要介绍了Vue.js2+Cesium1.103.0 十一、Three.js 炸裂效果。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Vue.js2+Cesium1.103.0 十一、Three.js 炸裂效果

Vue.js2+Cesium1.103.0 十一、Three.js 炸裂效果,javascript,vue.js,前端,gis

Vue.js2+Cesium1.103.0 十一、Three.js 炸裂效果,javascript,vue.js,前端,gis

Demo

ThreeModelBoom.vue

<template>
  <div
    :id="id"
    class="three_container"
  />
</template>

<script>
/* eslint-disable eqeqeq */
/* eslint-disable no-unused-vars */
/* eslint-disable no-undef */
/* eslint-disable no-caller */
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
// import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js'
// import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js'
export default {
  name: 'ThreeModel',
  props: {
    size: {
      type: Number,
      default: 20
    },
    url: {
      type: String,
      default: 'three_container'
    },
    id: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      modelMixer: null,
      modelClock: null,
      modelAnimationAction: null,
      modelAnimationAction2: null,
      model: null,
      scene: null,
      camera: null,
      renderer: null,
      textureLoader: null,
      groupBox: null,
      control: null,
      enableRotate: null
    }
  },
  computed: {},
  watch: {},
  mounted() {
    window.cancelAnimationFrame(this.clearAnim)
    this.init()
  },
  beforeDestroy() {
    window.cancelAnimationFrame(this.clearAnim)
  },
  methods: {
    applyScalar(scalar) {
      if (!this.model) {
        return
      }
      this.model.traverse(function (value) {
        if (!value.isMesh || !value.worldDir) return
        // 爆炸公式
        value.position.copy(
          new THREE.Vector3()
            .copy(value.userData.oldPs)
            .add(
              new THREE.Vector3().copy(value.worldDir).multiplyScalar(scalar)
            )
        )
      })
    },
    async init() {
      const _this = this
      const element = document.getElementById(this.id)
      const width = element.clientWidth // 窗口宽度
      const height = element.clientHeight // 窗口高度
      // 场景
      this.scene = new THREE.Scene()
      // this.scene.background = new THREE.Color(0x000000, 0)
      this.scene.background = null

      // 相机
      const k = width / height // 窗口宽高比
      const s = 400 // 三维场景显示范围控制系数,系数越大,显示的范围越大
      // this.camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 1000) // 透视摄像机
      this.camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000) // 正交摄像机
      // 设置摄像机位置,相机方向逆X轴方向,倾斜向下看
      this.camera.position.set(0, 180, 360)
      // this.camera.rotation.order = 'YXZ'
      // 指向场景中心
      this.camera.lookAt(this.scene.position)

      // 渲染器
      this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true })
      // 设置环境
      this.renderer.setClearColor(0x000000, 0)
      // 设置场景大小
      this.renderer.setSize(800, 800)
      // 渲染器开启阴影效果
      this.renderer.shadowMap.enabled = true

      // 纹理加载器
      this.textureLoader = new THREE.TextureLoader()

      // 组合对象
      this.groupBox = new THREE.Group()

      // 坐标轴
      // const axes = new THREE.AxesHelper(1000)
      // this.scene.add(axes)

      // 点光源
      const point = new THREE.PointLight(0xffffff)
      point.position.set(500, 300, 400) // 点光源位置
      this.scene.add(point) // 点光源添加到场景中

      // 环境光
      const ambient = new THREE.AmbientLight(0xffffff, 0.8)
      this.scene.add(ambient)

      element.appendChild(this.renderer.domElement)

      // 相机控件
      this.control = new OrbitControls(this.camera, this.renderer.domElement)
      this.control.enableDamping = true
      // 动态阻尼系数 就是鼠标拖拽旋转灵敏度,阻尼越小越灵敏
      this.control.dampingFactor = 0.5
      // 是否可以缩放
      this.control.enableZoom = true
      // 是否自动旋转
      this.control.autoRotate = false
      // 设置相机距离原点的最近距离
      this.control.minDistance = 20
      // 设置相机距离原点的最远距离
      this.control.maxDistance = 1000
      // 是否开启右键拖拽
      this.control.enablePan = true
      // 上下翻转的最大角度
      this.control.maxPolarAngle = 1.5
      // 上下翻转的最小角度
      this.control.minPolarAngle = 0.0
      // 是否可以旋转
      this.enableRotate = true

      // 加载模型
      const loader = new GLTFLoader()
      await loader.load(
        this.url,
        gltf => {
          gltf.scene.name = 'Cesium_Air'
          gltf.scene.scale.set(_this.size, _this.size, _this.size) //  设置模型大小缩放
          gltf.scene.position.set(0, 0, 0)
          gltf.scene.translateY(0)
          _this.modelMixer = new THREE.AnimationMixer(gltf.scene)
          _this.modelClock = new THREE.Clock()
          if (gltf.animations.length > 0) {
            // http://www.yanhuangxueyuan.com/threejs/docs/index.html#api/zh/animation/AnimationAction
            _this.modelAnimationAction = _this.modelMixer.clipAction(
              gltf.animations[0]
            )
            _this.modelAnimationAction.timeScale = 1
            // _this.modelAnimationAction.loop = THREE.LoopOnce // 播放一次
            _this.modelAnimationAction.clampWhenFinished = true
          }
          _this.scene.add(gltf.scene)
          _this.model = gltf.scene

          // 模型包围盒
          const modelBox3 = new THREE.Box3()
          const meshBox3 = new THREE.Box3()

          // 获取模型的包围盒
          modelBox3.expandByObject(_this.model)
          // 计算模型的中心点坐标,这个为爆炸中心
          const modelWorldPs = new THREE.Vector3()
            .addVectors(modelBox3.max, modelBox3.min)
            .multiplyScalar(0.5)

          _this.model.traverse(function (value) {
            if (value.isMesh) {
              meshBox3.setFromObject(value)
              // 获取每个 mesh 的中心点,爆炸方向为爆炸中心点指向 mesh 中心点
              const worldPs = new THREE.Vector3()
                .addVectors(meshBox3.max, meshBox3.min)
                .multiplyScalar(0.5)
              if (isNaN(worldPs.x)) return
              // 计算爆炸方向
              value.worldDir = new THREE.Vector3()
                .subVectors(worldPs, modelWorldPs)
                .normalize()
              // 保存初始坐标
              value.userData.oldPs = value.getWorldPosition(new THREE.Vector3())
            }
          })
        },
        _xhr => {
          // console.log((_xhr.loaded / _xhr.total) * 100 + '% loaded')
        },
        _error => {
          // console.error(_error)
        }
      )

      const animate = () => {
        // 循环调用函数
        this.clearAnim = requestAnimationFrame(animate)
        // 更新相机控件
        this.control.update()
        // 渲染界面
        this.renderer.render(this.scene, this.camera)
        if (this.modelMixer) {
          // modelClock.getDelta() 方法获得两帧的时间间隔
          // 更新混合器相关的时间
          this.modelMixer.update(this.modelClock.getDelta())
        }
      }
      animate()
    }
  }
}
</script>


index.vue文章来源地址https://www.toymoban.com/news/detail-682062.html

<template>
  <div
    id="cesium-container"
    style="width: 100%; height: 100%;"
  >
    <div style="position: absolute;width: 400px;right: 50px;top: 100px;z-index: 9;">
      <div>
        <el-slider
          v-model="sliderVal"
          :min="0"
          :max="100"
          @input="handleChange"
        />
      </div>
    </div>
    <div class="model_container">
      <ThreeModel
        :id="'three_model_a'"
        ref="ThreeModelA"
        :url="'model/SnowyVillage.glb'"
        :size="5"
        class="three_model"
      />
    </div>
  </div>
</template>

<script>
import ThreeModel from './components/ThreeModelBoom.vue'

export default {
  components: {
    ThreeModel
  },
  data() {
    return {
      sliderVal: 0,
      paused: false
    }
  },
  computed: {},
  watch: {},
  mounted() {
    window.$InitMap()
  },
  methods: {
    handleChange(val) {
      this.$refs.ThreeModelA.applyScalar(val)
    }
  }
}
</script>

<style lang="scss">
.model_container {
  position: absolute;
  z-index: 999;
  left: 50%;
  top: 50%;
  transform: translateX(-50%) translateY(-50%);
  display: flex;
  .three_model {
    width: 800px;
    height: 800px;
  }
}
</style>

到了这里,关于Vue.js2+Cesium1.103.0 十一、Three.js 炸裂效果的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • python中import js2py报错:No module named ‘js2py‘

    这种错误的原因是没有安装js2py 安装js2py的方法步骤: 1.首先使用快捷键”Ctrl+R“运行打开任务栏; 2.在任务栏输入cmd,点击确定; 3.找到python的安装路径; 4.这是我的安装路径: 这是我的python安装路径 5.在命令提示符窗口中切换到该路径: 6.然后输入:pip install js2py,点击

    2023年04月08日
    浏览(24)
  • 【案例】3D地球(vue+three.js)

    需要下载插件 有人找不到合适的地球平面图的话,可直接地球平面图

    2024年02月06日
    浏览(28)
  • three.js实现点击事件(vue)

    1.加载模型(通过点击模型触发事件) 2.通过射线获取到事件源 (new THREE.Raycaster()和new THREE.Vector2()) 3.通过点击到该模型使用名字匹配 clickedObject.name==“xx” addEventListener监听事件触发 创建 Raycaster和Vector2 计算鼠标或触摸点的位置 (这里的event是通过事件监听获取) 更新射线

    2024年02月16日
    浏览(32)
  • Vue+Three.js建造3D小房子

    前言 一、Three.js简介 二、开发步骤 1.安装Three.js 2.创建容器 3.创建模型 总结 3D模型给人一种更真实的感受,带来极致的视觉体验。本文介绍Vue结合Three.js开发3D小房子,接触过OpenGL的小伙伴看起来会更轻松一点。 Three.js,一个WebGL引擎,基于JavaScript,可直接运行GPU驱动游戏与

    2024年02月07日
    浏览(26)
  • vue3项目中使用three.js

    在vue3项目中,通过three.js使用了一段短小但完整的代码实现了实际的三维效果图。 Three.js是一个轻量级,跨平台的Javascript库,可以在浏览器上结合HTML5的canvas,SVG或者WebGL,创建和展示3D模型和动画。 Three.js允许我们在不依赖任何浏览器插件的情况下,创建一个GPU加速的3D动画场

    2024年01月23日
    浏览(35)
  • three.js实现vr全景图(vue)

    方法: 可以利用Threejs中的立方体或者球体实现全景图功能,把立方体或球体当成天空盒子,将无缝衔接的图片贴上,看起来就像在一个场景中,相机一般放置在中央。 three.js中文网 1、立方体实现 立方体6个面要贴上6个方向的图片,这6个图片如下所示: 实现代码如下: 图片

    2024年02月12日
    浏览(29)
  • vue2+three.js实现宇宙(进阶版)

    2023.9.12今天我学习了vue2+three.js实现一个好看的动态效果: 首先是安装: npm install three 相关代码如下:

    2024年02月09日
    浏览(28)
  • vue 项目使用three.js 实现3D看房效果

    0.前言 该教程能帮助直接写出vue项目的3D看房效果!!! 先上效果图 1.安装依赖 2.vue代码 这里文件名为three.vue 代码非原创,出处 vue3+threejs实现全景看房 (异步加载 BOLLROOM 部件为对原代码的修改) 注意这里的hdr 文件必须要放在assets文件夹中,且要通过import模块的形式导入!

    2024年02月13日
    浏览(29)
  • mapbox在Vue框架中对three.js的应用

    在现代Web开发中,使用Vue框架和Three.js库可以创建出色的3D体验。然而,为了实现这样的效果,需要使用地图来提供场景的背景。在这种情况下,Mapbox是一个很好的选择,因为它提供了强大的地图API和工具,可以与Vue和Three.js无缝集成。 在本文中,我们将探讨如何在Vue框架中使

    2024年02月08日
    浏览(27)
  • 【Three.js】vue2导入pcd文件 PCDLoader

    a. TypeError: Cannot read properties of null (reading \\\'1\\\')     at parseHeader (PCDLoader.js?edd4:119:1)     at PCDLoader.parse (PCDLoader.js?edd4:226:1)     at Object.eval [as onLoad] (PCDLoader.js?edd4:34:1)     at XMLHttpRequest.eval (three.module.js?5a89:34770:1) b. GET http://localhost:8080/public/Zaghetto 404 (Not Found) 两者本质同个问题,

    2024年02月08日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包