src/views/screen/components/screen-map-three/experience/index.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/screen/components/screen-map-three/experience/utils/sizes.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/screen/components/screen-map-three/experience/world/map.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/screen/components/screen-map-three/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/screen/components/screen-wrapper/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
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); 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'); // } // }); } } src/views/screen/components/screen-map-three/experience/world/map.js
@@ -4,7 +4,7 @@ import textureMapImage from '@/assets/map/texture/gz-map.jpg'; import textureMapFxImage from '@/assets/map/texture/gz-map-fx.jpg'; import { BufferGeometryUtils } from 'three/examples/jsm/utils/BufferGeometryUtils.js'; import { mergeGeometries } from 'three/examples/jsm/utils/BufferGeometryUtils.js'; import gsap from 'gsap'; // 地图深度 @@ -19,10 +19,11 @@ this.experience = experience; this.scene = this.experience.scene; this.camera = this.experience.camera; this.material = null; this.provinceMeshList = []; this.textureLoader = new THREE.TextureLoader(); this.setTexture(); this.operationData(mapData); this.setLineHelper(); } setTexture() { const textureMap = this.textureLoader.load(textureMapImage); @@ -54,8 +55,8 @@ * @param {*} jsondata 地图数据 */ operationData(jsondata) { this.map = new THREE.Group(); this.map = new THREE.Object3D(); // geo信息 const features = jsondata.features; features.forEach((feature) => { @@ -72,6 +73,7 @@ const mesh = this.drawExtrudeMesh(rows); province.add(line); province.add(mesh); this.provinceMeshList.push(mesh); }); }); } @@ -83,18 +85,17 @@ const mesh = this.drawExtrudeMesh(coordinate); province.add(line); province.add(mesh); this.provinceMeshList.push(mesh); }); } // 合并成一个mesh // const mergedGeometry = BufferGeometryUtils.mergeGeometries(province.children); // 合并mesh // const mergedGeometry = mergeGeometries(province.children,true); province.isHover = false; this.map.add(province); }); this.map.position.set(1, 1, -1.5); this.map.scale.set(10, 10, 10); 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.map); console.log(this.map); this.setMouseEvent(); @@ -163,19 +164,22 @@ // console.log(this); // return; if (this.map) { const mouse = new THREE.Vector2(); mouse.x = (e.clientX / window.innerWidth) * 2 - 1; mouse.y = -(e.clientY / window.innerHeight) * 2 + 1; 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); const intersects = raycaster.intersectObjects(this.map.children, true); let intersects = raycaster.intersectObjects(this.provinceMeshList, false); if (intersects.length) { intersects.forEach((item) => { if (item.object) if (item.object.meshName === 'province') { console.log(item.object); this.animation(item.object); } }); let temp = intersects[0].object; this.animation(temp.parent); } else { this.animation(); } } } @@ -191,7 +195,69 @@ }; } animation(mesh) { console.log(mesh); 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); }) } setLineHelper() { const material = new THREE.LineBasicMaterial({ color: 0x0000ff }); const points = []; points.push(new THREE.Vector3(0, 0, 0)); points.push(new THREE.Vector3(0, 0, 0)); const geometry = new THREE.BufferGeometry().setFromPoints(points); this.lineHelper = new THREE.Line(geometry, material); console.log(this.lineHelper); this.scene.add(this.lineHelper); } updateLine(raycaster) { let pointArray = new Float32Array([ raycaster.ray.origin.x, raycaster.ray.origin.y, raycaster.ray.origin.z, raycaster.ray.direction.x, raycaster.ray.direction.y, raycaster.ray.direction.z, ]) this.lineHelper.geometry.attributes.position.array = pointArray; this.lineHelper.geometry.attributes.position.needsUpdate = true; } } 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> 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: {