Skip to content

Commit

Permalink
Merge pull request #50 from ccrma/mike-gyro
Browse files Browse the repository at this point in the history
Accelerometer and Gyroscope support on mobile devices
  • Loading branch information
terryzfeng authored Oct 24, 2024
2 parents 4511dc2 + b910cd3 commit 0919c85
Show file tree
Hide file tree
Showing 42 changed files with 2,976 additions and 93 deletions.
57 changes: 57 additions & 0 deletions dist/Accel.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import Chuck from "./Chuck";
/**
* Introducing Accel (accelerometer, on mobile) support for WebChucK. Accel wraps
* JavaScript DeviceMotionEvent listeners easing access to mobile device accelerometers
* in WebChucK code.
*
* To get started with Accel:
* @example
* ```ts
* import { Chuck, Accel } from "webchuck";
*
* const theChuck = await Chuck.init([]);
* const accel = await Accel.init(theChuck); // Initialize Accel
* ```
*/
export default class Accel {
private theChuck;
private _accelActive;
private boundHandleMotion;
/** @internal */
constructor(theChuck: Chuck);
/**
* Initialize Accel functionality in your WebChucK instance.
* This adds a `Accel` and `AccelMsg` class to the ChucK Virtual Machine (VM).
* Accelerometer event (DeviceMotionEvent) listeners are added if `enableAccel` is true (default).
* @example
* ```ts
* theChuck = await Chuck.init([]);
* accel = await Accel.init(theChuck); // Initialize Accel
*/
static init(theChuck: Chuck, enableAccel?: boolean): Promise<Accel>;
/**
* @internal
* Check if accel is active
*/
accelActive(): Promise<void>;
/**
* Enable Javascript event (DeviceMotionEvent) listeners for Accel
* @example
* ```ts
* // If accel is not yet enabled
* accel.enableAccel();
* ```
*/
enableAccel(): void;
/**
* Disable Javascript event (DeviceMotionEvent) listeners for Accel
* @example
* ```ts
* // If accel is enabled
* accel.disableAccel();
* ```
*/
disableAccel(): void;
/** @internal */
private handleMotion;
}
105 changes: 105 additions & 0 deletions dist/Accel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { Accel_ck, AccelMsg_ck } from "./accelCk";
/**
* Introducing Accel (accelerometer, on mobile) support for WebChucK. Accel wraps
* JavaScript DeviceMotionEvent listeners easing access to mobile device accelerometers
* in WebChucK code.
*
* To get started with Accel:
* @example
* ```ts
* import { Chuck, Accel } from "webchuck";
*
* const theChuck = await Chuck.init([]);
* const accel = await Accel.init(theChuck); // Initialize Accel
* ```
*/
export default class Accel {
/** @internal */
constructor(theChuck) {
this._accelActive = false;
// Initialize members
this.theChuck = theChuck;
this.boundHandleMotion = this.handleMotion.bind(this);
}
/**
* Initialize Accel functionality in your WebChucK instance.
* This adds a `Accel` and `AccelMsg` class to the ChucK Virtual Machine (VM).
* Accelerometer event (DeviceMotionEvent) listeners are added if `enableAccel` is true (default).
* @example
* ```ts
* theChuck = await Chuck.init([]);
* accel = await Accel.init(theChuck); // Initialize Accel
*/
static async init(theChuck, enableAccel = true) {
const accel = new Accel(theChuck);
// Add Accel and AccelMsg classes to ChucK VM
await accel.theChuck.runCode(AccelMsg_ck);
await accel.theChuck.runCode(Accel_ck);
// Enable mouse and keyboard
/*
if (enableAccel) {
// If iOS, request permission
if (typeof (DeviceOrientationEvent as any).requestPermission === 'function') {
const permission = await (DeviceOrientationEvent as any).requestPermission();
if (permission === 'granted') {
accel.enableAccel();
} else {
console.log("Accelscope permission denied.");
}
} else {
// just try to enable
accel.enableAccel();
}
}
*/
accel.enableAccel();
return accel;
}
/**
* @internal
* Check if accel is active
*/
async accelActive() {
const x = await this.theChuck.getInt("_accelActive");
this._accelActive = x == 1;
}
/**
* Enable Javascript event (DeviceMotionEvent) listeners for Accel
* @example
* ```ts
* // If accel is not yet enabled
* accel.enableAccel();
* ```
*/
enableAccel() {
// consider using "deviceorientationabsolute"
// https://developer.mozilla.org/en-US/docs/Web/API/Window/deviceorientationabsolute_event
window.addEventListener("devicemotion", this.boundHandleMotion);
}
/**
* Disable Javascript event (DeviceMotionEvent) listeners for Accel
* @example
* ```ts
* // If accel is enabled
* accel.disableAccel();
* ```
*/
disableAccel() {
window.removeEventListener("devicemotion", this.boundHandleMotion);
}
//-----------------------------------------
// JAVASCRIPT HID EVENT HANDLERS
//-----------------------------------------
/** @internal */
handleMotion(event) {
this.accelActive();
if (this._accelActive) {
if (event.acceleration != null) {
this.theChuck.setFloat("_accelX", event.acceleration.x ? event.acceleration.x : 0.0);
this.theChuck.setFloat("_accelY", event.acceleration.y ? event.acceleration.y : 0.0);
this.theChuck.setFloat("_accelZ", event.acceleration.z ? event.acceleration.z : 0.0);
this.theChuck.broadcastEvent("_accelReading");
}
}
}
}
57 changes: 57 additions & 0 deletions dist/Gyro.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import Chuck from "./Chuck";
/**
* Introducing Gyro (gyroerometer, on mobile) support for WebChucK. Gyro wraps
* JavaScript DeviceMotionEvent listeners easing access to mobile device gyroerometers
* in WebChucK code.
*
* To get started with Gyro:
* @example
* ```ts
* import { Chuck, Gyro } from "webchuck";
*
* const theChuck = await Chuck.init([]);
* const gyro = await Gyro.init(theChuck); // Initialize Gyro
* ```
*/
export default class Gyro {
private theChuck;
private _gyroActive;
private boundHandleOrientation;
/** @internal */
constructor(theChuck: Chuck);
/**
* Initialize Gyro functionality in your WebChucK instance.
* This adds a `Gyro` and `GyroMsg` class to the ChucK Virtual Machine (VM).
* Gyroerometer event (DeviceMotionEvent) listeners are added if `enableGyro` is true (default).
* @example
* ```ts
* theChuck = await Chuck.init([]);
* gyro = await Gyro.init(theChuck); // Initialize Gyro
*/
static init(theChuck: Chuck, enableGyro?: boolean): Promise<Gyro>;
/**
* @internal
* Check if gyro is active
*/
gyroActive(): Promise<void>;
/**
* Enable Javascript event (DeviceMotionEvent) listeners for Gyro
* @example
* ```ts
* // If gyro is not yet enabled
* gyro.enableGyro();
* ```
*/
enableGyro(): void;
/**
* Disable Javascript event (DeviceMotionEvent) listeners for Gyro
* @example
* ```ts
* // If gyro is enabled
* gyro.disableGyro();
* ```
*/
disableGyro(): void;
/** @internal */
private handleOrientation;
}
103 changes: 103 additions & 0 deletions dist/Gyro.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { Gyro_ck, GyroMsg_ck } from "./gyroCk";
/**
* Introducing Gyro (gyroerometer, on mobile) support for WebChucK. Gyro wraps
* JavaScript DeviceMotionEvent listeners easing access to mobile device gyroerometers
* in WebChucK code.
*
* To get started with Gyro:
* @example
* ```ts
* import { Chuck, Gyro } from "webchuck";
*
* const theChuck = await Chuck.init([]);
* const gyro = await Gyro.init(theChuck); // Initialize Gyro
* ```
*/
export default class Gyro {
/** @internal */
constructor(theChuck) {
this._gyroActive = false;
// Initialize members
this.theChuck = theChuck;
this.boundHandleOrientation = this.handleOrientation.bind(this);
}
/**
* Initialize Gyro functionality in your WebChucK instance.
* This adds a `Gyro` and `GyroMsg` class to the ChucK Virtual Machine (VM).
* Gyroerometer event (DeviceMotionEvent) listeners are added if `enableGyro` is true (default).
* @example
* ```ts
* theChuck = await Chuck.init([]);
* gyro = await Gyro.init(theChuck); // Initialize Gyro
*/
static async init(theChuck, enableGyro = true) {
const gyro = new Gyro(theChuck);
// Add Gyro and GyroMsg classes to ChucK VM
await gyro.theChuck.runCode(GyroMsg_ck);
await gyro.theChuck.runCode(Gyro_ck);
// Enable mouse and keyboard
/*
if (enableGyro) {
// If iOS, request permission
if (typeof (DeviceOrientationEvent as any).requestPermission === 'function') {
const permission = await (DeviceOrientationEvent as any).requestPermission();
if (permission === 'granted') {
gyro.enableGyro();
} else {
console.log("Gyroscope permission denied.");
}
} else {
// just try to enable
gyro.enableGyro();
}
}
*/
gyro.enableGyro();
return gyro;
}
/**
* @internal
* Check if gyro is active
*/
async gyroActive() {
const x = await this.theChuck.getInt("_gyroActive");
this._gyroActive = x == 1;
}
/**
* Enable Javascript event (DeviceMotionEvent) listeners for Gyro
* @example
* ```ts
* // If gyro is not yet enabled
* gyro.enableGyro();
* ```
*/
enableGyro() {
// consider using "deviceorientationabsolute"
// https://developer.mozilla.org/en-US/docs/Web/API/Window/deviceorientationabsolute_event
window.addEventListener("deviceorientation", this.boundHandleOrientation);
}
/**
* Disable Javascript event (DeviceMotionEvent) listeners for Gyro
* @example
* ```ts
* // If gyro is enabled
* gyro.disableGyro();
* ```
*/
disableGyro() {
window.removeEventListener("deviceorientation", this.boundHandleOrientation);
}
//-----------------------------------------
// JAVASCRIPT HID EVENT HANDLERS
//-----------------------------------------
/** @internal */
handleOrientation(event) {
this.gyroActive();
if (this._gyroActive) {
this.theChuck.setFloat("_gyroX", event.alpha ? event.alpha : 0.0);
this.theChuck.setFloat("_gyroY", event.beta ? event.beta : 0.0);
this.theChuck.setFloat("_gyroZ", event.gamma ? event.gamma : 0.0);
this.theChuck.broadcastEvent("_gyroReading");
}
}
}
57 changes: 57 additions & 0 deletions dist/accel/Accel.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import Chuck from "../Chuck";
/**
* Introducing Accel (accelerometer, on mobile) support for WebChucK. Accel wraps
* JavaScript DeviceMotionEvent listeners easing access to mobile device accelerometers
* in WebChucK code.
*
* To get started with Accel:
* @example
* ```ts
* import { Chuck, Accel } from "webchuck";
*
* const theChuck = await Chuck.init([]);
* const accel = await Accel.init(theChuck); // Initialize Accel
* ```
*/
export default class Accel {
private theChuck;
private _accelActive;
private boundHandleMotion;
/** @internal */
constructor(theChuck: Chuck);
/**
* Initialize Accel functionality in your WebChucK instance.
* This adds a `Accel` and `AccelMsg` class to the ChucK Virtual Machine (VM).
* Accelerometer event (DeviceMotionEvent) listeners are added if `enableAccel` is true (default).
* @example
* ```ts
* theChuck = await Chuck.init([]);
* accel = await Accel.init(theChuck); // Initialize Accel
*/
static init(theChuck: Chuck, enableAccel?: boolean): Promise<Accel>;
/**
* @internal
* Check if accel is active
*/
accelActive(): Promise<void>;
/**
* Enable Javascript event (DeviceMotionEvent) listeners for Accel
* @example
* ```ts
* // If accel is not yet enabled
* accel.enableAccel();
* ```
*/
enableAccel(): void;
/**
* Disable Javascript event (DeviceMotionEvent) listeners for Accel
* @example
* ```ts
* // If accel is enabled
* accel.disableAccel();
* ```
*/
disableAccel(): void;
/** @internal */
private handleMotion;
}
Loading

0 comments on commit 0919c85

Please sign in to comment.