@realsee/dnalogel
Version:
155 lines (154 loc) • 7.33 kB
JavaScript
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
};