UNPKG

@vuemap/vue-amap-extra

Version:

@vuemap/vue-amap扩展库,包含threejs相关图层

211 lines (208 loc) 6.86 kB
import { Group, TextureLoader, RepeatWrapping, MeshLambertMaterial, DoubleSide, CanvasTexture, Vector2, Path, Shape, ExtrudeGeometry, UniformsUtils, UniformsLib, Color, ShaderMaterial, Mesh } from 'three'; import { getRgbNumber, getAlpha } from '../../utils/colorUtil.mjs'; import { clearGroup } from '../../utils/threeUtil.mjs'; import { vertex, fragment } from './meshlambert.glsl.mjs'; var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => { __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; class ThreePolygon { constructor(layer, options) { __publicField(this, "object"); // Group __publicField(this, "layer"); // threejs的图层对象 __publicField(this, "bottomMaterial"); //底部材质 __publicField(this, "topMaterial"); // 顶部材质 __publicField(this, "sideImgMaterial"); // 侧面贴图材质 __publicField(this, "canvasTexture"); this.layer = layer; this.object = new Group(); this.createGlobalMaterial(options); this.layer.add(this.object); this.init(options); } createGlobalMaterial(options) { if (options.sideTexture) { const sideTexture = new TextureLoader().load(options.sideTexture); sideTexture.wrapS = sideTexture.wrapT = RepeatWrapping; sideTexture.offset.set(0, 0.5); sideTexture.repeat.set(0.1, 0.1); this.sideImgMaterial = new MeshLambertMaterial({ depthTest: options.depthTest, map: sideTexture, side: DoubleSide }); } else { const canvas = document.createElement("canvas"); canvas.width = 512; canvas.height = 512; canvas.style.background = "transparent"; const ctx = canvas.getContext("2d"); if (ctx) { const gradient = ctx.createLinearGradient(0, 0, 0, 512); gradient.addColorStop(0, options.sideTopColor); gradient.addColorStop(1, options.sideBottomColor); ctx.fillStyle = gradient; ctx.fillRect(0, 0, 512, 512); } this.canvasTexture = new CanvasTexture(canvas); } this.bottomMaterial = new MeshLambertMaterial({ depthTest: options.depthTest, transparent: true, color: getRgbNumber(options.bottomColor), opacity: getAlpha(options.bottomColor) }); this.topMaterial = new MeshLambertMaterial({ depthTest: options.depthTest, transparent: true, color: getRgbNumber(options.topColor), opacity: getAlpha(options.topColor) }); } init(options) { options.source.features.forEach((feature) => { if (feature.geometry.type === "Polygon") { this.createMesh(feature.geometry.coordinates, feature.properties, options); } else if (feature.geometry.type === "MultiPolygon") { feature.geometry.coordinates.forEach((cood) => { this.createMesh(cood, feature.properties, options); }); } }); this.refresh(); } createMesh(paths, properties, options) { if (paths.length === 0) { return; } properties = properties || {}; const height = properties.height !== void 0 ? properties.height : options.height; const path = paths[0]; const outPolygonArray = []; const holesArray = []; for (let i = 0; i < path.length; i++) { const point = this.convertLngLat(path[i]); outPolygonArray.push(new Vector2(point[0], point[1])); } for (let i = 1; i < paths.length; i++) { const inPolygonPath = paths[i]; const array = []; for (let j = 0; j < inPolygonPath.length; j++) { const inPoint = this.convertLngLat(inPolygonPath[j]); array.push(new Vector2(inPoint[0], inPoint[1])); } holesArray.push(new Path(array)); } const shape = new Shape(outPolygonArray); shape.holes = holesArray; if (height > 0) { const sideExtrudeGeometry = new ExtrudeGeometry(shape, { depth: height, bevelEnabled: false, steps: 1, bevelSize: 0 }); const hideMaterial = new MeshLambertMaterial({ visible: false }); const materialList = [hideMaterial]; let sideMaterial; if (options.sideTexture) { sideMaterial = this.sideImgMaterial; } else { const uniforms = UniformsUtils.merge([ UniformsLib.common, UniformsLib.specularmap, UniformsLib.envmap, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.emissivemap, UniformsLib.fog, UniformsLib.lights, { emissive: { value: new Color("#000") }, "height": { value: height }, "texture": { value: this.canvasTexture } } ]); sideMaterial = new ShaderMaterial({ depthTest: options.depthTest, depthWrite: true, side: DoubleSide, transparent: true, lights: true, uniforms, vertexShader: vertex, fragmentShader: fragment }); } materialList.push(sideMaterial); const bottomExtrudeGeometry = new ExtrudeGeometry(shape, { depth: 0 }); const bottomMesh = new Mesh(bottomExtrudeGeometry, this.bottomMaterial); this.object.add(bottomMesh); const sideMesh = new Mesh(sideExtrudeGeometry, materialList); this.object.add(sideMesh); } const topExtrudeGeometry = new ExtrudeGeometry(shape, { depth: 0 }); const topMesh = new Mesh(topExtrudeGeometry, this.topMaterial); topMesh.translateZ(height); this.object.add(topMesh); } convertLngLat(lnglat) { var _a; return (_a = this.layer) == null ? void 0 : _a.convertLngLat(lnglat); } refresh() { var _a; (_a = this.layer) == null ? void 0 : _a.update(); } show() { this.object.visible = true; this.refresh(); } hide() { this.object.visible = false; this.refresh(); } remove() { var _a; if (this.object) { (_a = this.layer) == null ? void 0 : _a.remove(this.object); } } destroy() { if (this.object) { clearGroup(this.object); if (this.bottomMaterial) { this.bottomMaterial.dispose(); this.bottomMaterial = void 0; } if (this.canvasTexture) { this.canvasTexture.dispose(); } if (this.topMaterial) { this.topMaterial.dispose(); this.topMaterial = void 0; } if (this.sideImgMaterial) { this.sideImgMaterial.dispose(); this.sideImgMaterial = void 0; } this.object = null; this.layer = void 0; } } } export { ThreePolygon as default }; //# sourceMappingURL=ThreePolygon.mjs.map