@vuemap/vue-amap-extra
Version:
@vuemap/vue-amap扩展库,包含threejs相关图层
215 lines (210 loc) • 7.01 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var three = require('three');
var colorUtil = require('../../utils/colorUtil.js');
var threeUtil = require('../../utils/threeUtil.js');
var meshlambert_glsl = require('./meshlambert.glsl.js');
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 three.Group();
this.createGlobalMaterial(options);
this.layer.add(this.object);
this.init(options);
}
createGlobalMaterial(options) {
if (options.sideTexture) {
const sideTexture = new three.TextureLoader().load(options.sideTexture);
sideTexture.wrapS = sideTexture.wrapT = three.RepeatWrapping;
sideTexture.offset.set(0, 0.5);
sideTexture.repeat.set(0.1, 0.1);
this.sideImgMaterial = new three.MeshLambertMaterial({
depthTest: options.depthTest,
map: sideTexture,
side: three.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 three.CanvasTexture(canvas);
}
this.bottomMaterial = new three.MeshLambertMaterial({
depthTest: options.depthTest,
transparent: true,
color: colorUtil.getRgbNumber(options.bottomColor),
opacity: colorUtil.getAlpha(options.bottomColor)
});
this.topMaterial = new three.MeshLambertMaterial({
depthTest: options.depthTest,
transparent: true,
color: colorUtil.getRgbNumber(options.topColor),
opacity: colorUtil.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 three.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 three.Vector2(inPoint[0], inPoint[1]));
}
holesArray.push(new three.Path(array));
}
const shape = new three.Shape(outPolygonArray);
shape.holes = holesArray;
if (height > 0) {
const sideExtrudeGeometry = new three.ExtrudeGeometry(shape, {
depth: height,
bevelEnabled: false,
steps: 1,
bevelSize: 0
});
const hideMaterial = new three.MeshLambertMaterial({
visible: false
});
const materialList = [hideMaterial];
let sideMaterial;
if (options.sideTexture) {
sideMaterial = this.sideImgMaterial;
} else {
const uniforms = three.UniformsUtils.merge([
three.UniformsLib.common,
three.UniformsLib.specularmap,
three.UniformsLib.envmap,
three.UniformsLib.aomap,
three.UniformsLib.lightmap,
three.UniformsLib.emissivemap,
three.UniformsLib.fog,
three.UniformsLib.lights,
{
emissive: { value: new three.Color("#000") },
"height": { value: height },
"texture": { value: this.canvasTexture }
}
]);
sideMaterial = new three.ShaderMaterial({
depthTest: options.depthTest,
depthWrite: true,
side: three.DoubleSide,
transparent: true,
lights: true,
uniforms,
vertexShader: meshlambert_glsl.vertex,
fragmentShader: meshlambert_glsl.fragment
});
}
materialList.push(sideMaterial);
const bottomExtrudeGeometry = new three.ExtrudeGeometry(shape, {
depth: 0
});
const bottomMesh = new three.Mesh(bottomExtrudeGeometry, this.bottomMaterial);
this.object.add(bottomMesh);
const sideMesh = new three.Mesh(sideExtrudeGeometry, materialList);
this.object.add(sideMesh);
}
const topExtrudeGeometry = new three.ExtrudeGeometry(shape, {
depth: 0
});
const topMesh = new three.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) {
threeUtil.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;
}
}
}
exports.default = ThreePolygon;
//# sourceMappingURL=ThreePolygon.js.map