← All @molecule/* packages · App templates
@molecule/app-motionNative · native · App (browser) · v1.0.1 · Apache-2.0
Accelerometer and gyroscope interface for molecule.dev
npm install @molecule/app-motion@molecule/app-motion bridges the native core to the native platform layer of the app.
import {
createShakeDetector,
getAccelerometer,
hasProvider,
requestPermission,
} from '@molecule/app-motion'
async function undoOnShake(undo: () => void): Promise<() => void> {
if (!hasProvider()) return () => {} // no provider wired — skip
if ((await requestPermission()) !== 'granted') return () => {}
const shake = createShakeDetector(undo) // self-wires the accelerometer
shake.start()
return () => shake.stop() // ALWAYS stop on unmount — sensors drain battery
}
async function logTilt(): Promise<void> {
const { x, y, z } = await getAccelerometer() // one-off read
console.log(x, y, z)
}Works with: @molecule/app-bond, @molecule/app-i18n
Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit
src/index.tsJSDoc, not this file.
Accelerometer and gyroscope interface for molecule.dev.
Framework-agnostic core for motion sensors through a swappable
MotionProvider: continuous streams (startAccelerometer,
startGyroscope, startMagnetometer, startOrientation,
startMotion), one-off reads (getAccelerometer, getGyroscope,
getOrientation), a permission flow, and pure gesture helpers
(createShakeDetector, createTiltDetector, createStepCounter,
vector math).
import {
createShakeDetector,
getAccelerometer,
hasProvider,
requestPermission,
} from '@molecule/app-motion'
async function undoOnShake(undo: () => void): Promise<() => void> {
if (!hasProvider()) return () => {} // no provider wired — skip
if ((await requestPermission()) !== 'granted') return () => {}
const shake = createShakeDetector(undo) // self-wires the accelerometer
shake.start()
return () => shake.stop() // ALWAYS stop on unmount — sensors drain battery
}
async function logTilt(): Promise<void> {
const { x, y, z } = await getAccelerometer() // one-off read
console.log(x, y, z)
}
native
npm install @molecule/app-motion @molecule/app-bond @molecule/app-i18n
AccelerometerDataAccelerometer data
interface AccelerometerData extends Vector3D {
/** Timestamp */
timestamp: number
/** Whether gravity is included */
includesGravity: boolean
}
GyroscopeDataGyroscope rotation rate reading (x/y/z radians per second with timestamp).
interface GyroscopeData extends Vector3D {
/** Timestamp */
timestamp: number
}
MagnetometerDataMagnetometer data
interface MagnetometerData extends Vector3D {
/** Timestamp */
timestamp: number
}
MotionCapabilitiesMotion capabilities
interface MotionCapabilities {
/** Whether motion sensors are supported */
supported: boolean
/** Whether accelerometer is available */
hasAccelerometer: boolean
/** Whether gyroscope is available */
hasGyroscope: boolean
/** Whether magnetometer is available */
hasMagnetometer: boolean
/** Whether device orientation is available */
hasOrientation: boolean
/** Whether permission is required */
requiresPermission: boolean
}
MotionDataCombined motion data
interface MotionData {
/** Accelerometer with gravity */
accelerationIncludingGravity?: AccelerometerData
/** Accelerometer without gravity (linear) */
acceleration?: AccelerometerData
/** Gyroscope rotation rate */
rotationRate?: GyroscopeData
/** Device orientation */
orientation?: OrientationData
/** Interval in milliseconds */
interval: number
/** Timestamp */
timestamp: number
}
MotionProviderMotion provider interface
interface MotionProvider {
/**
* Start accelerometer updates
* @param callback - Called with accelerometer data
* @param options - Sensor options
* @returns Stop function
*/
startAccelerometer(
callback: (data: AccelerometerData) => void,
options?: SensorOptions,
): () => void
/**
* Start gyroscope updates
* @param callback - Called with gyroscope data
* @param options - Sensor options
* @returns Stop function
*/
startGyroscope(callback: (data: GyroscopeData) => void, options?: SensorOptions): () => void
/**
* Start magnetometer updates
* @param callback - Called with magnetometer data
* @param options - Sensor options
* @returns Stop function
*/
startMagnetometer(callback: (data: MagnetometerData) => void, options?: SensorOptions): () => void
/**
* Start device orientation updates
* @param callback - Called with orientation data
* @param options - Sensor options
* @returns Stop function
*/
startOrientation(callback: (data: OrientationData) => void, options?: SensorOptions): () => void
/**
* Start combined motion updates
* @param callback - Called with motion data
* @param options - Sensor options
* @returns Stop function
*/
startMotion(callback: (data: MotionData) => void, options?: SensorOptions): () => void
/**
* Get the current accelerometer reading.
* @returns The current accelerometer data with x, y, z values and timestamp.
*/
getAccelerometer(): Promise<AccelerometerData>
/**
* Get the current gyroscope reading.
* @returns The current gyroscope data with x, y, z rotation rates and timestamp.
*/
getGyroscope(): Promise<GyroscopeData>
/**
* Get the current device orientation reading.
* @returns The current orientation data with alpha, beta, gamma angles and timestamp.
*/
getOrientation(): Promise<OrientationData>
/**
* Get the motion sensor permission status.
* @returns The permission status: 'granted', 'denied', 'prompt', or 'unsupported'.
*/
getPermissionStatus(): Promise<MotionPermissionStatus>
/**
* Request motion sensor permission (required on iOS 13+).
* @returns The resulting permission status after the request.
*/
requestPermission(): Promise<MotionPermissionStatus>
/**
* Get the platform's motion sensor capabilities.
* @returns The capabilities indicating which sensors are available.
*/
getCapabilities(): Promise<MotionCapabilities>
}
OrientationDataDevice orientation data
interface OrientationData {
/** Alpha (rotation around Z-axis, 0-360) */
alpha: number
/** Beta (rotation around X-axis, -180 to 180) */
beta: number
/** Gamma (rotation around Y-axis, -90 to 90) */
gamma: number
/** Timestamp */
timestamp: number
/** Whether orientation is absolute */
absolute: boolean
}
SensorOptionsConfiguration for motion sensor listening (sampling frequency in Hz).
interface SensorOptions {
/** Sampling frequency in Hz (default: 60) */
frequency?: number
}
ShakeOptionsShake detection options
interface ShakeOptions {
/** Shake threshold acceleration (default: 15) */
threshold?: number
/** Minimum shakes to trigger (default: 3) */
minShakes?: number
/** Time window in ms (default: 1000) */
timeWindow?: number
}
Vector3D3D vector for sensor data
interface Vector3D {
/** X-axis value */
x: number
/** Y-axis value */
y: number
/** Z-axis value */
z: number
}
MotionPermissionStatusMotion permission status
type MotionPermissionStatus = 'granted' | 'denied' | 'prompt' | 'unsupported'
createShakeDetector(onShake, options)Create a shake gesture detector that uses accelerometer data to detect device shaking.
function createShakeDetector(
onShake: () => void,
options?: ShakeOptions,
): { start: () => void; stop: () => void }
onShake — Called when a shake gesture is detected.options — Shake detection options (threshold, minimum shakes, time window).Returns: A controller with start and stop methods for the shake detector.
createStepCounter(onStep)Create a basic step counter using accelerometer peak detection.
function createStepCounter(onStep: (count: number) => void): {
start: () => void
stop: () => void
getCount: () => number
reset: () => void
}
onStep — Called with the cumulative step count each time a step is detected.Returns: A controller with start, stop, getCount, and reset methods.
createTiltDetector(onChange, options)Create a tilt detector that calculates pitch and roll angles from accelerometer data.
function createTiltDetector(
onChange: (tilt: { pitch: number; roll: number }) => void,
options?: SensorOptions,
): { start: () => void; stop: () => void }
onChange — Called with pitch (front-back tilt) and roll (left-right tilt) angles in degrees.options — Sensor options (sampling frequency).Returns: A controller with start and stop methods for the tilt detector.
cross(a, b)Calculate the cross product of two 3D vectors.
function cross(a: Vector3D, b: Vector3D): Vector3D
a — The first vector.b — The second vector.Returns: A new Vector3D perpendicular to both input vectors.
dot(a, b)Calculate the dot product of two 3D vectors.
function dot(a: Vector3D, b: Vector3D): number
a — The first vector.b — The second vector.Returns: The scalar dot product (a.xb.x + a.yb.y + a.z*b.z).
getAccelerometer()Get the current accelerometer reading.
function getAccelerometer(): Promise<AccelerometerData>
Returns: The current accelerometer data with x, y, z values and timestamp.
getCapabilities()Get the platform's motion sensor capabilities.
function getCapabilities(): Promise<MotionCapabilities>
Returns: The capabilities indicating which sensors are available.
getGyroscope()Get the current gyroscope reading.
function getGyroscope(): Promise<GyroscopeData>
Returns: The current gyroscope data with x, y, z rotation rates and timestamp.
getOrientation()Get the current device orientation reading.
function getOrientation(): Promise<OrientationData>
Returns: The current orientation data with alpha, beta, gamma angles and timestamp.
getPermissionStatus()Get the motion sensor permission status.
function getPermissionStatus(): Promise<MotionPermissionStatus>
Returns: The permission status: 'granted', 'denied', 'prompt', or 'unsupported'.
getProvider()Get the current motion provider.
function getProvider(): MotionProvider
Returns: The active MotionProvider instance.
hasProvider()Check if a motion provider has been registered.
function hasProvider(): boolean
Returns: Whether a MotionProvider has been bonded.
magnitude(v)Calculate the magnitude (length) of a 3D vector.
function magnitude(v: Vector3D): number
v — The 3D vector with x, y, z components.Returns: The Euclidean magnitude of the vector.
normalize(v)Normalize a 3D vector to unit length. Returns a zero vector if the input has zero magnitude.
function normalize(v: Vector3D): Vector3D
v — The 3D vector to normalize.Returns: A new Vector3D with unit length pointing in the same direction.
requestPermission()Request motion sensor permission (required on iOS 13+).
function requestPermission(): Promise<MotionPermissionStatus>
Returns: The resulting permission status after the request.
setProvider(provider)Set the motion provider.
function setProvider(provider: MotionProvider): void
provider — MotionProvider implementation to register.startAccelerometer(callback, options)Start receiving accelerometer data updates.
function startAccelerometer(
callback: (data: AccelerometerData) => void,
options?: SensorOptions,
): () => void
callback — Called with AccelerometerData on each sensor reading.options — Sensor options (sampling frequency).Returns: A function that stops the accelerometer updates when called.
startGyroscope(callback, options)Start receiving gyroscope data updates.
function startGyroscope(
callback: (data: GyroscopeData) => void,
options?: SensorOptions,
): () => void
callback — Called with GyroscopeData on each sensor reading.options — Sensor options (sampling frequency).Returns: A function that stops the gyroscope updates when called.
startMagnetometer(callback, options)Start receiving magnetometer data updates.
function startMagnetometer(
callback: (data: MagnetometerData) => void,
options?: SensorOptions,
): () => void
callback — Called with MagnetometerData on each sensor reading.options — Sensor options (sampling frequency).Returns: A function that stops the magnetometer updates when called.
startMotion(callback, options)Start receiving combined motion data (accelerometer, gyroscope, orientation).
function startMotion(callback: (data: MotionData) => void, options?: SensorOptions): () => void
callback — Called with combined MotionData on each reading.options — Sensor options (sampling frequency).Returns: A function that stops the motion updates when called.
startOrientation(callback, options)Start receiving device orientation updates.
function startOrientation(
callback: (data: OrientationData) => void,
options?: SensorOptions,
): () => void
callback — Called with OrientationData (alpha, beta, gamma angles) on each reading.options — Sensor options (sampling frequency).Returns: A function that stops the orientation updates when called.
Peer dependencies:
@molecule/app-bond ^1.0.1@molecule/app-i18n ^1.0.1@molecule/app-bond
@molecule/app-i18n
Every accessor THROWS until setProvider() is called — there is no
web fallback and no prebuilt provider package ships with molecule;
supply a MotionProvider (native runtime, or a thin web one over
devicemotion/deviceorientation events).
iOS WebKit requires requestPermission() from a USER GESTURE
(DeviceMotionEvent.requestPermission) on HTTPS — calling it on page
load, or on http, rejects without a prompt. Desktop browsers simply
have no sensors: treat 'unsupported' as a normal outcome, not an
error.
Every start* returns a stop function — call it on unmount; a leaked
60 Hz sensor stream is a battery drain and keeps the page from
sleeping.
Axes/units are normalized by the provider contract (m/s², rad/s), but
includesGravity differs per source — check the flag on
AccelerometerData before applying filters.
Translation strings are provided by @molecule/app-locales-motion.