UNPKG

@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
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); } }