From e96c5023821c43c26993086de3a12eaf65a9d6d1 Mon Sep 17 00:00:00 2001 From: ZhangXianQiang <1135831638@qq.com> Date: 星期四, 18 四月 2024 18:05:11 +0800 Subject: [PATCH] Merge branch 'dev-threejs' --- src/views/screen/components/screen-map-three/experience/index.js | 6 src/views/screen/components/screen-data/index.vue | 6 src/views/screen/components/screen-map-three/experience/utils/sizes.js | 44 +++++----- vue.config.js | 3 src/views/screen/components/screen-map-three/experience/world/enviroment.js | 2 src/views/screen/components/screen-wrapper/index.vue | 4 src/views/screen/components/screen-map-three/index.vue | 17 ++++ src/views/screen/index.vue | 4 + src/views/screen/components/screen-map-three/experience/renderer.js | 2 src/views/screen/components/screen-map-three/experience/world/map.js | 116 +++++++++++++++++++++++++++- 10 files changed, 164 insertions(+), 40 deletions(-) diff --git a/src/views/screen/components/screen-data/index.vue b/src/views/screen/components/screen-data/index.vue index 300142c..86a6679 100644 --- a/src/views/screen/components/screen-data/index.vue +++ b/src/views/screen/components/screen-data/index.vue @@ -67,7 +67,7 @@ grid: { top: '10%', right: 0, - bottom: '15%', + bottom: '17%', }, legend: { right: 0, @@ -170,8 +170,8 @@ margin: 10px 0; .panel-item { - width: 120px; - height: 120px; + width: 110px; + height: 110px; } } </style> \ No newline at end of file diff --git a/src/views/screen/components/screen-map-three/experience/index.js b/src/views/screen/components/screen-map-three/experience/index.js index edc482f..8dd4eb2 100644 --- a/src/views/screen/components/screen-map-three/experience/index.js +++ b/src/views/screen/components/screen-map-three/experience/index.js @@ -12,15 +12,15 @@ export default class Experience { constructor(canvas) { this.canvas = canvas; - this.sizes = new Sizes(); + this.sizes = new Sizes(this.canvas); this.time = new Time(); this.scene = new Scene(); this.camera = new Camera(this); this.renderer = new Renderer(this); this.world = new World(this); - // const size = 200; - // const divisions = 200; + // const size = 100; + // const divisions = 100; // const gridHelper = new GridHelper(size, divisions); // this.scene.add(gridHelper); diff --git a/src/views/screen/components/screen-map-three/experience/renderer.js b/src/views/screen/components/screen-map-three/experience/renderer.js index 725c396..e75b135 100644 --- a/src/views/screen/components/screen-map-three/experience/renderer.js +++ b/src/views/screen/components/screen-map-three/experience/renderer.js @@ -14,7 +14,7 @@ canvas: this.canvas, antialias: true, alpha: true, - // logarithmicDepthBuffer: true + logarithmicDepthBuffer: true }); // this.instance.toneMapping = THREE.CineonToneMapping; // this.instance.toneMappingExposure = 1.75; diff --git a/src/views/screen/components/screen-map-three/experience/utils/sizes.js b/src/views/screen/components/screen-map-three/experience/utils/sizes.js index af7c98d..2c3aa9b 100644 --- a/src/views/screen/components/screen-map-three/experience/utils/sizes.js +++ b/src/views/screen/components/screen-map-three/experience/utils/sizes.js @@ -3,31 +3,33 @@ */ import EventEmitter from './eventEmitter'; export default class Sizes extends EventEmitter { - constructor() { + constructor(canvas) { super(); - this.width = document.body.clientWidth; - this.height = document.body.clientHeight; - this.device = document.body.clientWidth <= 968 ? 'mobile' : 'pc'; - // 璁惧鍍忕礌 + this.container = document.querySelector('.map-container'); this.pixelRatio = Math.min(window.devicePixelRatio, 2); + this.width = this.container.offsetWidth; + this.height = this.container.offsetHeight; + this.device = document.body.clientWidth <= 968 ? 'mobile' : 'pc'; + // this.resizeObserver = new ResizeObserver(entries => { + // let rect = canvas.getBoundingClientRect(); + // this.scaleX = rect.width / this.width; + // this.scaleY = rect.height / this.height; + // console.log(this.scaleX, this.scaleY); + // }) + // this.resizeObserver.observe(this.container); // 瀹介珮鍙樺寲 - window.addEventListener('resize', () => { - // this.width = window.innerWidth; - // this.height = window.innerHeight; + // window.addEventListener('resize', () => { + // this.pixelRatio = Math.min(window.devicePixelRatio, 2); + // this.trigger('resize'); - this.width = document.body.clientWidth; - this.height = document.body.clientHeight; - this.pixelRatio = Math.min(window.devicePixelRatio, 2); - this.trigger('resize'); - - if(this.width < 968 && this.device !== 'mobile') { - this.device = 'mobile'; - this.trigger('devicechange'); - } else if(this.width >= 968 && this.device !== 'pc') { - this.device = 'pc'; - this.trigger('devicechange'); - } - }); + // if (this.width < 968 && this.device !== 'mobile') { + // this.device = 'mobile'; + // this.trigger('devicechange'); + // } else if (this.width >= 968 && this.device !== 'pc') { + // this.device = 'pc'; + // this.trigger('devicechange'); + // } + // }); } } \ No newline at end of file diff --git a/src/views/screen/components/screen-map-three/experience/world/enviroment.js b/src/views/screen/components/screen-map-three/experience/world/enviroment.js index 6af5286..f648da6 100644 --- a/src/views/screen/components/screen-map-three/experience/world/enviroment.js +++ b/src/views/screen/components/screen-map-three/experience/world/enviroment.js @@ -17,7 +17,7 @@ this.setBackground(); this.setCirclePoint(); - this.debuger(); + // this.debuger(); } setSunLight() { // 骞宠鍏�1 diff --git a/src/views/screen/components/screen-map-three/experience/world/map.js b/src/views/screen/components/screen-map-three/experience/world/map.js index ab8c988..2d2a299 100644 --- a/src/views/screen/components/screen-map-three/experience/world/map.js +++ b/src/views/screen/components/screen-map-three/experience/world/map.js @@ -4,18 +4,28 @@ import textureMapImage from '@/assets/map/texture/gz-map.jpg'; import textureMapFxImage from '@/assets/map/texture/gz-map-fx.jpg'; + +import gsap from 'gsap'; + // 鍦板浘娣卞害 const MAP_DEPTH = 0.2; const projection = d3.geoMercator().center([104.779307, 29.33924]).translate([0, 0, 0]); + +const raycaster = new THREE.Raycaster(); + export default class Map { constructor(experience) { this.experience = experience; this.scene = this.experience.scene; - this.material = null; + this.camera = this.experience.camera; + this.provinceMeshList = []; this.textureLoader = new THREE.TextureLoader(); this.setTexture(); this.operationData(mapData); + setTimeout(() => { + this.enterAnimation(); + }, 500); } setTexture() { const textureMap = this.textureLoader.load(textureMapImage); @@ -47,8 +57,8 @@ * @param {*} jsondata 鍦板浘鏁版嵁 */ operationData(jsondata) { + this.map = new THREE.Group(); - this.map = new THREE.Object3D(); // geo淇℃伅 const features = jsondata.features; features.forEach((feature) => { @@ -59,13 +69,13 @@ // 澶氫釜鎯呭喌 // console.log(feature.geometry.type); if (feature.geometry.type === "MultiPolygon") { - console.log(feature.geometry.coordinates); feature.geometry.coordinates.forEach((coordinate) => { coordinate.forEach((rows) => { const line = this.drawBoundary(rows); const mesh = this.drawExtrudeMesh(rows); province.add(line); province.add(mesh); + this.provinceMeshList.push(mesh); }); }); } @@ -77,16 +87,18 @@ const mesh = this.drawExtrudeMesh(coordinate); province.add(line); province.add(mesh); + this.provinceMeshList.push(mesh); }); } + province.isHover = false; this.map.add(province); }); this.map.position.set(1, 1, -1.5); - this.map.scale.set(10, 10, 10); + this.map.scale.set(10, 10, 1); this.map.rotation.set(THREE.MathUtils.degToRad(-90), 0, THREE.MathUtils.degToRad(20)); - this.container = new THREE.Object3D(); - this.container.add(this.map); - this.scene.add(this.container); + this.scene.add(this.map); + + this.setMouseEvent(); } /** @@ -136,4 +148,94 @@ this.sideMaterial, ]); } + + + setMouseEvent() { + this.mouseEvent = this.handleEvent.bind(this); + this.experience.canvas.addEventListener("mousemove", this.mouseEvent); + } + + removeMouseEvent() { + this.experience.canvas.removeEventListener("mousemove", this.mouseEvent); + } + + handleEvent(e) { + // console.log(this); + // return; + if (this.map) { + let mouse = new THREE.Vector2(); + let getBoundingClientRect = this.experience.canvas.getBoundingClientRect(); + let x = ((e.clientX - getBoundingClientRect.left) / getBoundingClientRect.width) * 2 - 1; + let y = -((e.clientY - getBoundingClientRect.top) / getBoundingClientRect.height) * 2 + 1; + mouse.x = x; + mouse.y = y; + + raycaster.setFromCamera(mouse, this.camera.instance); + + let intersects = raycaster.intersectObjects(this.provinceMeshList, false); + + if (intersects.length) { + let temp = intersects[0].object; + this.animation(temp.parent); + } else { + this.animation(); + } + } + } + + throttle(callback, delay) { + let lastCall = 0; + return function () { + let now = new Date().getTime(); + if (now - lastCall >= delay) { + lastCall = now; + callback.apply(null, arguments); + } + }; + } + + animation(province) { + if (province) { + if (!province.isHover) { + province.isHover = true; + this.map.children.forEach((item) => { + if (item.properties === province.properties) { + gsap.to(province.position, { + z: 0.12, + duration: 0.6 + }) + } else { + this.resetAnimation(item); + } + }) + } + } else { + this.resetAllAnimation(); + } + + } + + resetAnimation(province) { + gsap.to(province.position, { + z: 0, + duration: 0.6, + onComplete: () => { + province.isHover = false; + } + }) + } + + resetAllAnimation() { + this.map.children.forEach((item) => { + this.resetAnimation(item); + }) + } + + enterAnimation() { + gsap.to(this.map.scale, { + z: 10, + duration: 0.6, + ease: 'power1.out' + }) + } } \ No newline at end of file diff --git a/src/views/screen/components/screen-map-three/index.vue b/src/views/screen/components/screen-map-three/index.vue index a117a58..af189c1 100644 --- a/src/views/screen/components/screen-map-three/index.vue +++ b/src/views/screen/components/screen-map-three/index.vue @@ -9,8 +9,23 @@ let world = null; export default { name: 'ScreenMapThree', + props: { + loadEnd: { + type: Boolean, + default: false + }, + }, + watch: { + loadEnd: { + handler(newVal) { + console.log(newVal); + if(newVal) { + world = new Experience(this.$refs.worldContainer); + } + } + } + }, mounted() { - world = new Experience(this.$refs.worldContainer); } } </script> diff --git a/src/views/screen/components/screen-wrapper/index.vue b/src/views/screen/components/screen-wrapper/index.vue index 680c6d1..a6e27e1 100644 --- a/src/views/screen/components/screen-wrapper/index.vue +++ b/src/views/screen/components/screen-wrapper/index.vue @@ -5,7 +5,7 @@ 杩斿洖 </div> <div class="wrapper-content"> - <screen-map-three></screen-map-three> + <screen-map-three :loadEnd="isEnd"></screen-map-three> <div class="left-container wrapper"> <screen-face class="enter-left" :class="{ 'animate-enter-x': isEnd }"></screen-face> <screen-car class="enter-left animate-delay-1" :class="{ 'animate-enter-x': isEnd }"></screen-car> @@ -51,7 +51,7 @@ }, data() { return { - isEnd: false + isEnd: false, } }, methods: { diff --git a/src/views/screen/index.vue b/src/views/screen/index.vue index 4e8cf80..2d85420 100644 --- a/src/views/screen/index.vue +++ b/src/views/screen/index.vue @@ -30,6 +30,10 @@ </script> <style lang="scss" scoped> +.screen-container { + user-select: none; + -webkit-user-select: none; +} .screen { background: url('../../assets/images/screen/pageBg1.jpg') !important; background-size: cover !important; diff --git a/vue.config.js b/vue.config.js index 0dae064..022ec47 100644 --- a/vue.config.js +++ b/vue.config.js @@ -35,7 +35,8 @@ proxy: { // detail: https://cli.vuejs.org/config/#devserver-proxy [process.env.VUE_APP_BASE_API]: { - target: `http://localhost:8080`, + // target: `http://localhost:8080`, + target: `http://192.168.3.87:8080`, changeOrigin: true, pathRewrite: { ['^' + process.env.VUE_APP_BASE_API]: '' -- Gitblit v1.8.0