summaryrefslogtreecommitdiff
path: root/site/public/assets/demo/cloud/src/index.js
blob: 270891d570104004298133da535ad6ed9a7e7c79 (plain)
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();
	}
}