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
|
import {
Math as THREE_Math,
Sprite,
SpriteMaterial,
} from 'three';
import TextTexture from 'three.texttexture';
import getOptimalFontSize from './getOptimalFontSize';
export default class extends Sprite {
constructor({
textSize = 1,
redrawInterval = 1,
minFontSize = 0,
maxFontSize = Infinity,
material = {},
texture = {},
} = {}) {
super(new SpriteMaterial({
...material,
map: new TextTexture(texture),
}));
this.textSize = textSize;
this.redrawInterval = redrawInterval;
this.minFontSize = minFontSize;
this.maxFontSize = maxFontSize;
this.lastRedraw = 0;
}
get isTextSprite() {
return true;
}
onBeforeRender(renderer, scene, camera) {
this.redraw(renderer, camera);
}
updateScale() {
this.scale
.set(this.material.map.imageAspect, 1, 1)
.multiplyScalar(this.textSize * this.material.map.imageHeight);
}
updateMatrix(...args) {
this.updateScale();
return super.updateMatrix(...args);
}
redraw(renderer, camera) {
if (this.lastRedraw + this.redrawInterval < Date.now()) {
if (this.redrawInterval) {
setTimeout(() => {
this.redrawNow(renderer, camera);
}, 1);
} else {
this.redrawNow(renderer, camera);
}
}
}
redrawNow(renderer, camera) {
this.updateScale();
this.material.map.autoRedraw = true;
this.material.map.fontSize = THREE_Math.clamp(
THREE_Math.ceilPowerOfTwo(
getOptimalFontSize(this, renderer, camera)
),
this.minFontSize,
this.maxFontSize,
);
this.lastRedraw = Date.now();
}
dispose() {
this.material.map.dispose();
this.material.dispose();
}
}
|