@egjs/view360
Version:
360 integrated viewing solution from inside-out view to outside-in view. It provides user-friendly service by rotating 360 degrees through various user interaction such as motion sensor and touch.
115 lines (91 loc) • 3.13 kB
text/typescript
import Component from "@egjs/component";
import { quat } from "gl-matrix";
import { InputTypeObserver } from "@egjs/axes/declaration/inputType/InputType";
import { toAxis } from "../utils";
import { util, ROTATE_CONSTANT } from "../../utils/math-util";
import FusionPoseSensor from "./FusionPoseSensor";
const getDeltaYaw = (prvQ: quat, curQ: quat): number => {
const yawDeltaByYaw = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW) as number;
const yawDeltaByRoll = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL) *
Math.sin(util.extractPitchFromQuat(curQ));
return yawDeltaByRoll + yawDeltaByYaw;
};
const getDeltaPitch = (prvQ: quat, curQ: quat): number => {
const pitchDelta = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA);
return pitchDelta;
};
// eslint-disable-next-line @typescript-eslint/ban-types
export default class TiltMotionInput extends Component<{}> {
public element: HTMLElement;
public options: { scale: number; threshold: number };
public fusionPoseSensor: FusionPoseSensor | null;
public axes: string[];
public observer: InputTypeObserver | null;
private _prevQuaternion: quat | null;
private _quaternion: quat | null;
public constructor(el: HTMLElement, options: Partial<{ scale: number; threshold: number }> = {}) {
super();
this.element = el;
this._prevQuaternion = null;
this._quaternion = null;
this.fusionPoseSensor = null;
this.options = {
...{
scale: 1,
threshold: 0
}, ...options
};
this._onPoseChange = this._onPoseChange.bind(this);
}
public mapAxes(axes: string[]) {
this.axes = axes;
}
public connect(observer: InputTypeObserver) {
if (this.observer) {
return this;
}
this.observer = observer;
this.fusionPoseSensor = new FusionPoseSensor();
this.fusionPoseSensor.enable();
this._attachEvent();
return this;
}
public disconnect() {
if (!this.observer) {
return this;
}
this._dettachEvent();
this.fusionPoseSensor!.disable();
this.fusionPoseSensor!.destroy();
this.fusionPoseSensor = null;
this.observer = null;
return this;
}
public destroy() {
this.disconnect();
(this.element as any) = null;
(this.options as any) = null;
(this.axes as any) = null;
this._prevQuaternion = null;
this._quaternion = null;
}
private _onPoseChange(event) {
if (!this._prevQuaternion) {
this._prevQuaternion = quat.clone(event.quaternion);
this._quaternion = quat.clone(event.quaternion);
return;
}
quat.copy(this._prevQuaternion, this._quaternion!);
quat.copy(this._quaternion!, event.quaternion);
this.observer!.change(this, event, toAxis(this.axes, [
getDeltaYaw(this._prevQuaternion, this._quaternion as quat),
getDeltaPitch(this._prevQuaternion, this._quaternion as quat)
]));
}
private _attachEvent() {
this.fusionPoseSensor!.on("change", this._onPoseChange);
}
private _dettachEvent() {
this.fusionPoseSensor!.off("change", this._onPoseChange);
}
}