src/views/screen/components/screen-data/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/screen/components/screen-map-three/experience/index.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/screen/components/screen-map-three/experience/renderer.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/screen/components/screen-map-three/experience/utils/sizes.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/screen/components/screen-map-three/experience/world/enviroment.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/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
vue.config.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
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> 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/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; 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/enviroment.js
@@ -17,7 +17,7 @@ this.setBackground(); this.setCirclePoint(); this.debuger(); // this.debuger(); } setSunLight() { // 平行光1 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' }) } } 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: { 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; 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]: ''