-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #50 from ccrma/mike-gyro
Accelerometer and Gyroscope support on mobile devices
- Loading branch information
Showing
42 changed files
with
2,976 additions
and
93 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
Oops, something went wrong.