diff --git a/public/light.png b/public/light.png deleted file mode 100644 index 07fa92d..0000000 Binary files a/public/light.png and /dev/null differ diff --git a/src/utils/inject.js b/src/utils/inject.js index f20b13a..a7443c2 100644 --- a/src/utils/inject.js +++ b/src/utils/inject.js @@ -41,7 +41,7 @@ window.$loadScript = (type = 'js', url, dom = "body") => { }; }); }; -window.$glob = {} +window.$glob = {token: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJoLXVzZXItaWQiOiIxODA4MDM2NzI3NzQzNDU1MjMyIiwiaC1yb2xlLWlkIjoiMTgwODAzNjg5NDQxMjUxMzI4MCIsImV4cCI6MTc1MTQ0NDg0MywibmJmIjoxNzE5OTA4ODQzfQ.Wi6wzArP79mFj3XEzSendOfWHJc1mNuSAlAC1W4zMzI"} window.$dicts = dicts window.$waitFor = (target, t = 500) => new Promise(resolve => { const interval = setInterval(() => { @@ -57,7 +57,7 @@ window.$waitFor = (target, t = 500) => new Promise(resolve => { }) Vue.prototype.$marketBoard = Vue.observable({ - search: {"groupCodeList": ["20001003"], "currentDate": "20240501", "compareDate": "20240430", "hourNum": "18"} + search: {"groupCodeList": ["20011061"], "currentDate": "20240701", "compareDate": "20240630", "hourNum": "18"} }) Vue.prototype.$multipleStoreBoard = Vue.observable({ search: {} diff --git a/src/views/AppThreeMap.vue b/src/views/AppThreeMap.vue index b8e7147..711a66d 100644 --- a/src/views/AppThreeMap.vue +++ b/src/views/AppThreeMap.vue @@ -4,9 +4,13 @@ export default { label: "3D地图", data() { return { - geoMap: null + geoMap: null, + layers: [{longitude: 113.631676, latitude: 34.766458}] } }, + computed: { + search: v => v.$marketBoard.search + }, methods: { loadLib() { const {$waitFor, THREE, $loadScript} = window @@ -15,10 +19,11 @@ export default { initMap() { const {THREE, d3, axios, TWEEN} = window const rootEl = this.$el + const root = this class GeoMap { constructor() { - this.cameraPosition = {x: 15, y: 5, z: 15}; // 相机位置 + this.cameraPosition = {x: 10, y: 0, z: 100}; // 相机位置 this.scene = null; // 场景 this.camera = null; // 相机 this.renderer = null; // 渲染器 @@ -33,7 +38,6 @@ export default { /** * @desc 初始化 * */ - init() { this.setScene(); this.setCamera(); @@ -43,8 +47,9 @@ export default { this.setControl(); this.makeGround(); this.getMap('http://10.0.97.209/blade-visual/map/data?id=1456'); + this.addMarkers() this.animat(); - this.bindMouseEvent(); + this.bindMouseEvent() } /** @@ -102,16 +107,24 @@ export default { data: features.properties, mercator: [] }; + const getLnglat = (arr, cb) => { + arr?.map(e => { + if (e.length > 2) { + getLnglat(e, cb) + } else if (e.length === 2) { + cb(e) + } + }) + } areaItems.forEach(function (item, areaIndex) { vector3json[featuresIndex].mercator[areaIndex] = []; - item.forEach(function (cp) { + getLnglat(item, cp => { const lnglat = that.lnglatToVector3(cp); const vector3 = new THREE.Vector3(lnglat[0], lnglat[1], lnglat[2]).multiplyScalar(1.2); vector3json[featuresIndex].mercator[areaIndex].push(vector3) }) }) }); - console.log(data) this.drawMap(vector3json) } @@ -131,22 +144,29 @@ export default { curveSegments: 1, bevelEnabled: false, }; + const canvas = document.createElement('canvas'); + canvas.width = 256; + canvas.height = 256; + const ctx = canvas.getContext('2d'); + + const gradient = ctx.createLinearGradient(0, 0, canvas.width, 0); + gradient.addColorStop(1, '#09E2F8'); // 起始颜色 + gradient.addColorStop(0, 'rgba(61,127,255,0.35)'); // 结束颜色 + ctx.fillStyle = gradient; + ctx.fillRect(0, 0, canvas.width, canvas.height); const blockMaterial = new THREE.MeshBasicMaterial({ - color: '#3700b1', - opacity: 0.7, - transparent: true, - wireframe: false + map: new THREE.CanvasTexture(canvas), + side: THREE.DoubleSide }); const blockSideMaterial = new THREE.MeshBasicMaterial({ - color: '#5923bc', + color: '#002240', opacity: 0.7, transparent: true, wireframe: false }); const lineMaterial = new THREE.LineBasicMaterial({ - color: '#9800ff' + color: '#97CAE6' }); - console.log(data) data.forEach(function (areaData) { let areaGroup = new THREE.Group(); areaGroup.name = 'area'; @@ -165,16 +185,22 @@ export default { lineMeshCp.position.z = 0.8; areaGroup.add(lineMesh); areaGroup.add(lineMeshCp); + console.log(lineMeshCp.position.x, lineMeshCp.position.y, lineMeshCp.position.z) // add mesh to meshList for mouseEvent that.meshList.push(mesh); }); - areaGroup.add(that.lightGroup(areaData)); - areaGroup.add(that.tipsSprite(areaData)); + // areaGroup.add(that.transLayer(areaData)); + // areaGroup.add(that.tipsSprite(areaData)); + areaGroup.scale.set(4, 4, 4) that.mapGroup.add(areaGroup); }); that.scene.add(that.mapGroup); } + addMarkers() { + root.layers.map(layer => this.scene.add(this.transLayer(layer))) + } + /** * @desc 移动相机 * */ @@ -207,7 +233,7 @@ export default { * */ lnglatToVector3(lnglat = []) { if (!this.projection) { - this.projection = d3.geoMercator().center([114.31, 34.80]).scale(100).translate([0, 0]); + this.projection = d3.geoMercator().center([113.665412, 34.757975]).scale(100).translate([0, 0]); } const [x, y] = this.projection([lnglat[0], lnglat[1]]) const z = 0; @@ -258,6 +284,7 @@ export default { * */ setControl() { this.controls = new THREE.OrbitControls(this.camera); + this.controls.enableRotate = false this.camera.position.set(this.cameraPosition.x, this.cameraPosition.y, this.cameraPosition.z); } @@ -317,12 +344,10 @@ export default { } function transiform(o, n, t) { - let e = new TWEEN.Tween(o) - .to(n, t) - .start(); + new TWEEN.Tween(o).to(n, t).start(); } - window.addEventListener('mousemove', onMouseMove, false); + // window.addEventListener('mousemove', onMouseMove, false); } /** @@ -337,7 +362,7 @@ export default { // map: maps, opacity: 1, transparent: true, - color: '#212121' + color: '#07193D' }); const geometry = new THREE.PlaneGeometry(100, 100, 1, 1); let ground = new THREE.Mesh(geometry, material); @@ -353,71 +378,22 @@ export default { * @desc 光柱 * */ - lightGroup(areaData) { - /*光柱*/ - const lightMapTexture = new THREE.TextureLoader().load('/light.png'); - lightMapTexture.repeat.set(1, 1); // 纹理 y,x方向重铺 - lightMapTexture.needsUpdate = false; // 纹理更新 - let lightTipGroup = new THREE.Group(); - lightTipGroup.name = 'lightTipGroup' - let lightGeometry = new THREE.PlaneBufferGeometry(2, 0.5, 1); - let lightMaterial = new THREE.MeshBasicMaterial({ - map: lightMapTexture, + transLayer({bakeStockAmt, longitude, latitude} = {}) { + const markerGeometry = new THREE.CircleBufferGeometry(0.02, 32); + const markerMaterial = new THREE.MeshBasicMaterial({ side: THREE.DoubleSide, blending: THREE.AdditiveBlending, - depthTest: false, - transparent: true, - opacity: 0.5 - }); - let lightPlane = new THREE.Mesh(lightGeometry, lightMaterial); - lightPlane.rotation.y = Math.PI / 2; - lightPlane.position.x = 0; - lightPlane.position.y = 0; - lightPlane.position.z = 0; - lightTipGroup.add(lightPlane); - - let lightMeshCp = lightPlane.clone(); - lightMeshCp.rotation.x = Math.PI / 2; - lightMeshCp.rotation.y = 0; - lightMeshCp.rotation.z = -Math.PI / 2; - lightTipGroup.add(lightMeshCp); - - let circleGeometry = new THREE.CircleBufferGeometry(0.2, 20); - let circleMaterial = new THREE.MeshBasicMaterial({ - side: THREE.DoubleSide, - blending: THREE.AdditiveBlending, - color: '#ff007e', + // color: bakeStockAmt > 0 ? "#66FFFF" : "#FFD15C", + color: "#66FFFF", depthTest: false, transparent: true, opacity: 1 }); - let circleMesh = new THREE.Mesh(circleGeometry, circleMaterial); - circleMesh.position.z = -0.99; - - circleMesh.renderOrder = 1; - lightTipGroup.add(circleMesh); - - let circleCpGeometry = new THREE.CircleBufferGeometry(0.2, 20); - let circleCpMaterial = new THREE.MeshBasicMaterial({ - side: THREE.DoubleSide, - blending: THREE.AdditiveBlending, - color: 0xffffff, - depthTest: false, - transparent: true, - opacity: 1 - }); - let circleMeshCp = new THREE.Mesh(circleCpGeometry, circleCpMaterial); - circleMeshCp.name = 'circleMesh'; - circleMeshCp.position.z = -0.995; - lightTipGroup.add(circleMeshCp); - - lightTipGroup.position.x = areaData.data.cp[0]; - lightTipGroup.position.y = areaData.data.cp[1]; - lightTipGroup.position.z = 1.5; - lightTipGroup.rotation.z = Math.PI / 4; - lightTipGroup.renderOrder = 2; - - return lightTipGroup + const marker = new THREE.Mesh(markerGeometry, markerMaterial); + marker.position.set(...this.lnglatToVector3([longitude, latitude])) + marker.position.z = -0.995 + marker.scale.set(4, 4, 4) + return marker } /** @@ -433,7 +409,7 @@ export default { let ctx = canvas.getContext("2d"); ctx.fillStyle = "#ffffff"; - ctx.font = "50px Arial"; + ctx.font = "20px Arial"; ctx.textAlign = "center"; ctx.fillText(areaData.data.name, 250, 40); @@ -487,10 +463,22 @@ export default { } return new GeoMap() + }, + getData() { + const {$http, $waitFor} = window + const {groupCodeList, currentDate} = this.search + return $waitFor($http).then(() => $http.post("/data-boot/la/screen/marketBoard/storeReport", { + groupCodeList, currentDate + })).then(res => { + if (res?.data) { + return this.layers = res.data || [] + } + }) } }, mounted() { - this.loadLib().then(() => { + Promise.all([this.getData(), + this.loadLib()]).then(() => { this.geoMap = this.initMap(); this.geoMap.init(); })