File size: 2,293 Bytes
5b324f1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import { Texture, Sprite, SRGBColorSpace, SpriteMaterial, DoubleSide } from "three";

export class TextSprite {
	private canvas: HTMLCanvasElement;
	private context: CanvasRenderingContext2D;
	private texture: Texture;
	private sprite: Sprite;
	private fontSize: number;
	private color: string;
	private strokeWidth: number;
	private lineHight: number;

	constructor(text: string, fontSize: number, color: string, strokeWidth: number, lineHight: number) {
		this.fontSize = fontSize;
		this.color = color;
		this.strokeWidth = strokeWidth;
		this.lineHight = lineHight;

		// 创建画布
		this.canvas = document.createElement("canvas");
		const resolution = 10;
		this.canvas.width = fontSize * resolution;
		this.canvas.height = fontSize * resolution;

		this.context = this.canvas.getContext("2d") as CanvasRenderingContext2D;
		this.texture = new Texture(this.canvas);
		this.texture.needsUpdate = true;
		this.texture.colorSpace = SRGBColorSpace;

		// 创建材质和精灵
		const material = new SpriteMaterial({
			map: this.texture,
			depthWrite: false,
			transparent: true,
			side: DoubleSide,
		});
		this.sprite = new Sprite(material);

		// 初始化文字
		this.updateText(text);
	}

	// 更新文字的方法,支持换行
	public updateText(text: string, color = this.color) {
		const { context, canvas, fontSize, strokeWidth } = this;

		// 清空画布
		context.clearRect(0, 0, canvas.width, canvas.height);

		// 设置样式
		context.fillStyle = color;
		context.font = `bold ${fontSize}px ContentFont`;
		context.textBaseline = "middle";
		context.textAlign = "center";
		context.lineWidth = strokeWidth;
		context.strokeStyle = "#fff";

		// 处理换行
		const lines = text.split("\n");
		const lineHeight = this.lineHight; // 设置行高,可以调整
		const totalHeight = lineHeight * lines.length;
		const startY = -totalHeight / 2 + lineHeight / 2;

		context.save();
		context.translate(canvas.width / 2, canvas.height / 2);

		// 绘制每行文字
		lines.forEach((line, index) => {
			const y = startY + index * lineHeight;
			context.strokeText(line, 0, y);
			context.fillText(line, 0, y);
		});

		context.restore();

		// 更新纹理
		this.texture.needsUpdate = true;
	}

	// 获取精灵对象
	public getSprite() {
		return this.sprite;
	}
}