提交一下

This commit is contained in:
aixianling
2024-07-12 17:59:27 +08:00
parent 8df752e89f
commit f7ee299e95
2 changed files with 79 additions and 154 deletions

File diff suppressed because one or more lines are too long

View File

@@ -5,7 +5,8 @@ export default {
data() {
return {
geoMap: null,
layers: []
layers: [],
font: null
}
},
computed: {
@@ -16,7 +17,7 @@ export default {
const {$waitFor, THREE, $loadScript} = window
return $waitFor(THREE).then(() => Promise.all([
`http://10.0.97.209/presource/datascreen/js/three/js/controls/OrbitControls.js`,
`http://10.0.97.209/presource/datascreen/js/three/js/renderers/CSS3DRenderer.js`,
`http://10.0.97.209/presource/datascreen/js/three/js/renderers/CSS2DRenderer.js`,
`http://10.0.97.209/presource/datascreen/js/three/js/loaders/FontLoader.js`,
`http://10.0.97.209/presource/datascreen/js/three/js/geometries/TextGeometry.js`,
].map(e => $loadScript('js', e))))
@@ -26,7 +27,6 @@ export default {
const rootEl = this.$el
const root = this
const scale = 4
const transform = (o, n, t) => new TWEEN.Tween(o).to(n, t).start();
class GeoMap {
constructor() {
@@ -35,10 +35,10 @@ export default {
this.camera = null; // 相机
this.renderer = null; // 渲染器
this.controls = null; // 控制器
this.mapGroup = []; // 组
this.selectedObject = null; // 当前选中对象
this.loopIndex = 0; // 循环标记
this.mapGroup = new THREE.Group(); // 组
this.mouse = new THREE.Vector2();
this.font = null;
this.tips = new THREE.Group()
}
/**
@@ -47,21 +47,30 @@ export default {
init() {
this.setScene();
this.setCamera();
this.setLight()
this.setAxes();
this.setRenderer();
this.setControl();
this.makeGround();
this.getMap('http://10.0.97.209/blade-visual/map/data?id=1456');
this.addMarkers()
this.animat();
this.animation();
this.bindMouseEvent()
}
setLight() {
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
this.scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(1, 1, 1).normalize();
this.scene.add(directionalLight);
}
/**
* @desc 动画循环
* */
animat() {
requestAnimationFrame(this.animat.bind(this));
animation() {
requestAnimationFrame(this.animation.bind(this));
TWEEN.update();
this.controls.update();
this.renderer.render(this.scene, this.camera);
@@ -128,7 +137,6 @@ export default {
* */
drawMap(data, border) {
let that = this;
this.mapGroup = new THREE.Group();
this.mapGroup.position.y = 0;
this.scene.add(that.mapGroup);
const extrudeSettings = {
@@ -154,12 +162,7 @@ export default {
// side: THREE.DoubleSide,
transparent: true, wireframe: false
});
const blockSideMaterial = new THREE.MeshBasicMaterial({
color: '#002240',
wireframe: false
});
const lineMaterial = new THREE.LineBasicMaterial({color: '#97CAE6'});
const areas = []
data.forEach(function (areaData) {
let areaGroup = new THREE.Group();
areaGroup.name = 'area';
@@ -173,17 +176,18 @@ export default {
lineMesh.position.z = 0.201;
areaGroup.add(lineMesh);
});
// areaGroup.add(that.transLayer(areaData));
const {name, cp} = areaData.data
that.setTips(name, cp[0], cp[1])
// areaGroup.add(that.tipsSprite(areaData));
that.mapGroup.add(areaGroup);
});
that.mapGroup.add(that.tips)
const shape = new THREE.Shape(border);
const areaGeometry = new THREE.ExtrudeBufferGeometry(shape, extrudeSettings);
// const mesh = new THREE.Mesh(areaGeometry, [blockMaterial, blockSideMaterial]);
const areaGeometry = new THREE.ExtrudeGeometry(shape, extrudeSettings);
const mesh = new THREE.Mesh(areaGeometry, blockMaterial);
that.mapGroup.add(mesh)
that.mapGroup.scale.set(scale, scale, scale)
that.mapGroup.position.set(-3, 0, 0)
that.mapGroup.position.set(0, 0, 0)
that.scene.add(that.mapGroup);
}
@@ -191,7 +195,7 @@ export default {
let {bakeStockAmt, longitude, latitude} = item
longitude = Number(longitude || 0).toFixed(6);
latitude = Number(latitude || 0).toFixed(6);
const markerGeometry = new THREE.CircleBufferGeometry(0.015, 32);
const markerGeometry = new THREE.CircleGeometry(0.015, 32);
const markerMaterial = new THREE.MeshBasicMaterial({
side: THREE.DoubleSide,
blending: THREE.AdditiveBlending,
@@ -202,26 +206,21 @@ export default {
});
const marker = new THREE.Mesh(markerGeometry, markerMaterial);
const lnglat = this.lnglatToVector3([longitude, latitude]);
const v3 = new THREE.Vector3(lnglat[0], lnglat[1], lnglat[2]).multiplyScalar(1.2);
// marker.scale.set(scale, scale, 1)
let v3 = new THREE.Vector3(lnglat[0], lnglat[1], lnglat[2]).multiplyScalar(1.2);
marker.data = item
marker.position.set(v3.x, v3.y, 0.201)
return marker
}
addMarkers() {
this.markers = [];
this.markers = new THREE.Group();
root.layers.map(layer => {
const marker = this.transLayer(layer)
this.markers.push(marker)
this.mapGroup.add(marker)
this.markers.add(marker)
})
this.mapGroup.add(this.markers)
}
/**
* @desc 坐标转换
* @param lnglat [x,y]
* */
lnglatToVector3(lnglat = []) {
if (!this.projection) {
this.projection = d3.geoMercator().center([113.665412, 34.757975]).scale(100).translate([0.3, 0]);
@@ -265,6 +264,7 @@ export default {
this.camera.aspect = rootEl.offsetWidth / rootEl.offsetHeight;
this.camera.updateProjectionMatrix();
this.renderer.setSize(rootEl.offsetWidth, rootEl.offsetHeight);
this.labelRenderer.setSize(rootEl.offsetWidth, rootEl.offsetHeight);
}
rootEl.addEventListener('resize', onWindowResize.bind(this), false);
@@ -290,17 +290,40 @@ export default {
/**
* @desc 鼠标 hover 事件
* */
makeGround() {
const material = new THREE.MeshBasicMaterial({opacity: 0.5, transparent: true, color: '#07193D'});
const geometry = new THREE.PlaneGeometry(100, 100, 1, 1);
let ground = new THREE.Mesh(geometry, material);
ground.position.x = 0;
ground.position.y = 0;
ground.position.z = -1;
this.scene.add(ground);
ground.receiveShadow = true;
ground.castShadow = true;
}
setTips(text, x, y) {
const textGeometry = new THREE.TextGeometry(text, {
font: root.font,
size: 0.04,
height: 0.02
});
textGeometry.center()
textGeometry.rotateZ(Math.PI / 2)
textGeometry.rotateY(Math.PI / 4)
textGeometry.translate(x, y, 0.25)
const textMaterial = new THREE.MeshBasicMaterial({color: 0xffffff, transparent: true, opacity: 0.8});
const textMesh = new THREE.Mesh(textGeometry, textMaterial);
this.tips.add(textMesh)
}
bindMouseEvent() {
const that = this, _this = this;
const raycaster = new THREE.Raycaster();
function onMouseMove(event) {
const {top, left, width, height} = rootEl.getBoundingClientRect();
// const clientX = event.clientX - left
// const clientY = event.clientY - top
that.mouse.x = (event.clientX / width) * 2 - 1; //标准设备横坐标
that.mouse.y = -(event.clientY / height) * 2 + 1; //标准设备纵坐标
const onPointerMove = (event) => {
const {clientWidth: width, clientHeight: height} = rootEl;
this.mouse.x = (event.clientX / width) * 2 - 1; //标准设备横坐标
this.mouse.y = -(event.clientY / height) * 2 + 1; //标准设备纵坐标
// const standardVector = new THREE.Vector3(x, y, 0.5); //标准设备坐标
// //标准设备坐标转世界坐标
// const worldVector = standardVector.unproject(that.camera);
@@ -338,127 +361,23 @@ export default {
// }
}
function onPointerMove() {
if (_this.selectedObject) {
_this.selectedObject.material.color.set(0xffffff);
_this.selectedObject = null;
}
if (raycaster) {
const intersects = raycaster.intersectObjects(_this.markers);
console.log(intersects)
if (intersects.length > 0) {
const res = intersects.filter(function (res) {
return res && res.object;
})[intersects.length - 1];
if (res && res.object) {
_this.selectedObject = res.object;
_this.selectedObject.material.color.set('#f00');
}
}
}
}
const onClick = evt => {
// 创建一个射线投射器
raycaster.setFromCamera(this.mouse, this.camera);
console.log(raycaster.intersectObjects(this.markers))
const marker = this.markers.find(e => raycaster.intersectObject(e, true).length > 0)
if (marker) {
console.log("选取的点:", marker)
const {$glob} = window
root.$storeBoard.search.storeCode = marker.data?.storeCode
$glob.group = '9f299712-5549-413b-a93b-7c3e3b5bfadb'
}
console.table(raycaster.ray)
const intersects = raycaster.intersectObjects(this.markers.children)
console.log(intersects)
intersects.forEach(e => {
if (e.visible) {
const {$glob} = window
root.$storeBoard.search.storeCode = marker.data?.storeCode
$glob.group = '9f299712-5549-413b-a93b-7c3e3b5bfadb'
}
})
}
window.addEventListener('mousemove', onMouseMove, false);
// rootEl.addEventListener('pointermove', onPointerMove);
rootEl.addEventListener('pointermove', onPointerMove);
rootEl.addEventListener('click', onClick);
}
makeGround() {
const material = new THREE.MeshBasicMaterial({opacity: 0.5, transparent: true, color: '#07193D'});
const geometry = new THREE.PlaneGeometry(100, 100, 1, 1);
let ground = new THREE.Mesh(geometry, material);
ground.position.x = 0;
ground.position.y = 0;
ground.position.z = -1;
this.scene.add(ground);
ground.receiveShadow = true;
ground.castShadow = true;
const loader = new THREE.FontLoader();
loader.load('/presource/datascreen/js/three/fonts/PingFang SC_Regular.json', (font) => {
const textGeometry = new THREE.TextGeometry('郑州市', {
font: font,
size: 1,
height: 0.2,
curveSegments: 12,
bevelEnabled: true,
bevelThickness: 0.01,
bevelSize: 0.02,
bevelOffset: 0,
bevelSegments: 5
});
textGeometry.translate(1, 0, 3.2)
textGeometry.rotateX(Math.PI / 2)
textGeometry.rotateZ(Math.PI / 2)
const textMaterial = new THREE.MeshPhongMaterial({color: 0xffffff});
const text = new THREE.Mesh(textGeometry, textMaterial);
this.scene.add(text);
// const planeGeometry = new THREE.PlaneGeometry(textGeometry.boundingBox.max.x, textGeometry.boundingBox.max.y);
// const planeMaterial = new THREE.MeshBasicMaterial({color: '#07193D', side: THREE.DoubleSide});
// const plane = new THREE.Mesh(planeGeometry, planeMaterial);
// plane.position.copy(text.position).add(new THREE.Vector3(0, -textGeometry.boundingBox.max.y, 0));
// plane.position.set(0, 0, 0);
// this.scene.add(plane);
})
// const div = document.createElement("div");
// div.style.color = "#fff";
// div.style.width = "40px";
// div.style.height = "25px";
// div.style.borderWidth = "1px";
// div.style.borderStyle = "solid";
// div.style.borderColor = "#00ffc4";
// div.style.borderRadius = "5px";
// div.style.fontSize = "14px";
// div.style.fontWeight = 600;
// div.style.textShadow = "1px 1px 6px #fff";
// div.style.textAlign = "center";
// div.style.lineHeight = "25px";
// div.textContent = `我操你大爷`;
// const tip = new THREE.CSS3DObject(div);
// tip.scale.set(0.01, 0.01, 0.01);
// tip.position.set(0, 0, 1);
// this.scene.add(tip);
}
tipsSprite(areaData) {
let canvas = document.createElement("canvas");
canvas.width = 500;
canvas.height = 60;
document.body.appendChild(canvas);
let ctx = canvas.getContext("2d");
ctx.fillStyle = "#ffffff";
ctx.font = "20px Arial";
ctx.textAlign = "center";
ctx.fillText(areaData.data.name, 250, 40);
let texture = new THREE.CanvasTexture(canvas);
texture.needsUpdate = true;
let SpriteMaterial = new THREE.SpriteMaterial({
map: texture,
depthTest: false,
});
let textSprite = new THREE.Sprite(SpriteMaterial);
textSprite.position.set(areaData.data.cp[0], areaData.data.cp[1], 1);
textSprite.scale.set(4, 0.5, 1);
textSprite.renderOrder = 3;
return textSprite
}
}
return new GeoMap()
@@ -484,14 +403,19 @@ export default {
}
},
mounted() {
this.loadLib().then(() => {
this.loadLib().then(() => new Promise(resolve => {
const loader = new THREE.FontLoader();
loader.load("/presource/datascreen/js/three/fonts/HarmonyOS Sans SC_Regular.json", font => {
this.font = font
resolve()
})
})).then(() => {
this.geoMap = this.initMap();
this.geoMap.init();
})
}
}
</script>
<template>
<section class="AppThreeMap"/>
</template>