UNPKG

@realsee/dnalogel

Version:
468 lines (462 loc) 20.4 kB
var P = Object.defineProperty, V = Object.defineProperties; var T = Object.getOwnPropertyDescriptors; var k = Object.getOwnPropertySymbols; var F = Object.prototype.hasOwnProperty, L = Object.prototype.propertyIsEnumerable; var v = (h, e, t) => e in h ? P(h, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : h[e] = t, d = (h, e) => { for (var t in e || (e = {})) F.call(e, t) && v(h, t, e[t]); if (k) for (var t of k(e)) L.call(e, t) && v(h, t, e[t]); return h; }, p = (h, e) => V(h, T(e)); var i = (h, e, t) => (v(h, typeof e != "symbol" ? e + "" : e, t), t); import * as n from "three"; import { logWarning as S, logError as U } from "../../shared-utils/log.js"; import { createLineGeometry as x } from "../utils/createLineGeometry.js"; import { isPanoramaLike as M, isModelLike as O } from "../../shared-utils/five/mode.js"; import "hammerjs"; import "@realsee/five"; import "../../vendor/@tweenjs/tween/dist/tween.esm.js.js"; import "../../CSS3DRenderPlugin/utils/three/CSS3DRender.js"; import "../../CSS3DRenderPlugin/utils/generateBehindFiveElement.js"; import { BetterTween as _, tweenProgress as A } from "../../shared-utils/animationFrame/BetterTween.js"; import { loadTexture as G } from "../../shared-utils/three/loadTexture.js"; import w from "../../PanoTagPlugin/controller/index.js"; import E from "../Components/Tag.js"; import { filterAdjacentDistinct as B } from "../utils/index.js"; import { objectAssignDeepExports as I } from "../../vendor/object-assign-deep/objectAssignDeep.js"; const R = ( /* glsl */ ` varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } ` ), W = ( /* glsl */ ` // 是否使用颜色 uniform int useMapColor; // 贴图 uniform sampler2D map; // 贴图颜色 uniform vec3 mapColor; // 贴图透明度 uniform float mapOpacity; // 背景颜色 uniform vec3 backgroundColor; // 边框颜色 uniform vec3 borderColor; // 边框透明度 uniform float borderOpacity; // 背景透明度 uniform float backgroundOpacity; // 整体透明度 uniform float opacity; // 最大 U 值 uniform float maxU; // v offset uniform float vOffset; // 闪烁动画值 uniform float flicker; // 纹理坐标 varying vec2 vUv; // 获取纹理颜色 vec4 getImage() { vec2 uv = vUv; uv.y = uv.y - vOffset; // 原始贴图颜色 vec4 image = texture2D(map, uv); // 如果使用颜色 if (useMapColor == 1) { // 混合颜色 image = mix(image, vec4(mapColor, image.a), image.a); } image.a = image.a * mapOpacity; return image; } // 获取线性渐变的透明度 float linearGradientOpacity() { // 当前的 v 值 float v = vUv.y; float gradientLength = 1.0; if (v <= gradientLength) { return v / gradientLength; // 在 [0, gradientLength] 范围内,透明度为 [0, 1] } else if (v <= maxU - gradientLength) { return 1.0; // 在 (gradientLength, maxU - gradientLength) 范围内,透明度为 1 } else { return (maxU - v) / gradientLength; // 在 [maxU - gradientLength, maxU] 范围内,透明度为 [1, 0] } } vec4 getBorder() { float u = vUv.x; float borderSize = 0.05; if (u <= borderSize || u >= 1.0 - borderSize) { return vec4(borderColor, borderOpacity); } return vec4(0.0, 0.0, 0.0, 0.0); } void main() { vec4 image = getImage(); vec4 border = getBorder(); // 设置背景颜色 gl_FragColor = vec4(backgroundColor, backgroundOpacity); // 混合颜色和背景 gl_FragColor = mix(gl_FragColor, image, image.a); // 混合边框 gl_FragColor = mix(gl_FragColor, border, border.a); // 设置整体透明度 gl_FragColor.a = gl_FragColor.a * opacity; gl_FragColor.a = gl_FragColor.a * linearGradientOpacity(); gl_FragColor.a = gl_FragColor.a * flicker; } ` ); class N { constructor(e, t) { i(this, "name", ""); i(this, "startTagContainer"); i(this, "endTagContainer"); i(this, "path", []); i(this, "geometryStyle", {}); i(this, "materialStyle", {}); i(this, "meshStyle", {}); i(this, "mesh"); i(this, "five"); i(this, "mode"); i(this, "_curvePath", null); i(this, "_curvePoints", null); i(this, "_panoGroup", []); i(this, "skippedPositions", null); i(this, "textureUrl", ""); i(this, "scale", 1); i(this, "width", 0.5); i(this, "unitLength", 0.5); i(this, "_visibleFloorIndexes", null); i(this, "visible", null); /** Five Mode 是否满足 */ i(this, "modeVisible", !1); /** 楼层是否满足展示条件 */ i(this, "floorVisible", !0); /** 默认是否展示 */ i(this, "defaultVisible", !1); /** 走点动画 */ i(this, "inWalkAnimation", !1); i(this, "customVisible", null); i(this, "parent"); i(this, "plugin"); i(this, "textureHasLoaded", !1); i(this, "disposed", !1); i(this, "flowAnime", new _({ progress: 0 }).to({ progress: 1 }).duration(1500).repeat(1 / 0)); i(this, "flickerAnime", A(300).yoyo(!0).repeat(5)); /** 缓存 panoGroup 中每个点距离起点的长度 */ i(this, "cacheLengths", []); /** 为了让多条路线在高度上错开,每个路线都需要有个额外的 offset */ i(this, "heightOffset", 0); i(this, "dispose", () => { var e, t; this.disposed || (this.disposed = !0, this.parent.hooks.off("show", this.updateVisible), this.parent.hooks.off("hide", this.updateVisible), this.plugin.hooks.off("show", this.updateVisible), this.plugin.hooks.off("hide", this.updateVisible), this.plugin.hooks.off("enable", this.updateVisible), this.plugin.hooks.off("disable", this.updateVisible), this.five.off("modeChange", this.onFiveModeChange), this.five.off("modelShownFloorChange", this.onFiveModelShownFloorChange), this.doHide(), (e = this.startTagContainer) == null || e.plugin.dispose(), (t = this.endTagContainer) == null || t.plugin.dispose()); }); /** 开始走点动画 */ i(this, "onWalkAnimationStart", () => { this.inWalkAnimation = !0, this.updateVisible(); }); /** 结束走点动画 */ i(this, "onWalkAnimationEnd", () => { this.inWalkAnimation = !1, this.updateVisible(); }); /** 模型状态变更 */ i(this, "onFiveModeChange", (e) => { this.modeVisible = this.mode === "panorama" ? M(e) : O(e), this.updateVisible(); }); i(this, "onFiveModelShownFloorChange", (e) => { this.floorVisible = e === null || this.visibleFloorIndexes === null || this.visibleFloorIndexes.includes(e), this.updateVisible(); }); /** 更新可见性 */ i(this, "updateVisible", () => { const e = (() => !this.parent.visible || !this.plugin.state.enabled || !this.plugin.state.visible ? !1 : this.customVisible !== null ? this.customVisible : this.inWalkAnimation ? !0 : this.modeVisible && this.textureHasLoaded && this.defaultVisible && this.floorVisible)(); this.visible !== e && (this.visible = e, e ? this.doShow() : this.doHide()); }); i(this, "onFlowAnimeUpdate", (e) => { const { progress: t } = e; this.mesh.material.uniforms.vOffset.value = t, this.mesh.material.uniformsNeedUpdate = !0, this.five.needsRender = !0; }); i(this, "onFlickerAnimeUpdate", (e) => { var s, o, a, l; const { progress: t } = e, r = 1 - t; this.mesh.material.uniforms.flicker.value = r, this.mesh.material.uniformsNeedUpdate = !0, this.five.needsRender = !0, this.startTagContainer.tag && y(this.startTagContainer.tag) && ((a = this.startTagContainer.app) == null || a.$set(p(d({}, this.startTagContainer.tag.data), { opacity: r, name: this.name, distance: Math.round((o = (s = this.curvePath) == null ? void 0 : s.getLength()) != null ? o : 0) }))), this.endTagContainer.tag && y(this.endTagContainer.tag) && ((l = this.endTagContainer.app) == null || l.$set(p(d({}, this.endTagContainer.tag.data), { opacity: r }))); }); i(this, "logWarning", (e) => S("GuideLineModeItem: ", e)); i(this, "logError", (e) => U("GuideLineModeItem: ", e)); var o, a; this.five = e, this.mode = t.mode, this.plugin = t.plugin, this.parent = t.parent, this.startTagContainer = { tag: null, plugin: new w(this.five) }, this.endTagContainer = { tag: null, plugin: new w(this.five) }; const r = new n.BufferGeometry(), s = new n.ShaderMaterial({ vertexShader: R, fragmentShader: W, transparent: !0, uniforms: { map: { value: null }, useMapColor: { value: 0 }, mapColor: { value: new n.Color() }, mapOpacity: { value: 1 }, backgroundColor: { value: new n.Color() }, backgroundOpacity: { value: 0 }, borderColor: { value: new n.Color() }, borderOpacity: { value: 0 }, opacity: { value: 1 }, flicker: { value: 1 }, maxU: { value: 0 }, vOffset: { value: 0 } } }); this.mesh = new n.Mesh(r, s), this.mesh.name = "GuideLineModeItem", this.mode === "panorama" && (this.parent.hooks.on("walkStart", this.onWalkAnimationStart), this.parent.hooks.on("walkEnded", this.onWalkAnimationEnd)), this.updateVisible(), this.onFiveModeChange(this.five.getCurrentState().mode), this.onFiveModelShownFloorChange((a = (o = this.five.model) == null ? void 0 : o.shownFloor) != null ? a : null), this.flowAnime.onUpdate(this.onFlowAnimeUpdate), this.flickerAnime.onUpdate(this.onFlickerAnimeUpdate), this.parent.hooks.on("show", this.updateVisible), this.parent.hooks.on("hide", this.updateVisible), this.plugin.hooks.on("show", this.updateVisible), this.plugin.hooks.on("hide", this.updateVisible), this.plugin.hooks.on("enable", this.updateVisible), this.plugin.hooks.on("disable", this.updateVisible), this.plugin.hooks.on("dispose", this.dispose), this.five.on("modeChange", this.onFiveModeChange), this.five.on("modelShownFloorChange", this.onFiveModelShownFloorChange); } get panoGroup() { return this._panoGroup; } /** 可展示的楼层 */ get visibleFloorIndexes() { return this._visibleFloorIndexes; } /** THREE Curve 路径 */ get curvePath() { return this._curvePath; } /** THREE Curve 路径上的点 */ get curvePoints() { return this._curvePoints; } /** 自定义展示 */ setCustomVisible(e) { if (this.disposed) return this.logError("disposed"); this.customVisible !== e && (this.customVisible = e, this.updateVisible()); } /** 设置默认展示 */ setDefaultVisible(e) { if (this.disposed) return this.logError("disposed"); this.defaultVisible !== e && (this.defaultVisible = e, this.updateVisible()); } /** 基础宽、长 */ setUnitSize(e, t) { if (this.disposed) return this.logError("disposed"); this.width = e, this.unitLength = t, this.setGeometryByPath(this.path, { width: e, unit_length: t }); } /** 设置缩放 */ setScale(e) { if (this.disposed) return this.logError("disposed"); this.scale = e, this.setGeometryByPath(this.path, { scale: e }); } /** 通过点位设置线条形状 */ setGeometryByPanoGroup(e, t) { if (this.disposed) return this.logError("disposed"); if (!this.five.work) return this.logError("setPathByPanoGroup: work is not ready"); const r = B(e); if (this._panoGroup = r, (t == null ? void 0 : t.skipPanoGroup) !== void 0) { const o = t.skipPanoGroup ? r.map((a) => this.plugin.workUtils.getObserverStandingPosition(a)) : null; this.skippedPositions = o; } const s = this.getPathFromPanoGroup(r, this.five.work, t); this.path = s, this.setGeometryByPath(s, t); } /** 通过路径设置线条形状 */ setGeometryByPath(e, t) { var c, b, C; if (this.disposed) return this.logError("disposed"); const r = (c = t == null ? void 0 : t.scale) != null ? c : this.scale, s = (b = t == null ? void 0 : t.width) != null ? b : this.width, o = (C = t == null ? void 0 : t.unit_length) != null ? C : this.unitLength; this.scale = r, this.width = s, this.unitLength = o; const { geometry: a, maxU: l, curvePath: u, curvePoints: g } = x({ path: e, width: s * r, unitLength: o * r, skipPositions: this.skippedPositions }); this._curvePath = u, this._curvePoints = g, this.mesh.geometry = a, this.mesh.material.needsUpdate = !0, this.mesh.material.uniforms.maxU.value = l, this.five.needsRender = !0; const m = e, f = d(d({}, this.geometryStyle), t); this.path = m, this.geometryStyle = f; } /** 设置线条材质 */ setMartial(e) { var r; if (this.disposed) return this.logError("disposed"); (e == null ? void 0 : e.visible) !== void 0 && this.setDefaultVisible(e.visible), (e == null ? void 0 : e.color) !== void 0 && this.setColor(e.color), (e == null ? void 0 : e.opacity) !== void 0 && this.setOpacity(e.opacity), ((r = e == null ? void 0 : e.texture) == null ? void 0 : r.url) !== void 0 && this.setTextureUrl(e.texture.url), (e == null ? void 0 : e.background_color) !== void 0 && this.setBackgroundColor(e.background_color), (e == null ? void 0 : e.background_opacity) !== void 0 && this.setBackgroundOpacity(e.background_opacity), (e == null ? void 0 : e.border_color) !== void 0 && this.setBorderColor(e.border_color), (e == null ? void 0 : e.border_opacity) !== void 0 && this.setBorderOpacity(e.border_opacity); const t = d(d({}, this.materialStyle), e); this.materialStyle = t; } /** 设置模型状态 */ setMeshStyle(e) { if (e != null && e.translate) { const s = new n.Vector3(), o = new n.Vector3().fromArray(e.translate); o.y += this.heightOffset, s.add(o), this.mesh.position.copy(s), r(this.startTagContainer, o), r(this.endTagContainer, o); } const t = d(d({}, this.meshStyle), e); this.meshStyle = t; function r(s, o) { if (!s.tag) return; const a = new n.Vector3().fromArray(s.tag.position); a.add(o); const l = a.toArray(); s.plugin.changeTagById(s.tag.id, { position: l }); } } /** 设置 Y 轴上的偏移量,为了让多条路线在高度上错开,每个路线都需要有个额外的 offset */ setHeightOffset(e) { const t = new n.Vector3(); this.meshStyle.translate && t.add(new n.Vector3().fromArray(this.meshStyle.translate)), t.setY(t.y + e), this.mesh.position.copy(t), this.heightOffset = e, this.five.needsRender = !0; } /** 设置贴图颜色 */ setColor(e) { if (this.disposed) return this.logError("disposed"); e && (this.mesh.material.uniforms.mapColor.value = new n.Color().set(e)), this.mesh.material.uniforms.useMapColor.value = e ? 1 : 0, this.mesh.material.uniformsNeedUpdate = !0, this.five.needsRender = !0; } /** 设置边框 */ setBorderColor(e) { if (this.disposed) return this.logError("disposed"); this.mesh.material.uniforms.borderColor.value = new n.Color().set(e), this.mesh.material.uniformsNeedUpdate = !0, this.five.needsRender = !0; } /** 设置边框透明度 */ setBorderOpacity(e) { if (this.disposed) return this.logError("disposed"); this.mesh.material.uniforms.borderOpacity.value = e, this.mesh.material.uniformsNeedUpdate = !0, this.five.needsRender = !0; } /** 设置背景颜色 */ setBackgroundColor(e) { if (this.disposed) return this.logError("disposed"); this.mesh.material.uniforms.backgroundColor.value = new n.Color().set(e), this.mesh.material.uniformsNeedUpdate = !0, this.five.needsRender = !0; } /** 设置背景透明度 */ setBackgroundOpacity(e) { if (this.disposed) return this.logError("disposed"); this.mesh.material.uniforms.backgroundOpacity.value = e, this.mesh.material.uniformsNeedUpdate = !0, this.five.needsRender = !0; } /** 设置整体透明度 */ setOpacity(e) { if (this.disposed) return this.logError("disposed"); this.mesh.material.uniforms.opacity.value = e, this.mesh.material.uniformsNeedUpdate = !0, this.five.needsRender = !0; } /** 设置贴图透明度 */ setMapOpacity(e) { if (this.disposed) return this.logError("disposed"); this.mesh.material.uniforms.mapOpacity.value = e, this.mesh.material.uniformsNeedUpdate = !0, this.five.needsRender = !0; } /** 设置贴图 */ setTextureUrl(e) { if (this.disposed) return this.logError("disposed"); this.textureUrl = e, G(e).then((t) => { this.disposed || this.textureUrl === e && (t.wrapT = n.RepeatWrapping, this.textureHasLoaded = !0, this.mesh.material.uniforms.map.value = t, this.mesh.material.uniformsNeedUpdate = !0, this.mesh.material.needsUpdate = !0, this.five.needsRender = !0, this.updateVisible()); }); } setVisibleFloorIndexes(e) { var t, r; if (this.disposed) return this.logError("disposed"); this._visibleFloorIndexes = e, this.onFiveModelShownFloorChange((r = (t = this.five.model) == null ? void 0 : t.shownFloor) != null ? r : null); } setStartTag(e) { this.setTag("start", e); } setEndTag(e) { this.setTag("end", e); } /** 闪烁 */ flicker() { if (this.disposed) return this.logError("disposed"); this.flickerAnime.play(); } /** 求起点到 panoIndex 曲线长度 * @param index panoIndex 在 panoGroup 中的索引 * * @description 为什么不使用 panoIndex 作为参数? * - panoIndex 在一个曲线中可能出现多次,无法确定是哪一个。 */ getLengthByPanoGroupIndex(e) { return this.disposed ? this.logError("disposed") : this.cacheLengths.length !== 0 ? this.cacheLengths[e] : (this.cacheLengths = this.getPanoGroupLengths(), this.cacheLengths[e]); } getPanoGroupLengths() { var u; if (!this.curvePoints || !this.curvePath) return []; const e = this.curvePoints.length, t = this.curvePath.getLength(), r = e - 1, s = t / r, o = (u = this.curvePath.getLengths(r)) != null ? u : [], a = []; let l = 0; for (let g = 0; g < e; g++) { const m = this.curvePoints[g], f = this.plugin.workUtils.getObserverStandingPosition(l); if (!f) break; f.clone().setY(0).distanceTo(m.clone().setY(0)) < s && (a.push(o[g]), l += 1); } return a; } setTag(e, t) { const r = this.curvePath, s = e === "start" ? this.startTagContainer : this.endTagContainer; if (!(t != null && t.data)) return s.plugin.clearTags(); const a = I({}, { contentType: "Custom", stickType: "2DPoint", config: { visibleConfig: { visibleFiveMode: ["Floorplan", "Mapview"], followModelVisibility: !1 } }, style: { point: { enabled: !1 } }, data: {} }, t); s.tag = a, y(a) && (s.tag.element = (u) => { var f, c; (f = s.app) == null || f.$destroy(); const g = e === "start" ? p(d({}, a.data), { name: this.name, distance: Math.round((c = r.getLength()) != null ? c : 0), i18n: this.plugin.config.i18n }) : a.data, m = new E({ target: u, intro: !0, props: g }); return s.app = m, () => m.$destroy(); }), s.plugin.load({ tagList: [s.tag] }); const l = this.meshStyle.translate; if (l && a.position) { const u = new n.Vector3().fromArray(a.position), g = new n.Vector3().fromArray(l); u.add(g), u.y += this.heightOffset; const m = u.toArray(); s.plugin.changeTagById(s.tag.id, { position: m }); } } doShow() { this.mode === "model" && this.flowAnime.play(), this.five.scene.add(this.mesh), this.startTagContainer.plugin.show(), this.endTagContainer.plugin.show(), this.five.needsRender = !0; } doHide() { this.mode === "model" && this.flowAnime.stop(), this.five.scene.remove(this.mesh), this.startTagContainer.plugin.hide(), this.endTagContainer.plugin.hide(), this.five.needsRender = !0; } /** 通过 panoIndex 数组计算路径 */ getPathFromPanoGroup(e, t, r) { if (e.length < 2) return []; const s = e.map((o) => this.plugin.workUtils.getObserverStandingPosition(o).toArray()); return [d({ type: "CatmullRomCurve3", points: s }, r)]; } } function y(h) { return h.contentType === "Custom"; } const se = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, GuideLineModeItem: N }, Symbol.toStringTag, { value: "Module" })); export { N as GuideLineModeItem, se as GuideLineModeItem$1 };