export class Avatar {
nickname: string = '用户';
fontSize: number = 32;
size: number = 100;
colors: string[] = ['#1677ff'];
fontWeight: string = 'normal';
private canvas: HTMLCanvasElement | null = null;
private ctx: CanvasRenderingContext2D | null = null;
constructor(args?: Partial<Avatar>) {
Object.assign(this, args);
this.init();
}
private init(): void {
this.canvas = document.createElement('canvas');
this.canvas.width = this.size;
this.canvas.height = this.size;
this.ctx = this.canvas.getContext('2d');
}
private render(name?: string, color?: string): HTMLCanvasElement {
if (!this.canvas || !this.ctx) {
throw new Error('画布或上下文未正确初始化,请检查相关代码。');
}
this.clearCanvas();
const avatarName = this.getAvatarName(name);
const bgColor = color || this.getRandomColor();
this.drawBackground(bgColor);
this.drawText(avatarName);
return this.canvas;
}
create(name?: string, color?: string): string {
const canvas = this.render(name, color);
return canvas.toDataURL('image/png');
}
createAsync(name?: string, color?: string): Promise<string> {
const canvas = this.render(name, color);
return new Promise((resolve, reject) => {
canvas.toBlob((blob) => {
if (blob) {
resolve(URL.createObjectURL(blob));
} else {
reject(new Error('创建 Blob 失败,请检查相关代码。'));
}
}, 'image/png');
});
}
private getAvatarName(name?: string): string {
const avatarName = name || this.nickname;
return avatarName.length > 2 ? avatarName.slice(-2) : avatarName;
}
private getRandomColor(): string {
return this.colors[Math.floor(Math.random() * this.colors.length)];
}
private drawBackground(color: string): void {
if (!this.ctx) return;
this.ctx.fillStyle = color;
this.ctx.fillRect(0, 0, this.size, this.size);
}
private drawText(text: string): void {
if (!this.ctx) return;
this.ctx.fillStyle = '#FFFFFF';
this.ctx.font = `${this.fontWeight} ${this.fontSize}px serif`;
this.ctx.textAlign = 'center';
this.ctx.textBaseline = 'middle';
this.ctx.fillText(text, this.size / 2, this.size / 2);
}
private clearCanvas(): void {
if (!this.ctx || !this.canvas) return;
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
}
}