Newer
Older
KaiFengPC / src / views / sponeScreen / projectHM / gongchenkanbani_comp / modalSJ.vue
@zhangdeliang zhangdeliang on 17 Jul 4 KB udpate
<template>
  <!-- 项目模型实景管理 -->
  <div class="projectModalM">
    <div id="QuanJing" ref="threeDom"></div>
  </div>
</template>

<script setup>
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'; //控制器
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'; // gltf加载器
import gsap from 'gsap';
import { CSSRulePlugin } from 'gsap/CSSRulePlugin';

const { proxy } = getCurrentInstance();
gsap.registerPlugin(CSSRulePlugin); // 引入css插件,完成某些css动画

const AllData = ref({
  show: false,
  numer: '0%',
  imgUrl: '/threeModal/baoGH.JPG',
  imgWidth: 1200,
  imgHeight: 560,
});
// 初始化模型
const Scene = new THREE.Scene();
const Camera = new THREE.PerspectiveCamera(30, AllData.value.imgWidth / AllData.value.imgHeight, 0.1, 5000);
const Renderer = new THREE.WebGLRenderer({
  antialias: true,
  alpha: true, //开启alpha
});
// 控制器
const Controls = new OrbitControls(Camera, Renderer.domElement);
//gltfLoader
const Gltfloader = new GLTFLoader();
// 注意:此处为threejs的DOM,需要将threejs的场景渲染进去
const threeDom = ref();

// 首页进入相机的视角,这个视角可以在三维模型中建立一个摄像机获取摄像机的坐标,如C4D,非常准确.
const cameraPosition = {
  x: 500,
  y: 400,
  z: -200,
};
const cameraLookat = {
  x: 0,
  y: 0,
  z: 0,
};
// 声明一个方法传入参数可以在不同的地方调用相机
const cameraReset = (position, lookAt, time = 1) => {
  gsap.to(Camera.position, {
    x: position.x,
    y: position.y,
    z: position.z,
    duration: time,
    ease: 'power4.out',
    // onComplete: function () {
    // 这是相机运动完成的回调,可以执行其他的方法.
    // }
  });
  gsap.to(Camera.lookAt, {
    x: lookAt.x,
    y: lookAt.y,
    z: lookAt.z,
    duration: time,
    ease: 'power4.out',
  });
  gsap.to(Camera.target, {
    x: lookAt.x,
    y: lookAt.y,
    z: lookAt.z,
    duration: time,
    ease: 'power4.out',
  });
};
// Scene.add(skyBox);

const initThreeScene = () => {
  // 使动画循环使用时阻尼或自转 意思是否有惯性
  Controls.enableDamping = true;
  // 动态阻尼系数 就是鼠标拖拽旋转灵敏度
  Controls.dampingFactor = 0.1;
  // 是否可以旋转
  Controls.enableRotate = true;
  // 是否可以缩放与速度
  Controls.enableZoom = true;
  // 设置相机距离原点的最远距离
  // Controls.minDistance = 1;
  // 设置相机距离原点的最远距离
  Controls.maxDistance = 900;
  Controls.autoRotate = true;
  Controls.autoRotateSpeed = 1.0;

  // 是否开启右键拖拽
  Controls.enablePan = false;
  // Controls.addEventListener("change", render);
  //render的相关设置
  // Renderer.setPixelRatio(window.devicePixelRatio);
  Renderer.setSize(AllData.value.imgWidth, AllData.value.imgHeight);
  Renderer.inputEncoding = true;
  // Renderer.outputEncoding = THREE.sRGBEncoding;
  // Renderer.setClearColor(0xd0d0d0, 1);
  // 将renderer渲染进DOM里面
  threeDom.value.appendChild(Renderer.domElement);
};
// 设置页面自适应
const onWindowResize = () => {
  Camera.aspect = AllData.value.imgWidth / AllData.value.imgHeight;
  Camera.updateProjectionMatrix();
  Renderer.setSize(AllData.value.imgWidth, AllData.value.imgHeight);
};
window.addEventListener('resize', onWindowResize, false);
//  完成以上步骤基本的场景已经配置完成

cameraReset(cameraPosition, cameraLookat);

const Render = () => {
  requestAnimationFrame(Render);
  Controls.update(); // 轨道控制器的更新
  Renderer.clear(); // 清除画布
  Renderer.render(Scene, Camera);
};

let event = {};
// 单张纹理图的加载
event.onLoad = function () {
  console.log('图片加载完成');
  AllData.value.show = false;
};
event.onProgress = function (url, num, total) {
  console.log('图片加载完成:', url);
  console.log('图片加载进度:', num);
  console.log('图片总数:', total);
  let value = ((num / total) * 100).toFixed(2) + '%';
  console.log('加载进度的百分比:', value);
  AllData.value.numer = value;
};
event.onError = function (e) {
  console.log('图片加载出现错误');
  console.log(e);
  AllData.value.show = false;
};

// 设置加载管理器
const loadingManager = new THREE.LoadingManager(event.onLoad, event.onProgress, event.onError);
const textureLoader = new THREE.TextureLoader(loadingManager);
var material = new THREE.MeshBasicMaterial(); //材质
var texture = textureLoader.load(AllData.value.imgUrl);
material.map = texture;
// var skyBox = new THREE.Mesh(new THREE.SphereBufferGeometry(600, 600, 600), material);
var skyBox = new THREE.Mesh(new THREE.SphereGeometry(600, 600, 600), material);

skyBox.geometry.scale(1, 1, -1);
Scene.add(skyBox);

onMounted(() => {
  initThreeScene();
  Render();
});
</script>

<style lang="scss" scoped>
.projectModalM {
  #QuanJing {
    width: 100%;
    height: 100%;
  }
}
</style>