@realsee/dnalogel
Version:
437 lines (436 loc) • 20.6 kB
JavaScript
var F = Object.defineProperty, P = Object.defineProperties;
var E = Object.getOwnPropertyDescriptors;
var v = Object.getOwnPropertySymbols;
var x = Object.prototype.hasOwnProperty, I = Object.prototype.propertyIsEnumerable;
var g = (d, r, t) => r in d ? F(d, r, { enumerable: !0, configurable: !0, writable: !0, value: t }) : d[r] = t, l = (d, r) => {
for (var t in r || (r = {}))
x.call(r, t) && g(d, t, r[t]);
if (v)
for (var t of v(r))
I.call(r, t) && g(d, t, r[t]);
return d;
}, m = (d, r) => P(d, E(r));
var o = (d, r, t) => (g(d, typeof r != "symbol" ? r + "" : r, t), t);
var u = (d, r, t) => new Promise((e, i) => {
var n = (a) => {
try {
s(t.next(a));
} catch (f) {
i(f);
}
}, h = (a) => {
try {
s(t.throw(a));
} catch (f) {
i(f);
}
}, s = (a) => a.done ? e(a.value) : Promise.resolve(a.value).then(n, h);
s((t = t.apply(d, r)).next());
});
import * as w from "three";
import { to as M } from "../../shared-utils/to.js";
import { equal as y } from "../../shared-utils/equal.js";
import { Main as L } from "../Components/Main.js";
import { formatData as b } from "../utils/formatData.js";
import { CAMERA_IMAGE as _ } from "../Assets/camera.js";
import { omit as S } from "../../shared-utils/filter.js";
import { FLOOR_PLAN_ATTACHED_TO as O } from "../constant.js";
import { Controller as D } from "../../base/BasePluginWithData.js";
import { getPxmm as T, getAttachedY as k } from "../../shared-utils/getPxmm.js";
import { correctFiveState as H } from "../utils/correctFiveState.js";
import { changeModelCanvasOpacity as C } from "../../shared-utils/changeModelCanvasOpacity.js";
import { FloorplanErrorType as p, SHOW_ANIME_DURATION as R } from "../utils/constant.js";
import "../../shared-utils/isTruelyObject.js";
import "../../vendor/svelte/internal/index.js";
import "../../vendor/svelte/transition/index.js";
import "../../vendor/svelte/easing/index.js";
import "../Components/CurrentFloor.js";
import "../../vendor/svelte/store/index.js";
import "../Components/BaseImage.js";
import "../Components/Normalmage.js";
import "../Components/SvgImage.js";
import "../Components/RoomLabels/RoomLabels.js";
import "../Components/RoomLabels/RoomLabel.js";
import "../../shared-utils/svelte/resizeObserver.js";
import "../../vendor/resize-observer-polyfill/dist/ResizeObserver.es.js";
import "../Components/RuleLabels/RuleLabels.js";
import "../Components/RuleLabels/RuleItem.js";
import "../Components/RoomMaterials/RoomMaterial.js";
import "../utils/formatPosition.js";
import "../Components/RoomMaterials/RoomMaterial_0.js";
import "../Components/RoomMaterials/RoomMaterial_1.js";
import "../Components/RoomMaterials/RoomMaterial_2.js";
import "../Components/RoomHighlight/RoomHighlight.js";
import "../Components/RoomHighlight/Room.js";
import "../Components/MissingFloor.js";
import "../Components/Camera.js";
import "../../shared-utils/math/rad2Deg.js";
import "../Components/Compass.js";
import "../Assets/compass.js";
import "../Assets/floorplanExtraObject.js";
import "../../shared-utils/tap.js";
import "../../base/BasePlugin.js";
import "../../shared-utils/Subscribe.js";
import "hammerjs";
import "@realsee/five";
import "../../vendor/@tweenjs/tween/dist/tween.esm.js.js";
import "../../CSS3DRenderPlugin/utils/three/CSS3DRender.js";
import "../../shared-utils/positionToVector3.js";
import "../../CSS3DRenderPlugin/utils/three/CSS3DRenderer.js";
import "three/examples/jsm/renderers/CSS3DRenderer";
import "../../CSS3DRenderPlugin/utils/getAllCSS3DObject.js";
import "../../shared-utils/util.js";
import "../../CSS3DRenderPlugin/utils/createResizeObserver.js";
import "../../CSS3DRenderPlugin/utils/even.js";
import "../../CSS3DRenderPlugin/utils/three/CSS3DObject.js";
import "../../CSS3DRenderPlugin/utils/three/OpacityMesh.js";
import "../../shared-utils/three/centerPoint.js";
import "../../shared-utils/three/getObjectVisible.js";
import "../../CSS3DRenderPlugin/utils/three/CSS3DScene.js";
import "../../CSS3DRenderPlugin/utils/three/CSS3DGroup.js";
import "../../CSS3DRenderPlugin/utils/generateBehindFiveElement.js";
import "../../shared-utils/url/absoluteUrl.js";
import "../../shared-utils/nearlyEqual.js";
import "../../shared-utils/five/changeMode.js";
function z(d) {
const { latitude: r, longitude: t } = d, e = Math.abs(r - Math.PI / 2) > 5 * Math.PI / 180, i = t > 5 * (Math.PI / 180) && t < 355 * (Math.PI / 180);
return e || i;
}
function W(d) {
const { latitude: r, longitude: t } = d, e = Math.abs(r - Math.PI / 2) < 10 * Math.PI / 180, i = t < 30 * (Math.PI / 180) || t > 330 * (Math.PI / 180);
return e && i;
}
class Qt extends D {
constructor(t, e) {
var a, f;
super(t);
// =============== public properties =================
o(this, "name", "modelFloorplanPlugin");
o(this, "state");
// =============== private properties =================
o(this, "data");
/** 展示户型图时,需要正确的状态 */
o(this, "showState");
/** show 动画的公共 Promise */
o(this, "showPromise");
o(this, "app");
o(this, "panoIndex", 0);
o(this, "floorIndex", 0);
o(this, "selector");
/** 公共 Promise 的 reject 方法 */
o(this, "showRejection");
/** 户型图父容器 */
o(this, "wrapper");
/** 户型图主容器 */
o(this, "container", document.createElement("div"));
/** 展示户型图图前,Five 的 Panorama Longitude */
o(this, "lastPanoramaLongitude", 0);
/** 户型图大小 */
o(this, "size", { width: 0, height: 0 });
o(this, "defaultMissingFloorConfig");
/** 是否已经执行过事件监听 */
o(this, "hasAddedEventListener", !1);
/** 上一次隐藏是否是用户调用了 hide 导致的 */
o(this, "isHiddenByHideFunc", !1);
/** 高亮区域 */
o(this, "highlightData", {});
/** 销毁插件 */
o(this, "dispose", () => {
var t, e;
this.removeEventListener(), (t = this.app) == null || t.$destroy(), this.app = void 0, (e = this.container) == null || e.remove(), this.data = void 0, this.wrapper = void 0, this.selector = void 0, this.hooks.emit("dispose");
});
/** 展示户型图
* 1. show 函数大部分情况下需要耗时
* 2. 如果当前已经在展示中,将不会触发任何事件
* 3. 如果展示过程被中断,将抛出错误
* 4. 多次调用 show 方法,只会触发一次 showAnimationEnded 事件,但是展示结果会取决于最后一次调用参数
* 5. 如果多次调用 show 方法,参数与上次参数不一致时,上次 show Promise 会被 reject
* @param opts.floorIndex 楼层
* @param opts.modelOpacity 模型透明度
* @param opts.immediately 是否立即展示
* @param opts.isAutoShow 是否是自动展示
* @param opts.userAction 是否是用户行为
*/
o(this, "show", (...e) => u(this, [...e], function* (t = {}) {
if (!this.state.enabled || !this.showPromise && this.state.visible)
return;
const i = t.userAction !== void 0 ? t.userAction : !0;
this.updateState({ visible: !0 }, i), this._show(t);
}));
/** 隐藏户型图 */
o(this, "hide", (...e) => u(this, [...e], function* (t = {}) {
this.state.enabled && (this.isHiddenByHideFunc = !0, this.state.visible !== !1 && (this.updateState({ visible: !1 }, t.userAction || !0), this._hide(t)));
}));
/** 更新户型图大小 */
o(this, "updateSize", () => {
if (!this.data || !this.container || !this.wrapper)
return !1;
const { min: t, max: e } = this.data.bounding, i = e.x - t.x, n = e.y - t.y, h = this.state.config.attachedTo ? { attachedTo: this.state.config.attachedTo } : void 0, s = T(this.five, this.wrapper, this.floorIndex, h), a = Math.ceil(i * s), f = Math.ceil(n * s);
return this.size.width === a && this.size.height === f || (this.container.style.width = a + "px", this.container.style.height = f + "px", this.size = { width: a, height: f }), !0;
});
o(this, "highlight", (t) => {
this.state.config.highlightEnable && (this.highlightData = t, this.render());
});
o(this, "unhighlight", () => {
this.highlightData = {}, this.render();
});
o(this, "_disable", (t) => {
var i, n, h;
const { userAction: e } = t;
this.hooks.emit("disable", { userAction: e }), (i = this.showRejection) == null || i.call(this, p.BreakOffByDisable), this.showPromise = void 0, (n = this.app) == null || n.$destroy(), this.app = void 0, (h = this.container) == null || h.remove(), this.removeEventListener();
});
o(this, "_enable", (t) => {
const { userAction: e } = t;
this.addEventListener(), this.wrapper && (this.wrapper.append(this.container), this.hooks.emit("enable", { userAction: e }), this.state.visible && this._show({ userAction: e }));
});
o(this, "_show", (t) => u(this, null, function* () {
var h;
if (!this.state.enabled)
return;
if (!((h = this.five.model) != null && h.loaded))
throw new Error(p.ModelNotLoaded);
if (!this.data)
throw new Error(p.DataNotLoaded);
if (this.showPromise)
return this.showPromise;
const e = {
floorIndex: this.floorIndex,
modelOpacity: this.state.config.modelOpacity,
immediately: !1,
isAutoShow: !1,
userAction: !0
}, i = l(l({}, e), t), n = () => u(this, null, function* () {
this.hooks.emit("show", { userAction: i.userAction, auto: i.isAutoShow });
let s = !1, a;
this.showRejection = (A) => {
s = !0, a = A;
};
const [f] = yield M(H(this.five, this.showState, i.userAction));
if (f)
throw f;
if (s)
throw a ? new Error(a) : new Error(p.UnknownError);
if (!this.updateSize())
throw new Error(p.UpdateSizeError);
this.updatePosition(), this.floorIndex = i.floorIndex, this.five.model.show(this.floorIndex);
});
return this.isHiddenByHideFunc = !1, this.showPromise = n().then(() => {
this.showPromise = void 0, this.showRejection = void 0;
const s = i.modelOpacity, a = i.immediately ? 0 : R;
C(this.five, s, a), this.render(a), this.hooks.emit("showAnimationEnded", {
auto: i.isAutoShow,
userAction: i.userAction
});
}).catch((s) => {
if (this.showPromise = void 0, this.showRejection = void 0, this.updateState({ visible: !1 }, i.userAction), !i.isAutoShow && s instanceof Error)
throw s;
}), this.showPromise;
}));
o(this, "_hide", (t) => {
var n;
(n = this.showRejection) == null || n.call(this, p.BreakOffByHide), this.showPromise = void 0;
const i = l(l({}, {
userAction: !0,
isAutoHide: !1
}), t);
C(this.five, 1, 0), this.hooks.emit("hide", { auto: i.isAutoHide, userAction: i.userAction }), this.render();
});
o(this, "handleClick", () => {
if (!this.state.visible)
return;
if (this.hooks.emit("click"))
return !1;
});
/** modelLoaded 之后自动执行 append container 操作 */
o(this, "onFiveModelLoaded", () => {
const e = this.five.model.bounding.getCenter(new w.Vector3());
if (this.showState.offset = e, this.state.enabled === !1 || this.wrapper || !this.selector)
return;
const i = this.selector instanceof Element ? this.selector : document.querySelector(this.selector);
if (!i)
throw new Error("不正确的父容器选择器");
this.wrapper = i, i.append(this.container);
});
/** 更改模型时,自动隐藏户型图 */
o(this, "onFiveModeChange", (t) => {
t !== this.showState.mode && (this.updateState({ visible: !1 }, !1), this._hide({ userAction: !1 }));
});
/** 惯性结束后,判断能否自动展示户型图 */
o(this, "onFiveInteriaPan", (t, e) => {
if (!e || this.state.visible || this.state.config.autoShowEnable === !1 || this.isHiddenByHideFunc)
return;
const i = this.five.getCurrentState();
i.mode === this.showState.mode && W(i) && (this.updateState({ visible: !0 }, !0), this._show({ isAutoShow: !0 }));
});
/** panoIndex 改变时,更新 floorIndex */
o(this, "onFivePanoArrived", (t) => {
var e;
(e = this.five) != null && e.work && (this.panoIndex = t, this.floorIndex = this.five.work.observers[t].floorIndex);
});
/** cameraUpdate 时判断户型图是否应该自动隐藏 */
o(this, "onFiveCameraUpdate", (t, e) => {
if (!this.state.visible || this.showPromise)
return;
const i = this.five.getCurrentState();
this.updatePosition(), this.updateSize(), z(i) && (this.updateState({ visible: !1 }, e), this._hide({ userAction: e }));
});
/** 户型图展示中,转动三维模型,结束时应该自动修复模型状态 */
o(this, "onFiveWantsPanGesture", (t, e) => {
if (this.five.getCurrentState().mode === this.showState.mode && this.state.config.autoShowEnable !== !1 && e && this.state.visible)
return this.five.updateCamera(S(this.showState, ["offset"]), 0), !1;
});
/** 阻止点击分间走点 */
o(this, "onFiveWantsTapGesture", () => this.handleClick());
/** 从 Panorama 切换到其他模态时,记录当前的相机水平视角 */
o(this, "onFiveWantsChangeMode", (t, e) => {
e === "Panorama" && t === this.showState.mode && (this.lastPanoramaLongitude = this.five.getCurrentState().longitude);
});
/** 模型楼层高亮改变时,自动进行楼层切换 */
o(this, "onModelShownFloorChange", (t) => {
if (this.floorIndex !== t) {
if (t === null) {
const e = this.five.getCurrentState().panoIndex;
this.floorIndex = this.five.work.observers[e].floorIndex;
return;
}
this.floorIndex = t, this.updateSize(), this.render();
}
});
e != null && e.selector && (this.selector = e.selector, console.warn("不推荐继续使用 params.selector 配置父容器,请使用 appendTo 方法")), this.showState = {
mode: "Mapview",
longitude: 0,
latitude: Math.PI / 2
}, this.defaultMissingFloorConfig = {
imageURL: this.staticPrefix + "/release/web/saas/missing-floorplan.e274c596.png",
imageWidth: 200,
imageHeight: 120,
text: (f = (a = e.i18n) == null ? void 0 : a.call(e, "暂无平面图")) != null ? f : "暂无平面图",
textFontSize: 14
};
const i = {
northDesc: "北",
modelOpacity: 1,
cameraEnable: !0,
highlightEnable: !1,
hoverEnable: !0,
compassEnable: !0,
autoShowEnable: !0,
ruleLabelsEnable: !0,
roomLabelsEnable: !0,
roomAreaEnable: !0,
roomNameEnable: !0,
cameraImageUrl: _,
attachedTo: O.BOUNDING_CENTER,
getLabelElement: void 0,
adaptiveRoomLabelVisibleEnable: !0,
missingFloorConfig: l(l({}, this.defaultMissingFloorConfig), e.missingFloorConfig),
i18n: (c) => c,
getRoomAreaText: (c) => (c / 1e6).toFixed(1) + "㎡",
getRuleDistanceText: (c) => c.toString()
}, n = e ? S(e, ["selector", "scale"]) : {}, h = l(l({}, i.missingFloorConfig), n.missingFloorConfig), s = m(l(l({}, i), n), { missingFloorConfig: h });
this.state = { enabled: !0, visible: !1, config: s }, this.initContainer(), t.model.loaded ? this.onFiveModelLoaded() : t.once("modelLoaded", this.onFiveModelLoaded), t.once("dispose", this.dispose), this.addEventListener();
}
load(t, e, i = !0) {
return u(this, null, function* () {
function n(c) {
return Object.prototype.hasOwnProperty.apply(c, ["version"]);
}
const h = t;
h && !h.version && console.warn("传入 serverData.data 的方式后续可能不再支持,请把 serverData 整体传入 load 函数");
const s = JSON.parse(JSON.stringify(t)), a = n(s) ? s.data : s, f = this.data;
this.data = yield b(a), this.hooks.emit("dataLoaded", this.data), this.hooks.emit("dataChange", this.data, f), e && this.updateState(e, i), this.render();
});
}
/** 把插件的渲染DOM插入到对应的容器中去 */
appendTo(t) {
if (this.wrapper = t, !!this.state.enabled)
return t.appendChild(this.container), this.render(), this;
}
/** 启用插件 */
enable(t = {}) {
if (this.state.enabled)
return;
const e = t.userAction !== void 0 ? t.userAction : !0;
this.updateState({ enabled: !0 }, t.userAction || e), this._enable({ userAction: e });
}
/** 禁用插件 */
disable(t = {}) {
if (!this.state.enabled)
return;
const e = t.userAction !== void 0 ? t.userAction : !0;
this.updateState({ enabled: !1 }, t.userAction || e), this._disable({ userAction: e });
}
/** 更改插件 State */
setState(t, e = {}) {
const i = this.state, n = e.userAction !== void 0 ? e.userAction : !0;
if (this.updateState(t, n), t.enabled !== void 0 && i.enabled !== t.enabled && (t.enabled ? this._enable({ userAction: n }) : this._disable({ userAction: n })), t.visible !== void 0 && i.visible !== t.visible) {
const h = { userAction: n };
t.visible ? this._show(h) : this._hide(h);
}
}
changeConfigs(t, e = !0) {
this.updateState({ config: t }, e), this.render();
}
/** 更新户型图位置 */
updatePosition() {
var s;
const t = k(this.five, this.floorIndex, this.state.config.attachedTo), e = (s = this.five.model) == null ? void 0 : s.bounding.getCenter(new w.Vector3()).setY(t);
if (!e)
return;
const i = e.clone().project(this.five.camera), n = (i.x + 1) / 2, h = -(i.y - 1) / 2;
this.container.style.left = n * 100 + "%", this.container.style.top = h * 100 + "%";
}
formatData(t) {
return u(this, null, function* () {
return yield b(t.data);
});
}
updateState(t, e) {
var s;
const i = this.state, n = (s = t.config) != null && s.missingFloorConfig ? l(l({}, i.config.missingFloorConfig), t.config.missingFloorConfig) : i.config.missingFloorConfig, h = t.config ? m(l(l({}, i.config), t.config), { missingFloorConfig: n }) : i.config;
this.state = m(l(l({}, this.state), t), { config: h }), !y(this.state, i, { deep: !0 }) && this.hooks.emit("stateChange", { state: this.state, prevState: i, userAction: e });
}
/** 如果用户是通过 selector 设置父容器,需要在 modelLoaded 之后把 container 自动放到父容器里
*
* - TODO: 等 selector 功能下掉之后删除这个逻辑
*/
initContainer() {
this.container.classList.add("floorplan-plugin"), Object.assign(this.container.style, {
position: "absolute",
left: "50%",
top: "50%",
transform: "translate(-50%, -50%)",
zIndex: 10,
pointerEvents: "none"
}), this.five.addExtraElement(this.container);
}
addEventListener() {
if (!this.state.enabled || this.hasAddedEventListener)
return;
const t = this.five;
t.on("modeChange", this.onFiveModeChange), t.on("interiaPan", this.onFiveInteriaPan), t.on("panoArrived", this.onFivePanoArrived), t.on("cameraUpdate", this.onFiveCameraUpdate), t.on("wantsPanGesture", this.onFiveWantsPanGesture), t.on("wantsTapGesture", this.onFiveWantsTapGesture), t.on("wantsChangeMode", this.onFiveWantsChangeMode), t.on("modelShownFloorChange", this.onModelShownFloorChange);
}
removeEventListener() {
const t = this.five;
this.hasAddedEventListener = !1, t.off("modelLoaded", this.onFiveModelLoaded), t.off("modeChange", this.onFiveModeChange), t.off("panoArrived", this.onFivePanoArrived), t.off("cameraUpdate", this.onFiveCameraUpdate), t.off("wantsPanGesture", this.onFiveWantsPanGesture), t.off("wantsTapGesture", this.onFiveWantsTapGesture), t.off("wantsChangeMode", this.onFiveWantsChangeMode), t.off("modelShownFloorChange", this.onModelShownFloorChange);
}
render(t) {
if (!this.state.enabled || !this.container || !this.data || this.size.width === 0 || this.showPromise)
return;
const e = m(l({}, this.state.config), {
visible: this.state.visible,
duration: t != null ? t : 0,
panoIndex: this.panoIndex,
floorIndex: this.floorIndex,
floorplanData: this.data,
lastPanoramaLongitude: this.lastPanoramaLongitude,
highlightData: this.highlightData
});
if (this.app)
return this.app.$set(e);
this.app = new L({ target: this.container, intro: !0, props: e });
}
}
export {
Qt as Controller
};