mirror of
https://github.com/Terncode/pixel.horse.git
synced 2026-09-24 13:55:04 +02:00
82 lines
2.3 KiB
TypeScript
82 lines
2.3 KiB
TypeScript
import { Component, Input, AfterViewInit, ElementRef, ChangeDetectionStrategy, ViewChild, NgZone } from '@angular/core';
|
|
import { findEmoji, getEmojiImageAsync } from '../../../common/emoji';
|
|
import { font } from '../../../common/fonts';
|
|
import { getCharacterSprite } from '../../../graphics/spriteFont';
|
|
import { loadAndInitSpriteSheets } from '../../../client/loadSprites';
|
|
|
|
@Component({
|
|
standalone: false,
|
|
selector: 'emote-box',
|
|
template: '<img #image class="emote-box pixelart" />',
|
|
styles: ['.emote-box { pointer-events: none; }'],
|
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
})
|
|
export class EmoteBox implements AfterViewInit {
|
|
@ViewChild('image', { static: true }) image!: ElementRef;
|
|
private emoteValue = '';
|
|
private scaleValue = 2;
|
|
private initialized = false;
|
|
constructor(private zone: NgZone) {
|
|
}
|
|
ngAfterViewInit() {
|
|
loadAndInitSpriteSheets()
|
|
.then(() => {
|
|
this.initialized = true;
|
|
this.zone.runOutsideAngular(() => this.redraw());
|
|
});
|
|
}
|
|
get emote() {
|
|
return this.emoteValue;
|
|
}
|
|
@Input()
|
|
set emote(value: string) {
|
|
if (this.emoteValue !== value) {
|
|
this.emoteValue = value;
|
|
this.zone.runOutsideAngular(() => this.redraw());
|
|
}
|
|
}
|
|
get scale() {
|
|
return this.scaleValue;
|
|
}
|
|
@Input()
|
|
set scale(value: number) {
|
|
if (this.scaleValue !== value) {
|
|
this.scaleValue = value;
|
|
this.zone.runOutsideAngular(() => this.redraw());
|
|
}
|
|
}
|
|
redraw() {
|
|
if (this.initialized) {
|
|
const emote = findEmoji(this.emote);
|
|
const sprite = font && emote && getCharacterSprite(emote.symbol, font);
|
|
const image = this.image.nativeElement as HTMLImageElement;
|
|
|
|
if (sprite) {
|
|
const width = sprite.w + sprite.ox;
|
|
const height = 10; // sprite.h + sprite.oy;
|
|
|
|
image.style.width = `${width * this.scale}px`;
|
|
image.style.height = `${height * this.scale}px`;
|
|
image.style.marginTop = `${-this.scale}px`;
|
|
image.style.display = 'inline-block';
|
|
image.style.visibility = 'hidden';
|
|
|
|
if (emote) {
|
|
image.setAttribute('aria-label', emote.names[0]);
|
|
}
|
|
|
|
getEmojiImageAsync(sprite, src => {
|
|
image.src = src;
|
|
image.alt = emote ? emote.symbol : '';
|
|
image.style.visibility = 'visible';
|
|
});
|
|
} else {
|
|
image.style.width = `0px`;
|
|
image.style.height = `0px`;
|
|
image.src = '';
|
|
image.alt = '';
|
|
}
|
|
}
|
|
}
|
|
}
|