pxt-common-packages
Version:
Microsoft MakeCode (PXT) common packages
101 lines (84 loc) • 2.86 kB
text/typescript
namespace texteffects {
export enum TextEffectKind {
//% block=none
None,
//% block=shake
Shake,
//% block=wave
Wave
}
export function getTextEffect(e: TextEffectKind) {
switch (e) {
case texteffects.TextEffectKind.Wave:
return texteffects.wave;
case texteffects.TextEffectKind.Shake:
return texteffects.shake;
default:
return null;
}
}
//% fixedInstances
export class TextEffect {
public getState: (index?: number, state?: TextEffectState) => TextEffectState;
constructor(getState: (index?: number, state?: TextEffectState) => TextEffectState) {
this.getState = getState;
}
}
//% fixedInstance whenUsed
export const shake = new TextEffect(() => {
return { xOffset: (Math.random() * 2 - 1),
yOffset: (Math.random() * 2 - 1) }
});
interface WaveEffectState extends TextEffectState {
up: boolean;
}
//% fixedInstance whenUsed
export const wave = new TextEffect((index?: number, state?: WaveEffectState) => { // TODO cast state type
if (!state) {
state = {
xOffset: 0,
yOffset: Math.sin(index) * 2,
up: Math.sign(Math.sin(index)) < 0
};
}
state.yOffset += (state.up ? 1 : -1) * 0.5;
state.up = Math.abs(state.yOffset) > 2 ? !state.up : state.up;
return state
});
/**
* A text sprite on the screen
**/
export class TextSprite {
_str: string
_font: image.Font
_color: number;
_effect: TextEffect
_state: TextEffectState[]; // per-character state initialized and used by the effect
get color(): number {
return this._color;
}
get state(): TextEffectState[] {
return this._state;
}
constructor(str: string, font: image.Font, color: number, effect?: TextEffect) {
this._str = str;
this._font = font;
this._color = color;
this._effect = effect;
this._state = [];
}
updateState() {
if (!this._effect) return;
let i = 0;
while (i < this._str.length) {
this._state[i] = this._effect.getState(i, (i < this._state.length ? this._state[i] : null));
i++;
}
}
draw(image: Image, x: number, y: number, start?: number, length?: number): void {
this.updateState();
let s = this._str.substr(Math.max(start, 0), Math.min(length, this._str.length - start));
image.print(s, x, y, this._color, this._font, this._state);
}
}
}