@realsee/dnalogel
Version:
189 lines (188 loc) • 8.72 kB
JavaScript
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
};