Vue.js2+Cesium1.103.0 十、加载 Three.js

news2024/11/24 5:57:55

Vue.js2+Cesium1.103.0 十、加载 Three.js

Demo

ThreeModel.vue

<template>
  <div
    id="three_container"
    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: {},
  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: {
    async init() {
      const _this = this
      const element = document.getElementById('three_container')
      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(600, 600)
      // 渲染器开启阴影效果
      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(
        'model/Cesium_Air.glb',
        gltf => {
          gltf.scene.name = 'Cesium_Air'
          gltf.scene.scale.set(20, 20, 20) //  设置模型大小缩放
          gltf.scene.position.set(0, 0, 0)
          gltf.scene.translateY(0)
          _this.modelMixer = new THREE.AnimationMixer(gltf.scene)
          _this.modelClock = new THREE.Clock()
          // 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.modelAnimationAction2 = _this.modelMixer.clipAction(
            gltf.animations[1]
          )
          _this.modelAnimationAction2.timeScale = 1
          // _this.modelAnimationAction2.loop = THREE.LoopOnce // 播放一次
          _this.modelAnimationAction2.clampWhenFinished = true
          _this.scene.add(gltf.scene)
          _this.model = gltf.scene
        },
        _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>

<style lang="scss" scoped>
.three_container {
  position: absolute;
  z-index: 999;
  top: 50%;
  left: 50%;
  width: 600px;
  height: 600px;
  transform: translateX(-50%) translateY(-50%);
  overflow: hidden;
}
</style>

index.vue

<template>
  <div
    id="cesium-container"
    style="width: 100%; height: 100%;"
  >
    <div style="position: absolute;right: 50px;top: 100px;z-index: 9;">
      <div>
        <button @click="handlePlay('play')">播放动画</button>
        <button @click="handlePlay('reverse')">播放动画(反)</button>
        <button @click="handlePlay('paused')">暂停</button>
        <button @click="handlePlay('stop')">停止动画</button>
      </div>
      <div>
        <button @click="handlePlay2('play')">播放动画</button>
        <button @click="handlePlay2('stop')">停止动画</button>
      </div>
    </div>
    <ThreeModel ref="ThreeModel" />
  </div>
</template>

<script>
/* eslint-disable no-undef */
/* eslint-disable no-caller */
/* eslint-disable eqeqeq */
import ThreeModel from './components/ThreeModel.vue'

export default {
  components: {
    ThreeModel
  },
  data() {
    return {
      paused: false
    }
  },
  computed: {},
  watch: {},
  mounted() {
    window.$InitMap()
  },
  methods: {
    handlePlay2(val) {
      if (val === 'play') {
        this.$refs.ThreeModel.modelAnimationAction2.play()
      } else if (val === 'stop') {
        this.$refs.ThreeModel.modelAnimationAction2.stop()
      }
    },
    handlePlay(val) {
      if (val === 'play') {
        this.$refs.ThreeModel.modelAnimationAction.paused = true
        this.$refs.ThreeModel.modelAnimationAction.timeScale = 1
        this.$refs.ThreeModel.modelAnimationAction.paused = false
        this.$refs.ThreeModel.modelAnimationAction.play()
      } else if (val === 'reverse') {
        this.$refs.ThreeModel.modelAnimationAction.paused = true
        this.$refs.ThreeModel.modelAnimationAction.timeScale = -1
        this.$refs.ThreeModel.modelAnimationAction.paused = false
        this.$refs.ThreeModel.modelAnimationAction.play()
      } else if (val === 'paused') {
        this.paused = !this.paused
        this.$refs.ThreeModel.modelAnimationAction.paused = this.paused
      } else if (val === 'stop') {
        this.$refs.ThreeModel.modelAnimationAction.stop()
      }
    }
  }
}
</script>

<style lang="scss">
.btns_container {
  position: absolute;
  z-index: 9;
  color: #fff;
  padding: 20px;
  width: 100%;
  box-sizing: border-box;
  bottom: 100px;
  left: 0;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/868609.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python爬虫-抓取的目标数据为#x开头,怎么解决?

前言 本文是该专栏的第4篇,后面会持续分享python爬虫案例干货,记得关注。 在做爬虫项目的时候,有时候抓取的平台目标数据为&#x开头,如下图所示: 浏览器显示的正常数据,但通过爬虫协议获取到的网页源码数据却是以&#x开头的隐藏数据,遇到这种情况,爬虫需要怎么处…

基于扩频的数字视频水印嵌入和检测算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ................................................................. for j 1:length(attens…

Google FixMatch:SOTA 在半监督学习基准测试中的性能

作为当前计算机视觉应用的首选&#xff0c;深度网络通常通过监督学习&#xff08;一种需要标记数据集的方法&#xff09;来实现其强大的性能。尽管人工智能多年来取得了许多成就和进步&#xff0c;但标记数据的关键任务仍然落在人类专家身上。他们很难满足那些数据饥渴的深度网…

智慧工地管理平台源码,Spring Cloud +Vue+UniApp框架开发

智慧工地源码 智慧工地云平台源码 智慧建筑源码 互联网建筑工地&#xff0c;是将互联网的理念和技术引入建筑工地&#xff0c;从施工现场源头抓起&#xff0c;最大程度的收集人员、安全、环境、材料等关键业务数据&#xff0c;依托物联网、互联网&#xff0c;建立云端大数据管…

【C++】透过STL源码深度剖析及模拟实现vector

鉴于读者的响应&#xff0c;打算将文章拆分一下&#xff0c;方便观看&#xff0c;基本接口可看 深入浅出STL之vector类 一、源码引入 以下我所介绍的都是基于【SGI】版本的STL&#xff0c;对源码有兴趣的同学可以去看看 侯捷老师的《STL源码剖析》 然后呢我们就去调出【vector…

引用.so库,JNI使用方法

1、先将.so库放在libs下&#xff1a; 2、在工程模块下 的build.gradle配置&#xff1a; android的defaultConfig配置 不同的系统平台看项目需要 3、生成与so库中c文件的jni方法的一样包名的实体类以及方法 如C文件暴露的方法&#xff1a; 生成的类和包名对应为&#xff1a; …

Python-OpenCV中的图像处理-模板匹配

Python-OpenCV中的图像处理-模板匹配 模板匹配单对象的模板匹配多对象的模板匹配 模板匹配 使用模板匹配可以在一幅图像中查找目标函数&#xff1a; cv2.matchTemplate()&#xff0c; cv2.minMaxLoc()模板匹配是用来在一副大图中搜寻查找模版图像位置的方法。 OpenCV 为我们提…

Fast SAM与YOLOV8检测模型一起使用实现实例分割

Fast SAM与YOLOV8检测模型一起使用 部分源代码在结尾处可获取 晓理紫 1 使用场景 实例分割数据集的获取要比检测数据的获取更加困难&#xff0c;在已有检测模型不想从新标注分割数据进行训练但是又想获取相关物体的mask信息以便从像素级别对物体进行操作&#xff0c;这时就可以…

【JavaEE进阶】SpringBoot项目的创建

文章目录 一. SpringBoot简介1. 什么是SpringBoot?2. SpringBoot的优点 二. SpringBoot项目创建1. 使用IDEA创建2. 使用网页创建SpringBoot项目 三. 运行SpringBoot项目 一. SpringBoot简介 1. 什么是SpringBoot? Spring Boot 是一个用于快速构建基于 Spring 框架的应用程序…

使用 PyTorch 逐步检测单个对象

一、说明 在对象检测任务中&#xff0c;我们希望找到图像中对象的位置。我们可以搜索一种类型的对象&#xff08;单对象检测&#xff0c;如本教程所示&#xff09;或多个对象&#xff08;多对象检测&#xff09;。通常&#xff0c;我们使用边界框定义对象的位置。有几种方法可以…

概率论与数理统计:第四章:随机变量的数字特征

文章目录 Ch4. 随机变量的数字特征1. 数学期望E(X)(1)数学期望的概念1.离散型①一维离散型随机变量X的数学期望&#xff1a; E X EX EX②一维离散型随机变量的函数的期望&#xff1a; E [ g ( X ) ] E[g(X)] E[g(X)]③二维离散型随机变量的函数的期望&#xff1a; E [ g ( X , …

基于CentOS 7 部署社区版Haproxy

HAProxy是法国开发者 威利塔罗(Willy Tarreau) 在2000年使用C语言开发的一个开源软件&#xff0c;是一款具 备高并发(一万以上)、高性能的TCP和HTTP负载均衡器&#xff0c;支持基于cookie的持久性&#xff0c;自动故障切换&#xff0c;支 持正则表达式及web状态统计。 目录 1…

23款奔驰AMG GT50升级原厂香氛负离子系统,清香宜人,久闻不腻

奔驰原厂香氛合理性可通过车内空气调节组件营造芳香四溢的怡人氛围。通过更换手套箱内香氛喷雾发生器所用的香水瓶&#xff0c;可轻松选择其他香氛。香氛的浓度和持续时间可调。淡雅的香氛缓缓喷出&#xff0c;并且在关闭后能够立刻散去。车内气味不会永久改变&#xff0c;香氛…

nacos原理

不要纠结于具体代码&#xff0c;随着版本变化源码多变&#xff0c;要学习的是基本原理和思想&#xff1b; Nacos注册中心实现原理分析 Nacos架构图 其中分为这么几个模块&#xff1a; Provider APP&#xff1a;服务提供者。 Consumer APP&#xff1a;服务消费者。 Name Serv…

MiniPaint:在线图像编辑利器【在线PS】

MiniPaint在线图像编辑器使用 HTML5 实现图像的在线创建与编辑&#xff0c;在线PS&#xff0c;支持超过40种效果滤镜&#xff0c;无需本地安装&#xff0c;在很多应用场景中可以替代PhotopShop等传统软件。 访问地址&#xff1a;MiniPaint - 在线PS - 在线图像编辑。 1、打开图…

iOS- git对单个或者多个文件权限设置,使用pre-commit hook 和shell脚本,拦截校验

前提&#xff1a;最近&#xff0c;由于团队代码规范和安全问题&#xff0c;有一些文件只能是指定用户才能修改。 对比&#xff1a;调查了一下资料&#xff0c;发现好多人都在使用pre-commit技术。于是&#xff0c;就朝着这个方向去研究。于是抽空写了脚本&#xff0c;在提交的…

DOS、CMD、PowerShell、Shell 与 Windows (类Unix)Terminal 的区别

在计算机历史的演进中&#xff0c;命令行界面&#xff08;CLI&#xff09;始终是一个核心组件&#xff0c;它为用户提供了与计算机系统直接交互的能力。从早期的文本界面到现代的终端&#xff0c;命令行工具已经经历了长足的发展。 本文将深入探讨DOS、CMD、PowerShell、Shell和…

【Unity实战系列】Unity的下载安装以及汉化教程

君兮_的个人主页 即使走的再远&#xff0c;也勿忘启程时的初心 C/C 游戏开发 Hello,米娜桑们&#xff0c;这里是君兮_&#xff0c;怎么说呢&#xff0c;其实这才是我以后真正想写想做的东西&#xff0c;虽然才刚开始&#xff0c;但好歹&#xff0c;我总算是启程了。今天要分享…

阿里云Linux服务器安装FTP站点全流程

阿里云百科分享使用阿里云服务器安装FTP全教程&#xff0c;vsftpd&#xff08;very secure FTP daemon&#xff09;是Linux下的一款小巧轻快、安全易用的FTP服务器软件。本教程介绍如何在Linux实例上安装并配置vsftpd。 目录 前提条件 步骤一&#xff1a;安装vsftpd 步骤二…

Js小数运算精度缺失的解决方法

项目场景&#xff1a; 提示&#xff1a;项目需求截图&#xff1a; 问题描述 众所周知Js做运算时0.10.2不等于0.3,目前项目需要计算关于金额的选项&#xff0c;涉及到金额保留后两位。保单欠款是根据用户输入的保单应收和保单欠款自动计算的。 原因分析&#xff1a; 产生浮点数…