Tilt support in breadboard + display of accelerometer values (#1379)

* remove disable tilt option

* allow tilting when breadboard is up (music speakers)

* display acceleration

* only showing acc values if read
This commit is contained in:
Peli de Halleux 2018-10-11 13:25:52 -07:00 committed by GitHub
parent 50f29d278a
commit 37404acbcc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 71 additions and 21 deletions

View File

@ -13,12 +13,19 @@ namespace pxsim.input {
export function acceleration(dimension: number): number {
let b = board().accelerometerState;
let acc = b.accelerometer;
acc.activate();
switch (dimension) {
case 0: return acc.getX();
case 1: return acc.getY();
case 2: return acc.getZ();
default: return Math.floor(Math.sqrt(acc.instantaneousAccelerationSquared()));
case 0:
acc.activate(AccelerometerFlag.X);
return acc.getX();
case 1:
acc.activate(AccelerometerFlag.Y);
return acc.getY();
case 2:
acc.activate(AccelerometerFlag.Z);
return acc.getZ();
default:
acc.activate();
return Math.floor(Math.sqrt(acc.instantaneousAccelerationSquared()));
}
}
@ -99,6 +106,12 @@ namespace pxsim {
NORTH_EAST_DOWN
}
export enum AccelerometerFlag {
X = 1,
Y = 2,
Z = 4
}
export class Accelerometer {
private sigma: number = 0; // the number of ticks that the instantaneous gesture has been stable.
private lastGesture: number = 0; // the last, stable gesture recorded.
@ -110,6 +123,7 @@ namespace pxsim {
private id: number;
public isActive = false;
public sampleRange = 2;
public flags: AccelerometerFlag = 0;
constructor(public runtime: Runtime) {
this.id = DAL.MICROBIT_ID_ACCELEROMETER;
@ -120,11 +134,13 @@ namespace pxsim {
this.sampleRange = Math.max(1, Math.min(8, range));
}
public activate() {
public activate(flags?: AccelerometerFlag) {
if (!this.isActive) {
this.isActive = true;
this.runtime.queueDisplayUpdate();
}
if (flags)
this.flags |= flags;
}
/**
@ -383,7 +399,7 @@ namespace pxsim {
useShake = false;
constructor(runtime: Runtime) {
this.accelerometer = new Accelerometer(runtime);
this.accelerometer = new Accelerometer(runtime);
}
}
}

View File

@ -3,7 +3,6 @@ namespace pxsim.visuals {
return new visuals.MicrobitBoardSvg({
runtime: runtime,
theme: visuals.randomTheme(opts.highContrast),
disableTilt: false,
wireframe: opts.wireframe
});
}

View File

@ -274,7 +274,6 @@ path.sim-board {
export interface IBoardProps {
runtime?: pxsim.Runtime;
theme?: IBoardTheme;
disableTilt?: boolean;
wireframe?: boolean;
}
@ -306,6 +305,9 @@ path.sim-board {
private thermometerText: SVGTextElement;
private shakeButton: SVGCircleElement;
private shakeText: SVGTextElement;
private accTextX: SVGTextElement;
private accTextY: SVGTextElement;
private accTextZ: SVGTextElement;
public board: pxsim.DalBoard;
private pinNmToCoord: Map<Coord> = {};
@ -694,19 +696,52 @@ path.sim-board {
accessibility.setLiveContent(lv.toString());
}
findParentElement() {
let el = this.element;
while (el.parentNode && el.parentNode.nodeName == "svg")
el = el.parentNode as SVGSVGElement;
return el;
}
private updateTilt() {
if (this.props.disableTilt) return;
const state = this.board;
if (!state || !state.accelerometerState.accelerometer.isActive) return;
const x = state.accelerometerState.accelerometer.getX();
const y = -state.accelerometerState.accelerometer.getY();
const acc = state.accelerometerState.accelerometer;
const x = acc.getX();
const y = -acc.getY();
const z = acc.getZ();
const af = 8 / 1023;
const s = 1 - Math.min(0.1, Math.pow(Math.max(Math.abs(x), Math.abs(y)) / 1023, 2) / 35);
this.element.style.transform = `perspective(30em) rotateX(${y * af}deg) rotateY(${x * af}deg) scale(${s}, ${s})`
this.element.style.perspectiveOrigin = "50% 50% 50%";
this.element.style.perspective = "30em";
// fix top parent and apply style to it
const el = this.findParentElement();
el.style.transform = `perspective(30em) rotateX(${y * af}deg) rotateY(${x * af}deg) scale(${s}, ${s})`
el.style.perspectiveOrigin = "50% 50% 50%";
el.style.perspective = "30em";
// update text
if (acc.flags & AccelerometerFlag.X) {
if (!this.accTextX) {
this.accTextX = svg.child(this.g, "text", { x: 365, y: 260, class: "sim-text" }) as SVGTextElement;
this.accTextX.textContent = "";
}
this.accTextX.textContent = `ax:${x}`;
}
if (acc.flags & AccelerometerFlag.Y) {
if (!this.accTextY) {
this.accTextY = svg.child(this.g, "text", { x: 365, y: 285, class: "sim-text" }) as SVGTextElement;
this.accTextY.textContent = "";
}
this.accTextY.textContent = `ay:${-y}`;
}
if (acc.flags & AccelerometerFlag.Z) {
if (!this.accTextZ) {
this.accTextZ = svg.child(this.g, "text", { x: 365, y: 310, class: "sim-text" }) as SVGTextElement;
this.accTextZ.textContent = "";
}
this.accTextZ.textContent = `az:${z}`;
}
}
private buildDom() {
@ -729,13 +764,13 @@ path.sim-board {
// filters
let ledglow = svg.child(this.defs, "filter", { id: "ledglow", x: "-75%", y: "-75%", width: "300%", height: "300%" });
svg.child(ledglow, "feMorphology", { operator: "dilate", radius: "4", in: "SourceAlpha", result: "thicken"});
svg.child(ledglow, "feGaussianBlur", { stdDeviation: "5", in: "thicken", result: "blurred"});
svg.child(ledglow, "feFlood", { "flood-color": "rgb(255, 17, 77)", result: "glowColor"});
svg.child(ledglow, "feComposite", { in: "glowColor", in2: "blurred", operator: "in", result: "ledglow_colored"});
svg.child(ledglow, "feMorphology", { operator: "dilate", radius: "4", in: "SourceAlpha", result: "thicken" });
svg.child(ledglow, "feGaussianBlur", { stdDeviation: "5", in: "thicken", result: "blurred" });
svg.child(ledglow, "feFlood", { "flood-color": "rgb(255, 17, 77)", result: "glowColor" });
svg.child(ledglow, "feComposite", { in: "glowColor", in2: "blurred", operator: "in", result: "ledglow_colored" });
let ledglowMerge = svg.child(ledglow, "feMerge", {});
svg.child(ledglowMerge, "feMergeNode", { in: "ledglow_colored"});
svg.child(ledglowMerge, "feMergeNode", { in: "SourceGraphic"});
svg.child(ledglowMerge, "feMergeNode", { in: "ledglow_colored" });
svg.child(ledglowMerge, "feMergeNode", { in: "SourceGraphic" });
let glow = svg.child(this.defs, "filter", { id: "filterglow", x: "-5%", y: "-5%", width: "120%", height: "120%" });
svg.child(glow, "feGaussianBlur", { stdDeviation: "5", result: "glow" });