UNPKG

@realsee/dnalogel

Version:
155 lines (154 loc) 7.33 kB
var D = Object.defineProperty; var O = (g, h, n) => h in g ? D(g, h, { enumerable: !0, configurable: !0, writable: !0, value: n }) : g[h] = n; var d = (g, h, n) => (O(g, typeof h != "symbol" ? h + "" : h, n), n); import { BaseController as v } from "../Base/BaseController.js"; import * as s from "three"; import { getMouseRaycaster as E } from "../utils/getMouseRaycaster.js"; import { setObjectQuaternion as w } from "../utils/setObjectQuaternion.js"; import { rad2Deg as C } from "../../math/rad2Deg.js"; import { deg2Rad as f } from "../../math/deg2Rad.js"; class P extends v { constructor(...n) { var c, l, p; super(...n); d(this, "name", "RotateController"); d(this, "startInfo"); d(this, "removeListener"); const e = this.helperObject3D; this.hoverListener([(c = e.xCircle) == null ? void 0 : c.circle, (l = e.yCircle) == null ? void 0 : l.circle, (p = e.zCircle) == null ? void 0 : p.circle].filter(Boolean)); const t = this.dragStart.bind(this), i = this.dragging.bind(this), o = this.dragEnd.bind(this), r = this.show.bind(this), a = this.hide.bind(this); this.domEvents.addEventListener(this.helperObject3D, "mousedown", t), document.addEventListener("mousemove", i), document.addEventListener("mouseup", o), this.hooks.on("moveStart", a), this.hooks.on("moveEnd", r), this.hooks.on("moveByMouseEnable", a), this.hooks.on("moveByMouseDisable", r), this.removeListener = () => { this.domEvents.removeEventListener(this.helperObject3D, "mousedown", t), document.removeEventListener("mousemove", i), document.removeEventListener("mouseup", o), this.hooks.off("moveStart", a), this.hooks.off("moveEnd", r), this.hooks.off("moveByMouseEnable", a), this.hooks.off("moveByMouseDisable", r); }; } get rotateCenter() { return this.helperObject3D.position.clone(); } initialHelperQuaternion() { this.helperObject3D.applyHelperQuaternion(this.originObject3D.quaternion); } setRotateAngle(n) { const { x: e = 0, y: t = 0, z: i = 0 } = n, o = new s.Euler(f(e), f(t), f(i)), r = new s.Quaternion().setFromEuler(o); if (this.hooks.emit("wantToRotate", r)) return; const { originObject3D: c, rotateCenter: l } = this; w(c, r, l), this.hooks.emit("setObjectRotate", r, l), this.hooks.emit("rotate", r), this.render(); } dispose() { this.removeListener(), super.dispose(); } onApplyOriginObjectRotate(n) { this.isDragging || super.onApplyOriginObjectRotate(n); } onApplyOriginObjectScale(n) { } /** * @description: 拖动开始,找出拖的Direction */ dragStart(n) { if (this.isDragging) return; const e = n == null ? void 0 : n.intersect; if (!e) return this.dragEnd(); const t = (e == null ? void 0 : e.object).direction; if (!t) return this.dragEnd(); const i = e.point, o = this.getAngleHelper(t); this.setTipsAngle(0); const r = i.clone(); r.y += 0.2, this.setTipsPosition(r); const a = (() => { if (t === "x") return new s.Vector3(1, 0, 0).applyQuaternion(this.originObject3D.quaternion); if (t === "y") return new s.Vector3(0, 1, 0).applyQuaternion(this.originObject3D.quaternion); if (t === "z") return new s.Vector3(0, 0, 1).applyQuaternion(this.originObject3D.quaternion); })(), c = new s.Plane().setFromNormalAndCoplanarPoint(a, i), p = c.projectPoint(i.clone(), new s.Vector3()).clone().sub(this.rotateCenter), u = p.angleTo(o.baseAxes.clone().applyQuaternion(this.originObject3D.quaternion)); this.setAngleHelperStart(t, u), this.setAngleHelperLength(t, 0), this.startInfo = { direction: t, startVector: p, plane: c, angleHelper: o, angle: 0, objectQuaternion: this.originObject3D.quaternion.clone() }, this.helperObject3D.showDraggingHelper([t]), this.hooks.emit("rotateStart"), this.isDragging = !0; } dragging(n) { if (!this.isDragging) return; const e = E(this.camera, n, this.container); return e ? (this.rotate(e), !1) : this.dragEnd(); } rotate(n) { if (!this.startInfo) return this.dragEnd(); const { startVector: e, plane: t, angleHelper: i, direction: o, objectQuaternion: r } = this.startInfo, { originObject3D: a } = this, c = n.ray.intersectPlane(t, new s.Vector3()); if (!c) return; const l = this.rotateCenter.clone(), u = t.projectPoint(c.clone(), new s.Vector3()).clone().sub(l); if (e.angleTo(u) === 0) return; const m = new s.Quaternion().setFromUnitVectors(e.clone().normalize(), u.clone().normalize()), b = a.quaternion.clone().premultiply(m); if (this.hooks.emit("wantToRotate", b)) return; const y = new s.Euler().setFromQuaternion( new s.Quaternion().setFromUnitVectors( e.clone().normalize().applyQuaternion(r.clone().inverse()), u.clone().normalize().applyQuaternion(r.clone().inverse()) ), `${o.toUpperCase()}${"XZY".replace(o.toUpperCase(), "")}` )[o] * i.angleDirection; if (this.startInfo.angle += y, this.setAngleHelperLength(o, this.startInfo.angle), this.setTipsAngle(C(this.startInfo.angle)), l) { const j = new s.Vector3().subVectors(a.position, l).applyQuaternion(m).add(l); a.position.copy(j); } a.applyQuaternion(m), this.hooks.emit("applyObjectRotate", { quaternion: m, origin: l }), this.hooks.emit("rotate", a.quaternion), this.startInfo.startVector = u; } dragEnd() { this.isDragging && (this.hooks.emit("setObjectRotate", this.originObject3D.quaternion, this.rotateCenter), this.startInfo = void 0, this.isDragging = !1, this.helperObject3D.show(), this.hooks.emit("rotateEnd")); } getAngleHelper(n) { var e, t, i; switch (n) { case "x": return (e = this.helperObject3D.xCircle) == null ? void 0 : e.angleSector; case "y": return (t = this.helperObject3D.yCircle) == null ? void 0 : t.angleSector; case "z": return (i = this.helperObject3D.zCircle) == null ? void 0 : i.angleSector; } } setAngleHelperStart(n, e) { const t = this.getAngleHelper(n); if (!t) { console.warn("angleHelper is undefined"); return; } if (t instanceof s.Mesh && t.geometry instanceof s.CircleGeometry) { const { radius: i, segments: o, thetaLength: r } = t.geometry.parameters; t.geometry = new s.CircleGeometry(i, o, e, r); } else console.warn("only support THREE.CircleGeometry"); } setAngleHelperLength(n, e) { const i = e >= 0 ? Math.max(e, 1e-3) : Math.min(e, -1e-3), o = this.getAngleHelper(n); if (o instanceof s.Mesh && o.geometry instanceof s.CircleGeometry) { const { radius: r, thetaStart: a } = o.geometry.parameters, c = Math.ceil(Math.abs(i) * (40 / (2 * Math.PI))); o.geometry = new s.CircleGeometry(r, c, a, i); } else console.warn("only support THREE.CircleGeometry"); } setTipsAngle(n) { var t; const e = (t = this.helperObject3D.angleTips) == null ? void 0 : t.element; e && (e.innerText = `${n.toFixed(0)}°`); } setTipsPosition(n) { const e = this.helperObject3D.angleTips; if (!e) return; const t = n.project(this.camera), { x: i, y: o, z: r } = t; if (r > 1) return; const a = (i + 1) / 2 * 100 + "%", c = (-o + 1) / 2 * 100 + "%"; e.setLeftTop(a, c); } } export { P as RotateController };