@realsee/dnalogel
Version:
313 lines (312 loc) • 12.7 kB
JavaScript
var F = Object.defineProperty, N = Object.defineProperties;
var V = Object.getOwnPropertyDescriptors;
var j = Object.getOwnPropertySymbols;
var B = Object.prototype.hasOwnProperty, X = Object.prototype.propertyIsEnumerable;
var S = (v, e, t) => e in v ? F(v, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : v[e] = t, H = (v, e) => {
for (var t in e || (e = {}))
B.call(e, t) && S(v, t, e[t]);
if (j)
for (var t of j(e))
X.call(e, t) && S(v, t, e[t]);
return v;
}, k = (v, e) => N(v, V(e));
var l = (v, e, t) => (S(v, typeof e != "symbol" ? e + "" : e, t), t);
import * as T from "three";
import { getObjectVisible as Y } from "../three/getObjectVisible.js";
import { calculateThreeMouse as C } from "./calculateThreeMouse.js";
import { getFiveModel as A } from "./getFiveModel.js";
import { THREERaycaster as G } from "../three/core/Raycaster.js";
class U {
constructor(e, t) {
l(this, "_five");
/**
* @description: 拖动中
*/
l(this, "dragging", !1);
l(this, "boundObject", {});
l(this, "config");
l(this, "dragSelectTempWorld", new T.Vector3());
l(this, "dragSelectTempProjected", new T.Vector3());
l(this, "handleWantsGesture", (e, t) => {
if (t.length !== 1)
return;
const n = t[0];
if (n.raycaster) {
const i = new G();
i.ray = n.raycaster.ray, i.near = n.raycaster.near, i.far = n.raycaster.far, i.camera = n.raycaster.camera, i.layers = n.raycaster.layers, i.params = n.raycaster.params, n.raycaster = i;
}
if (n) {
if (e === "mouseMove" && this.onDomEvent("hover", n), e === "tap") {
const i = new MouseEvent("click", { clientX: n.x, clientY: n.y }), r = this.onDomEvent("click", n, i), a = this.onDomEvent("wantDblclick", n, i, this.boundObject.dblclick);
if (r === !1 || a === !1)
return !1;
}
if (this.dragging)
return !1;
}
});
l(this, "handleDomEvent", (e, t, n) => {
const i = { x: t.clientX, y: t.clientY };
this.onDomEvent(e, i, t, n);
});
l(this, "handleMouseEvent", (e) => {
this.handleDomEvent(e.type, e);
});
l(this, "handleMousedown", (e) => {
this.handleDomEvent("mousedown", e), this.handleDomEvent("dragstart", e, this.haveDragEventObject);
});
l(this, "handleMouseup", (e) => {
var t;
this.dragging = !1, (t = this.haveDragEventObject) == null || t.forEach((n) => {
n._dragging && (n._dragging = !1, this.notify({
eventName: "dragend",
object: n,
originEvent: e,
raycaster: this.getRaycaster({ x: e.clientX, y: e.clientY })
}));
}), this.handleDomEvent("mouseup", e);
});
l(this, "handleMousemove", (e) => {
var t;
this.dragging && ((t = this.boundObject.drag) == null || t.forEach((n) => {
n._dragging && this.notify({
eventName: "drag",
object: n,
originEvent: e,
raycaster: this.getRaycaster({ x: e.clientX, y: e.clientY })
});
}));
});
// eslint-disable-next-line complexity
l(this, "onDomEvent", (e, t, n, i = this.boundObject[e]) => {
var h, p, E, _, g;
if (!t || !i || (i == null ? void 0 : i.length) === 0)
return;
const r = [];
((h = this.config) == null ? void 0 : h.fiveModels) !== null && ((p = this.config) != null && p.fiveModels ? r.push(...this.config.fiveModels) : r.push(this.model));
const a = r.filter((c) => c.loaded), u = (E = t.raycaster) != null ? E : this.getRaycaster(t);
u.params.Points.threshold = 0.04;
let s = u.intersectObjects(i, !0);
if ((e === "dragstart" || e === "mousedown") && (!s || s.length === 0)) {
const c = this.findDragSelectIntersect(i, t, u);
c && (s = [c]);
}
const f = [];
a.forEach((c) => {
const w = c.intersectRaycaster(u);
f.push(...w);
});
const m = 0.01;
if (f.length > 0 && s.length > 0 && f[0].distance + m < s[0].distance)
return;
const o = (_ = s == null ? void 0 : s[0]) == null ? void 0 : _.object;
if (e === "wantDblclick")
return !1;
if ((!o || !this.objectIsBound(o)) && e === "hover")
for (const c of (g = this.boundObject.hover) != null ? g : [])
c._hovered && this.notify({ eventName: "unHover", object: c });
if (o && o && this.notify({ eventName: e, object: o, originEvent: n, raycaster: u, intersects: s, fiveModelIntersects: f }))
return !1;
});
l(this, "objectIsBound", (e) => {
let t = e._domEvent, n = e.parent;
for (; typeof t == "undefined" && n; )
t = n._domEvent, n = n.parent;
return !!t;
});
l(this, "notify", (e) => {
var _, g, c, w, D, O, M;
const { eventName: t, object: n, originEvent: i, raycaster: r, intersects: a, fiveModelIntersects: u } = e;
if (!n)
return !1;
let s = !1, f = [];
const m = [], o = () => {
if (!a)
return !1;
const d = a.slice(1);
return d[0] ? this.notify(k(H({}, e), { object: d[0].object, intersects: d })) : !1;
};
let h = n;
for (m.push(h); h.parent; )
h = h.parent, m.push(h);
const p = m[m.length - 1];
if ((_ = this.config) != null && _.noEmitWhenNotInScene && p.type !== "Scene")
return o();
let E = !1;
for (const d of m) {
if (s)
break;
d.draggable && (t === "dragstart" && (d._dragging = !0, this.dragging = !0), t === "dragend" && (d._dragging = !1, this.dragging = !1));
const I = d._domEvent;
if (!I)
continue;
const P = I[`${t}Handler`];
if (P)
for (const [R, y] of P) {
if (y != null && y.noEmitWhenNotInScene && p.type !== "Scene")
continue;
if (y.skipPano && u) {
const b = (g = u[0]) == null ? void 0 : g.point;
if (b && ((D = (w = (c = this.five.observers) == null ? void 0 : c[this.five.panoIndex]) == null ? void 0 : w.accessibleNodes) != null && D.some(($) => {
var W;
const L = (W = this.five.works.getResolvedObserver({
workCode: this.five.state.workCode,
panoIndex: $
})) == null ? void 0 : W.standingPosition;
return (L == null ? void 0 : L.distanceTo(b)) < 0.3;
})))
continue;
}
if (((O = this.config) != null && O.noEmitWhenHide || y != null && y.noEmitWhenHide) && !Y(d))
continue;
if (E = !0, t === "hover") {
if (d._hovered)
continue;
d._hovered = !0;
for (const b of (M = this.boundObject.hover) != null ? M : [])
b !== d && b._hovered && this.notify({ eventName: "unHover", object: b });
}
if (t === "unHover") {
if (!d._hovered)
continue;
d._hovered = !1;
}
const x = R({
type: t,
target: d,
origDomEvent: i,
raycaster: r,
intersects: a,
stopPropagation: () => {
s = !0;
}
});
f.push(x != null ? x : !0);
}
}
if (E === !1)
return o();
if (t === "click" || t === "wantDblclick")
return f.some((d) => d === !0);
});
var n;
this.five = e, this.config = t, e.off("wantsGesture", this.handleWantsGesture), e.on("wantsGesture", this.handleWantsGesture), document.addEventListener("mousedown", this.handleMousedown), document.addEventListener("dblclick", this.handleMouseEvent), document.addEventListener("mouseup", this.handleMouseup), document.addEventListener("mousemove", this.handleMousemove), window.__FIVE_DOM_EVENTS__ = (n = window.__FIVE_DOM_EVENTS__) != null ? n : [], window.__FIVE_DOM_EVENTS__.push(this);
}
get five() {
return this._five;
}
set five(e) {
var t;
(t = this._five) == null || t.off("wantsGesture", this.handleWantsGesture), this._five = e, this._five.on("wantsGesture", this.handleWantsGesture);
}
get haveDragEventObject() {
return [...new Set([this.boundObject.dragend, this.boundObject.drag, this.boundObject.dragstart].flat())].filter(Boolean);
}
get model() {
return A(this.five);
}
/**
* @description: added 时自动绑定事件,removed时自动解绑事件,也就是说只有物体在场景中的时候才会触发事件
* @note: 注意:目前需要触发物体的 added 事件和 removed 事件才会生效
* @todo: added 和 removed 还是不太智能
*/
addAutoBindEventListener(e, t, n, i) {
const r = () => this.addEventListener(e, t, n, i), a = () => this.removeEventListener(e, t, n, i);
return e.addEventListener("added", r), e.addEventListener("removed", a), e.addEventListener("dispose", a), () => {
e.removeEventListener("added", r), e.removeEventListener("removed", a), e.removeEventListener("dispose", a);
};
}
/**
* @description: add event listener
* @param params.object: object
* @param params.event: event name
* @param params.callback: 返回 false 可以不阻止 five 的 tap 事件; default: true
* @return {void}
*/
addEventListener(e, t, n, i) {
e._domEvent || (e._domEvent = {}), e._domEvent[`${t}Handler`] || (e._domEvent[`${t}Handler`] = []), this.boundObject[t] || (this.boundObject[t] = []), this.boundObject[t].includes(e) || this.boundObject[t].push(e), e._domEvent[`${t}Handler`].push([n, H({ noEmitWhenHide: !1, noEmitWhenNotInScene: !1 }, i)]);
}
removeEventListener(e, t, n, ...i) {
var a, u;
if (!e._domEvent || (t === void 0 && (Object.keys(this.boundObject).forEach((s) => {
var m, o;
const f = (m = this.boundObject[s]) == null ? void 0 : m.findIndex((h) => h === e);
f !== -1 && ((o = this.boundObject[s]) == null || o.splice(f, 1));
}), e._domEvent = {}), !e._domEvent[`${t}Handler`]))
return;
if (n === void 0) {
delete e._domEvent[`${t}Handler`];
return;
}
const r = e._domEvent[`${t}Handler`].findIndex((s) => s[0] === n);
if (r !== -1 && (e._domEvent[`${t}Handler`].splice(r, 1), e._domEvent[`${t}Handler`].length === 0 && delete e._domEvent[`${t}Handler`], e._domEvent && Object.keys(e._domEvent).length === 0 && delete e._domEvent, !e._domEvent)) {
const s = (a = this.boundObject[t]) == null ? void 0 : a.findIndex((f) => f === e);
s !== -1 && ((u = this.boundObject[t]) == null || u.splice(s, 1));
}
}
clear() {
this.boundObject = {};
}
dispose() {
var e;
(e = this.five) == null || e.off("wantsGesture", this.handleWantsGesture), document.removeEventListener("mousedown", this.handleMousedown), document.removeEventListener("mouseup", this.handleMouseup), document.removeEventListener("mousemove", this.handleMousemove), this.boundObject = {};
}
toJSON() {
return {
boundObject: this.boundObject
};
}
getRaycaster(e) {
const t = this.five.getElement();
if (!t)
return;
const n = C(e, t), i = new G();
return i.setFromCamera(n, this.five.camera), i;
}
getDragSelectPixelDistance(e) {
var n, i;
let t = e;
for (; t; ) {
const r = (n = t.userData) == null ? void 0 : n.dragSelectPixelDistance;
if (typeof r == "number")
return r;
t = (i = t.parent) != null ? i : null;
}
}
findDragSelectIntersect(e, t, n) {
var h, p;
if (!e || e.length === 0)
return;
const i = (p = (h = this.five) == null ? void 0 : h.getElement) == null ? void 0 : p.call(h), r = n.camera;
if (!i || !r)
return;
const a = i.clientWidth, u = i.clientHeight, s = i.getBoundingClientRect(), f = t.x - s.left, m = t.y - s.top;
let o;
for (const E of e) {
const _ = this.getDragSelectPixelDistance(E);
if (typeof _ != "number")
continue;
const g = this.dragSelectTempWorld;
E.getWorldPosition(g);
const c = this.dragSelectTempProjected.copy(g).project(r), w = (c.x * 0.5 + 0.5) * a, D = (1 - (c.y * 0.5 + 0.5)) * u, O = Math.hypot(w - f, D - m);
if (O > _)
continue;
const M = n.ray.distanceToPoint(g);
(!o || O < o.pixelDistance) && (o = {
pixelDistance: O,
object: E,
worldPoint: g.clone(),
distance: M
});
}
if (o)
return {
distance: o.distance,
object: o.object,
point: o.worldPoint
};
}
}
export {
U as FiveDomEvents
};