@damienmortini/three 0.1.182 → 0.1.183

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,241 +1,241 @@
1
- import {
2
- Object3D,
3
- Mesh,
4
- PlaneGeometry,
5
- Texture,
6
- } from '../../../three/src/Three.js'
7
-
8
- import THREEShaderMaterial from '../material/THREEShaderMaterial.js'
9
-
10
- export default class THREEText extends Object3D {
11
- constructor({
12
- textContent = '',
13
- font = '10px sans-serif',
14
- fillStyle = 'black',
15
- textAlign = 'start',
16
- shadowColor = 'rgba(0, 0, 0 ,0)',
17
- shadowBlur = 0,
18
- shadowOffsetX = 0,
19
- shadowOffsetY = 0,
20
- scale = 1,
21
- maxWidth = Infinity,
22
- geometry = new PlaneGeometry(1, 1),
23
- material = new THREEShaderMaterial({
24
- type: 'basic',
25
- transparent: true,
26
- }),
27
- } = {}) {
28
- super()
29
-
30
- this._scale = scale
31
-
32
- this._canvas = document.createElement('canvas')
33
- this._context = this._canvas.getContext('2d')
34
-
35
- this._texture = new Texture(this._canvas)
36
-
37
- material.map = this._texture
38
-
39
- this.textContent = textContent
40
- this.font = font
41
- this.fillStyle = fillStyle
42
- this.textAlign = textAlign
43
- this.maxWidth = maxWidth
44
- this.shadowColor = shadowColor
45
- this.shadowBlur = shadowBlur
46
- this.shadowOffsetX = shadowOffsetX
47
- this.shadowOffsetY = shadowOffsetY
48
-
49
- this._mesh = new Mesh(geometry, material)
50
- this.add(this._mesh)
51
-
52
- this._update()
53
- }
54
-
55
- _updateContextProperties() {
56
- this._context.font = this.font
57
- this._context.fillStyle = this.fillStyle
58
- this._context.shadowColor = this.shadowColor
59
- this._context.shadowBlur = this.shadowBlur
60
- this._context.shadowOffsetX = this.shadowOffsetX
61
- this._context.shadowOffsetY = this.shadowOffsetY
62
- this._context.textBaseline = 'top'
63
- }
64
-
65
- _update() {
66
- if (!this._mesh) {
67
- return
68
- }
69
-
70
- this._updateContextProperties()
71
-
72
- const shadowOffsetX = this.shadowOffsetX - this.shadowBlur
73
- const shadowOffsetY = this.shadowOffsetY - this.shadowBlur
74
-
75
- const words = this.textContent.split(' ')
76
-
77
- const spaceWidth = this._context.measureText(' ').width
78
- const wordsWidth = new Map()
79
- const lines = [{
80
- textContent: '',
81
- width: 0,
82
- }]
83
- for (const word of words) {
84
- if (!wordsWidth.get(word)) {
85
- wordsWidth.set(word, this._context.measureText(word).width)
86
- }
87
- }
88
-
89
- let width = 0
90
- let lineNumber = 0
91
- for (const word of words) {
92
- const newWidth = lines[lineNumber].width + wordsWidth.get(word)
93
-
94
- if (newWidth > this.maxWidth) {
95
- lineNumber++
96
- lines[lineNumber] = {
97
- textContent: word,
98
- width: wordsWidth.get(word),
99
- }
100
- } else {
101
- if (lines[lineNumber].textContent !== '') {
102
- lines[lineNumber].textContent += ' '
103
- }
104
- lines[lineNumber].textContent += word
105
- lines[lineNumber].width += spaceWidth + wordsWidth.get(word)
106
- }
107
- width = Math.max(width, lines[lineNumber].width)
108
- }
109
-
110
- width += this.shadowBlur * 2 + Math.abs(this.shadowOffsetX)
111
-
112
- const lineHeight = parseFloat(/\b(\d*)px/.exec(this._context.font)[1])
113
- let height = lineHeight
114
- height *= lines.length
115
- height += this.shadowBlur * 2 + Math.abs(this.shadowOffsetY)
116
-
117
- if (this._canvas.width !== width || this._canvas.height !== height) {
118
- this._canvas.width = width
119
- this._canvas.height = height
120
- this._updateContextProperties()
121
- }
122
-
123
- this._mesh.position.y = -shadowOffsetY * .5 * this._scale
124
-
125
- if (this.textAlign === 'start' || this.textAlign === 'left') {
126
- this._mesh.position.x = (this._canvas.width * .5 + Math.min(0, shadowOffsetX)) * this._scale
127
- } else if (this.textAlign === 'end' || this.textAlign === 'right') {
128
- this._mesh.position.x = (-this._canvas.width * .5 + Math.max(0, shadowOffsetX)) * this._scale
129
- } else {
130
- this._mesh.position.x = shadowOffsetX * .5 * this._scale
131
- }
132
- this._mesh.scale.x = this._canvas.width * this._scale
133
- this._mesh.scale.y = this._canvas.height * this._scale
134
- this._context.globalAlpha = 1 / 255
135
- this._context.fillRect(0, 0, width, height)
136
- this._context.globalAlpha = 1
137
- for (const [i, line] of lines.entries()) {
138
- let offsetX
139
- switch (this.textAlign) {
140
- case 'start':
141
- case 'left':
142
- offsetX = 0
143
- break
144
- case 'center':
145
- offsetX = (width - line.width) * .5
146
- break
147
- case 'end':
148
- case 'right':
149
- offsetX = width - line.width
150
- break
151
- }
152
- this._context.fillText(line.textContent, offsetX + (shadowOffsetX < 0 ? Math.abs(shadowOffsetX) : 0), (shadowOffsetY < 0 ? Math.abs(shadowOffsetY) : 0) + lineHeight * i)
153
- }
154
- this._texture.needsUpdate = true
155
- }
156
-
157
- get material() {
158
- return this._mesh.material
159
- }
160
-
161
- set textContent(value) {
162
- this._textContent = value
163
- this._update()
164
- }
165
-
166
- get textContent() {
167
- return this._textContent
168
- }
169
-
170
- set font(value) {
171
- this._context.font = this._font = value
172
- this._update()
173
- }
174
-
175
- get font() {
176
- return this._font
177
- }
178
-
179
- set fillStyle(value) {
180
- this._context.fillStyle = this._fillStyle = value
181
- this._update()
182
- }
183
-
184
- get fillStyle() {
185
- return this._fillStyle
186
- }
187
-
188
- set textAlign(value) {
189
- this._textAlign = value
190
- this._update()
191
- }
192
-
193
- get textAlign() {
194
- return this._textAlign
195
- }
196
-
197
- set maxWidth(value) {
198
- this._maxWidth = value
199
- this._update()
200
- }
201
-
202
- get maxWidth() {
203
- return this._maxWidth
204
- }
205
-
206
- set shadowColor(value) {
207
- this._context.shadowColor = this._shadowColor = value
208
- this._update()
209
- }
210
-
211
- get shadowColor() {
212
- return this._shadowColor
213
- }
214
-
215
- set shadowBlur(value) {
216
- this._context.shadowBlur = this._shadowBlur = value
217
- this._update()
218
- }
219
-
220
- get shadowBlur() {
221
- return this._shadowBlur
222
- }
223
-
224
- set shadowOffsetX(value) {
225
- this._context.shadowOffsetX = this._shadowOffsetX = value
226
- this._update()
227
- }
228
-
229
- get shadowOffsetX() {
230
- return this._shadowOffsetX
231
- }
232
-
233
- set shadowOffsetY(value) {
234
- this._context.shadowOffsetY = this._shadowOffsetY = value
235
- this._update()
236
- }
237
-
238
- get shadowOffsetY() {
239
- return this._shadowOffsetY
240
- }
241
- }
1
+ import {
2
+ Object3D,
3
+ Mesh,
4
+ PlaneGeometry,
5
+ Texture,
6
+ } from '../../../three/src/Three.js'
7
+
8
+ import THREEShaderMaterial from '../material/THREEShaderMaterial.js'
9
+
10
+ export default class THREEText extends Object3D {
11
+ constructor({
12
+ textContent = '',
13
+ font = '10px sans-serif',
14
+ fillStyle = 'black',
15
+ textAlign = 'start',
16
+ shadowColor = 'rgba(0, 0, 0 ,0)',
17
+ shadowBlur = 0,
18
+ shadowOffsetX = 0,
19
+ shadowOffsetY = 0,
20
+ scale = 1,
21
+ maxWidth = Infinity,
22
+ geometry = new PlaneGeometry(1, 1),
23
+ material = new THREEShaderMaterial({
24
+ type: 'basic',
25
+ transparent: true,
26
+ }),
27
+ } = {}) {
28
+ super()
29
+
30
+ this._scale = scale
31
+
32
+ this._canvas = document.createElement('canvas')
33
+ this._context = this._canvas.getContext('2d')
34
+
35
+ this._texture = new Texture(this._canvas)
36
+
37
+ material.map = this._texture
38
+
39
+ this.textContent = textContent
40
+ this.font = font
41
+ this.fillStyle = fillStyle
42
+ this.textAlign = textAlign
43
+ this.maxWidth = maxWidth
44
+ this.shadowColor = shadowColor
45
+ this.shadowBlur = shadowBlur
46
+ this.shadowOffsetX = shadowOffsetX
47
+ this.shadowOffsetY = shadowOffsetY
48
+
49
+ this._mesh = new Mesh(geometry, material)
50
+ this.add(this._mesh)
51
+
52
+ this._update()
53
+ }
54
+
55
+ _updateContextProperties() {
56
+ this._context.font = this.font
57
+ this._context.fillStyle = this.fillStyle
58
+ this._context.shadowColor = this.shadowColor
59
+ this._context.shadowBlur = this.shadowBlur
60
+ this._context.shadowOffsetX = this.shadowOffsetX
61
+ this._context.shadowOffsetY = this.shadowOffsetY
62
+ this._context.textBaseline = 'top'
63
+ }
64
+
65
+ _update() {
66
+ if (!this._mesh) {
67
+ return
68
+ }
69
+
70
+ this._updateContextProperties()
71
+
72
+ const shadowOffsetX = this.shadowOffsetX - this.shadowBlur
73
+ const shadowOffsetY = this.shadowOffsetY - this.shadowBlur
74
+
75
+ const words = this.textContent.split(' ')
76
+
77
+ const spaceWidth = this._context.measureText(' ').width
78
+ const wordsWidth = new Map()
79
+ const lines = [{
80
+ textContent: '',
81
+ width: 0,
82
+ }]
83
+ for (const word of words) {
84
+ if (!wordsWidth.get(word)) {
85
+ wordsWidth.set(word, this._context.measureText(word).width)
86
+ }
87
+ }
88
+
89
+ let width = 0
90
+ let lineNumber = 0
91
+ for (const word of words) {
92
+ const newWidth = lines[lineNumber].width + wordsWidth.get(word)
93
+
94
+ if (newWidth > this.maxWidth) {
95
+ lineNumber++
96
+ lines[lineNumber] = {
97
+ textContent: word,
98
+ width: wordsWidth.get(word),
99
+ }
100
+ } else {
101
+ if (lines[lineNumber].textContent !== '') {
102
+ lines[lineNumber].textContent += ' '
103
+ }
104
+ lines[lineNumber].textContent += word
105
+ lines[lineNumber].width += spaceWidth + wordsWidth.get(word)
106
+ }
107
+ width = Math.max(width, lines[lineNumber].width)
108
+ }
109
+
110
+ width += this.shadowBlur * 2 + Math.abs(this.shadowOffsetX)
111
+
112
+ const lineHeight = parseFloat(/\b(\d*)px/.exec(this._context.font)[1])
113
+ let height = lineHeight
114
+ height *= lines.length
115
+ height += this.shadowBlur * 2 + Math.abs(this.shadowOffsetY)
116
+
117
+ if (this._canvas.width !== width || this._canvas.height !== height) {
118
+ this._canvas.width = width
119
+ this._canvas.height = height
120
+ this._updateContextProperties()
121
+ }
122
+
123
+ this._mesh.position.y = -shadowOffsetY * .5 * this._scale
124
+
125
+ if (this.textAlign === 'start' || this.textAlign === 'left') {
126
+ this._mesh.position.x = (this._canvas.width * .5 + Math.min(0, shadowOffsetX)) * this._scale
127
+ } else if (this.textAlign === 'end' || this.textAlign === 'right') {
128
+ this._mesh.position.x = (-this._canvas.width * .5 + Math.max(0, shadowOffsetX)) * this._scale
129
+ } else {
130
+ this._mesh.position.x = shadowOffsetX * .5 * this._scale
131
+ }
132
+ this._mesh.scale.x = this._canvas.width * this._scale
133
+ this._mesh.scale.y = this._canvas.height * this._scale
134
+ this._context.globalAlpha = 1 / 255
135
+ this._context.fillRect(0, 0, width, height)
136
+ this._context.globalAlpha = 1
137
+ for (const [i, line] of lines.entries()) {
138
+ let offsetX
139
+ switch (this.textAlign) {
140
+ case 'start':
141
+ case 'left':
142
+ offsetX = 0
143
+ break
144
+ case 'center':
145
+ offsetX = (width - line.width) * .5
146
+ break
147
+ case 'end':
148
+ case 'right':
149
+ offsetX = width - line.width
150
+ break
151
+ }
152
+ this._context.fillText(line.textContent, offsetX + (shadowOffsetX < 0 ? Math.abs(shadowOffsetX) : 0), (shadowOffsetY < 0 ? Math.abs(shadowOffsetY) : 0) + lineHeight * i)
153
+ }
154
+ this._texture.needsUpdate = true
155
+ }
156
+
157
+ get material() {
158
+ return this._mesh.material
159
+ }
160
+
161
+ set textContent(value) {
162
+ this._textContent = value
163
+ this._update()
164
+ }
165
+
166
+ get textContent() {
167
+ return this._textContent
168
+ }
169
+
170
+ set font(value) {
171
+ this._context.font = this._font = value
172
+ this._update()
173
+ }
174
+
175
+ get font() {
176
+ return this._font
177
+ }
178
+
179
+ set fillStyle(value) {
180
+ this._context.fillStyle = this._fillStyle = value
181
+ this._update()
182
+ }
183
+
184
+ get fillStyle() {
185
+ return this._fillStyle
186
+ }
187
+
188
+ set textAlign(value) {
189
+ this._textAlign = value
190
+ this._update()
191
+ }
192
+
193
+ get textAlign() {
194
+ return this._textAlign
195
+ }
196
+
197
+ set maxWidth(value) {
198
+ this._maxWidth = value
199
+ this._update()
200
+ }
201
+
202
+ get maxWidth() {
203
+ return this._maxWidth
204
+ }
205
+
206
+ set shadowColor(value) {
207
+ this._context.shadowColor = this._shadowColor = value
208
+ this._update()
209
+ }
210
+
211
+ get shadowColor() {
212
+ return this._shadowColor
213
+ }
214
+
215
+ set shadowBlur(value) {
216
+ this._context.shadowBlur = this._shadowBlur = value
217
+ this._update()
218
+ }
219
+
220
+ get shadowBlur() {
221
+ return this._shadowBlur
222
+ }
223
+
224
+ set shadowOffsetX(value) {
225
+ this._context.shadowOffsetX = this._shadowOffsetX = value
226
+ this._update()
227
+ }
228
+
229
+ get shadowOffsetX() {
230
+ return this._shadowOffsetX
231
+ }
232
+
233
+ set shadowOffsetY(value) {
234
+ this._context.shadowOffsetY = this._shadowOffsetY = value
235
+ this._update()
236
+ }
237
+
238
+ get shadowOffsetY() {
239
+ return this._shadowOffsetY
240
+ }
241
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@damienmortini/three",
3
- "version": "0.1.182",
3
+ "version": "0.1.183",
4
4
  "description": "Three.js helpers",
5
5
  "scripts": {
6
6
  "install": "npm run copyexamples",
@@ -28,9 +28,9 @@
28
28
  "bugs": "https://github.com/damienmortini/lib/issues",
29
29
  "homepage": "https://github.com/damienmortini/lib/tree/main/packages/three",
30
30
  "dependencies": {
31
- "@damienmortini/core": "^0.2.143",
31
+ "@damienmortini/core": "^0.2.144",
32
32
  "fs-extra": "^11.1.0",
33
33
  "three": "0.149.0"
34
34
  },
35
- "gitHead": "9c39ac87a4d53c7be6b0c9cf128b892e4fd3abc3"
35
+ "gitHead": "a374cfe16eaed4d1bfd283b3fc544d6c5665d1ac"
36
36
  }