UNPKG

@realsee/dnalogel

Version:
189 lines (188 loc) 8.72 kB
var P = Object.defineProperty, S = Object.defineProperties; var w = Object.getOwnPropertyDescriptors; var m = Object.getOwnPropertySymbols; var H = Object.prototype.hasOwnProperty, b = Object.prototype.propertyIsEnumerable; var d = (s, e, t) => e in s ? P(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t, h = (s, e) => { for (var t in e || (e = {})) H.call(e, t) && d(s, t, e[t]); if (m) for (var t of m(e)) b.call(e, t) && d(s, t, e[t]); return s; }, c = (s, e) => S(s, w(e)); var i = (s, e, t) => (d(s, typeof e != "symbol" ? e + "" : e, t), t); import { Subscribe as y } from "@realsee/five"; import { PointSelectorHelper as F } from "./PointSelectorHelper.js"; import { isTouchDevice as E } from "../isTouchDevice.js"; import U from "hammerjs"; import { getIntersectionFromEvent as f } from "../getIntersectionFromEvent.js"; import { Vector3 as M, Object3D as I, Face3 as O, Vector2 as V, Raycaster as C } from "three"; import { getIntersectFromRelativePosition as k } from "./getIntersect.js"; const l = () => !1; class N { constructor(e, t) { i(this, "hook", new y()); /** * @description: 不在 five canvas 上时为 true */ i(this, "outOfFive", !1); i(this, "five"); i(this, "hammer"); i(this, "mode"); i(this, "pointSelectorHelper"); i(this, "enabled", !1); /** 长按屏幕的动作触发后为true,手指抬起后为false */ i(this, "pressDown", !1); /** 一组吸附的点,光标靠近这些点时,会将helper以及放大镜的位置设置为这些点 */ i(this, "adherePoints", null); /** 吸附点的半径 */ i(this, "adherePointsRadius", 0.1); i(this, "lastFiveHelperVisible"); /** * @description: 主动触发一次选点 * @return: select 是否成功 */ i(this, "select", (e) => { e && this.updatePointSelectorHelperIntersect(e); const t = this.hook.emit("wantsSelect", this.position); return t || (this.pointSelectorHelper.hide(), this.hook.emit("select", this.position)), !t; }); /** * @description: 鼠标进入five canvas时 */ i(this, "onEnter", () => { this.pointSelectorHelper.show(), this.outOfFive = !1, this.hook.emit("intersectionUpdate", this.position); }); /** * @description: 鼠标离开five canvas时 */ i(this, "onLeave", () => { this.pointSelectorHelper.hide(), this.outOfFive = !0, this.hook.emit("intersectionUpdate", null); }); i(this, "onTap", (e) => { const [t] = f(this.five, e); t != null && t.face && this.select(t); }); /** * 1. 如果之前没有长按行为「即没有长按点时」-> 滑动全景 * 2. 如果有长按点,把长按点位置更新为当前位置 */ i(this, "onPan", (e) => { if (!this.pressDown) return; const [t] = f(this.five, e); t != null && t.face && this.intersectionOnModelUpdate(t); }); /** * @description: 长按屏幕后,更新长按点的位置 */ i(this, "onPress", (e) => { const [t] = f(this.five, e); t != null && t.face && (this.pressDown = !0, this.intersectionOnModelUpdate(t)); }); /** * @description: 手指抬起后,重置pressDown状态 */ i(this, "onPanEnd", () => { this.pressDown && (this.pressDown = !1, this.select()); }); i(this, "intersectionOnModelUpdate", (e) => { this.pointSelectorHelper.show(), this.updatePointSelectorHelperIntersect(e); }); i(this, "updateByMousePosition", (e) => { const t = this.five.getElement(); if (!t) return; const { top: o, left: r, width: n, height: a } = t.getBoundingClientRect(), { clientX: p, clientY: u } = e, v = { x: (p - r) / n, y: 1 - (u - o) / a }; this.updateByNdcPosition(v); }); /** * @description: 根据鼠标位置更新helper位置 */ i(this, "updateByNdcPosition", (e) => { const t = k(this.five, e), o = (() => t ? c(h({}, t), { isVirtual: !1 }) : c(h({}, G(this.five, e)), { isVirtual: !0 }))(); this.updatePointSelectorHelperIntersect(o); }); /** * @description: 更新 pointSelectorHelper 的焦点位置 */ i(this, "updatePointSelectorHelperIntersect", (e) => { var r; const t = h({}, e); let o = !1; if (((r = this.adherePoints) == null ? void 0 : r.length) > 0 && typeof this.adherePointsRadius == "number") { for (const n of this.adherePoints) if (n.distanceTo(e.point) < this.adherePointsRadius) { t.point = n.clone(), o = !0; break; } } this.pointSelectorHelper.updateWithIntersect(t, { emitEvent: !1 }), this.hook.emit("intersectionUpdate", t, o); }); i(this, "onFiveWantsPanGesture", () => { if (this.pressDown) return !1; }); i(this, "renderScreenCenter", () => { this.updateByNdcPosition({ x: 0.5, y: 0.5 }); }); i(this, "emitIntersectionUpdate", (e) => { this.hook.emit("intersectionUpdate", e); }); var n, a; this.five = e; const o = (n = t == null ? void 0 : t.mode) != null ? n : "auto"; o === "auto" ? this.mode = E ? "fixed" : "cursor" : this.mode = o; const r = { autoFixPCPosition: this.mode === "cursor", initialPosition: this.mode === "fixed" ? { left: "35%", top: "20%" } : void 0 }; this.pointSelectorHelper = new F(e, c(h({}, t == null ? void 0 : t.pointSelectorHelperParams), { magnifierParams: h(h({}, r), (a = t == null ? void 0 : t.pointSelectorHelperParams) == null ? void 0 : a.magnifierParams) })), this.pointSelectorHelper.hide(); } get position() { return this.outOfFive ? null : this.pointSelectorHelper.position; } enable() { if (this.enabled) return; this.enabled = !0, this.pointSelectorHelper.enable(); const e = this.five.getElement(); if (!e) throw new Error("five element not found"); this.hammer || (this.hammer = new U(e)), this.mode === "cursor" ? (this.five.on("intersectionOnModelUpdate", this.intersectionOnModelUpdate), this.five.on("wantsPanGesture", this.onFiveWantsPanGesture), this.five.on("wantsMoveToPano", l), this.five.on("wantsChangeMode", l), this.five.on("wantsTapGesture", l), e.addEventListener("mousemove", this.updateByMousePosition), e.addEventListener("mouseenter", this.onEnter), e.addEventListener("mouseout", this.onLeave), this.hammer.on("tap", this.onTap), this.hammer.on("pan", this.onPan), this.hammer.on("press", this.onPress), this.hammer.on("panend", this.onPanEnd)) : this.mode === "fixed" && (this.five.on("panGesture", this.renderScreenCenter), this.five.on("interiaPan", this.renderScreenCenter), this.renderScreenCenter(), this.pointSelectorHelper.show()), this.pointSelectorHelper.hooks.on("intersectionUpdate", this.emitIntersectionUpdate), this.lastFiveHelperVisible = this.five.helperVisible, this.five.helperVisible = !1; } disable() { if (!this.enabled) return; this.enabled = !1, this.pointSelectorHelper.disable(); const e = this.five.getElement(); this.five.off("intersectionOnModelUpdate", this.intersectionOnModelUpdate), this.five.off("wantsPanGesture", this.onFiveWantsPanGesture), this.five.off("wantsMoveToPano", l), this.five.off("wantsChangeMode", l), this.five.off("wantsTapGesture", l), this.five.helperVisible = this.lastFiveHelperVisible, e == null || e.removeEventListener("mousemove", this.updateByMousePosition), e == null || e.removeEventListener("mouseenter", this.onEnter), e == null || e.removeEventListener("mouseout", this.onLeave), this.hammer.off("tap", this.onTap), this.hammer.off("pan", this.onPan), this.hammer.off("press", this.onPress), this.hammer.off("panend", this.onPanEnd), this.five.off("panGesture", this.renderScreenCenter), this.five.off("interiaPan", this.renderScreenCenter), this.pointSelectorHelper.hooks.off("intersectionUpdate", this.emitIntersectionUpdate); } dispose() { this.disable(), this.pointSelectorHelper.dispose(); } setAdherePoints(e, t) { e ? this.adherePoints = Array.isArray(e) ? e : [e] : this.adherePoints = null, typeof t == "number" && (this.adherePointsRadius = t); } } function x(s, e) { const { x: t, y: o } = e, r = t * 2 - 1, n = o * 2 - 1, a = new V().fromArray([r, n]), p = new C(); return p.setFromCamera(a, s.camera), p; } function G(s, e) { const t = x(s, e), o = 3, r = new M().addVectors(t.ray.origin, t.ray.direction.clone().normalize().multiplyScalar(o)), n = t.ray.direction.clone().negate(); return { distance: o, point: r, object: new I(), face: new O(0, 0, 0, n) }; } export { N as PointSelector };