three-text 0.2.1 → 0.2.3
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.
- package/README.md +44 -23
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/index.min.cjs +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.min.js +1 -1
- package/dist/p5/index.cjs +92 -13
- package/dist/p5/index.d.ts +8 -2
- package/dist/p5/index.js +92 -13
- package/dist/three/index.cjs +2 -2
- package/dist/three/index.js +3 -3
- package/dist/three/react.cjs +0 -7
- package/dist/three/react.js +0 -7
- package/dist/types/p5/index.d.ts +8 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@ A high fidelity 3D font renderer and text layout engine for the web
|
|
|
17
17
|
|
|
18
18
|
**three-text** renders and formats text from TTF, OTF, and WOFF font files as 3D geometry. It uses [TeX](https://en.wikipedia.org/wiki/TeX)-based parameters for breaking text into paragraphs across multiple lines, and turns font outlines into 3D shapes on the fly, caching their geometries for low CPU overhead in languages with lots of repeating glyphs. Variable fonts are supported as static instances at a given axis coordinate
|
|
19
19
|
|
|
20
|
-
The library has a framework-agnostic core that returns raw vertex data, with lightweight adapters for Three.js, React Three Fiber, p5.js, WebGL, and WebGPU
|
|
20
|
+
The library has a framework-agnostic core that returns raw vertex data, with lightweight adapters for [Three.js](https://threejs.org), [React Three Fiber](https://docs.pmnd.rs/react-three-fiber), [p5.js](https://p5js.org), [WebGL](https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API), and [WebGPU](https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API)
|
|
21
21
|
|
|
22
22
|
Under the hood, three-text relies on [HarfBuzz](https://github.com/harfbuzz/harfbuzzjs) for text shaping, [Knuth-Plass](http://www.eprg.org/G53DOC/pdfs/knuth-plass-breaking.pdf) line breaking, [Liang](https://tug.org/docs/liang/liang-thesis.pdf) hyphenation, [libtess2](https://github.com/memononen/libtess2) (based on the [OpenGL Utility Library (GLU) tessellator](https://www.songho.ca/opengl/gl_tessellation.html) by Eric Veach) for removing overlaps and triangulation, bezier curve polygonization from Maxim Shemanarev's [Anti-Grain Geometry](https://web.archive.org/web/20060128212843/http://www.antigrain.com/research/adaptive_bezier/index.html), and [Visvalingam-Whyatt](https://hull-repository.worktribe.com/preview/376364/000870493786962263.pdf) [line simplification](https://bost.ocks.org/mike/simplify/).
|
|
23
23
|
|
|
@@ -25,12 +25,9 @@ Under the hood, three-text relies on [HarfBuzz](https://github.com/harfbuzz/harf
|
|
|
25
25
|
|
|
26
26
|
- [Overview](#overview)
|
|
27
27
|
- [Getting started](#getting-started)
|
|
28
|
-
- [Three.js](#threejs
|
|
29
|
-
- [React Three Fiber](#react-three-fiber
|
|
30
|
-
- [
|
|
31
|
-
- [WebGPU](#webgpu-usage)
|
|
32
|
-
- [p5.js](#p5js-usage)
|
|
33
|
-
- [Core (framework-agnostic)](#core-usage)
|
|
28
|
+
- [Three.js](#threejs)
|
|
29
|
+
- [React Three Fiber](#react-three-fiber)
|
|
30
|
+
- [p5.js](#p5js)
|
|
34
31
|
- [Development and examples](#development-and-examples)
|
|
35
32
|
- [Architecture](#architecture)
|
|
36
33
|
- [Why three-text?](#why-three-text)
|
|
@@ -70,7 +67,7 @@ three-text has a framework-agnostic core that processes fonts and generates geom
|
|
|
70
67
|
- **`three-text/three/react`** - React Three Fiber component
|
|
71
68
|
- **`three-text/webgl`** - WebGL buffer utility
|
|
72
69
|
- **`three-text/webgpu`** - WebGPU buffer utility
|
|
73
|
-
- **`three-text/p5`** - p5.js
|
|
70
|
+
- **`three-text/p5`** - p5.js adapter
|
|
74
71
|
|
|
75
72
|
Choose the import that matches your stack. Most users will use `three-text/three` or `three-text/p5`
|
|
76
73
|
|
|
@@ -94,34 +91,58 @@ const mesh = new THREE.Mesh(result.geometry, material);
|
|
|
94
91
|
scene.add(mesh);
|
|
95
92
|
```
|
|
96
93
|
|
|
94
|
+
#### React Three Fiber
|
|
95
|
+
|
|
96
|
+
```jsx
|
|
97
|
+
import { Canvas } from '@react-three/fiber';
|
|
98
|
+
import { Text } from 'three-text/three/react';
|
|
99
|
+
|
|
100
|
+
Text.setHarfBuzzPath('/hb/hb.wasm');
|
|
101
|
+
|
|
102
|
+
function App() {
|
|
103
|
+
return (
|
|
104
|
+
<Canvas>
|
|
105
|
+
<ambientLight />
|
|
106
|
+
<Text font="/fonts/Font.woff" size={72} depth={10}>
|
|
107
|
+
Hello React
|
|
108
|
+
</Text>
|
|
109
|
+
</Canvas>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
97
114
|
#### p5.js
|
|
98
115
|
|
|
99
116
|
```javascript
|
|
100
|
-
import
|
|
101
|
-
|
|
117
|
+
import 'three-text/p5';
|
|
118
|
+
|
|
119
|
+
let font;
|
|
120
|
+
let textResult;
|
|
102
121
|
|
|
103
|
-
|
|
122
|
+
function preload() {
|
|
123
|
+
loadThreeTextShaper('/hb/hb.wasm');
|
|
124
|
+
font = loadThreeTextFont('/fonts/Font.woff');
|
|
125
|
+
}
|
|
104
126
|
|
|
105
127
|
async function setup() {
|
|
106
128
|
createCanvas(400, 400, WEBGL);
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
font: '/fonts/Font.woff',
|
|
112
|
-
size: 72
|
|
129
|
+
textResult = await createThreeTextGeometry('Hello p5!', {
|
|
130
|
+
font: font,
|
|
131
|
+
size: 72,
|
|
132
|
+
depth: 30
|
|
113
133
|
});
|
|
114
|
-
|
|
115
|
-
textGeom = createP5Geometry(window, data);
|
|
116
134
|
}
|
|
117
135
|
|
|
118
136
|
function draw() {
|
|
119
137
|
background(200);
|
|
120
138
|
lights();
|
|
121
|
-
model(
|
|
139
|
+
if (textResult) model(textResult.geometry);
|
|
122
140
|
}
|
|
123
141
|
```
|
|
124
142
|
|
|
143
|
+
`createThreeTextGeometry()` accepts all the same options as Three.js (`layout`, `fontVariations`, `depth`, etc.) and returns `{ geometry, planeBounds, glyphs }`. Use `planeBounds` to center the text
|
|
144
|
+
|
|
145
|
+
|
|
125
146
|
### Setup
|
|
126
147
|
|
|
127
148
|
The library bundles harfbuzzjs but requires the WASM binary to be available at runtime. You have two options for providing it:
|
|
@@ -244,7 +265,7 @@ three-text/
|
|
|
244
265
|
│ │ └── ThreeText.tsx # React Three Fiber component
|
|
245
266
|
│ ├── webgl/ # WebGL buffer utility
|
|
246
267
|
│ ├── webgpu/ # WebGPU buffer utility
|
|
247
|
-
│ ├── p5/ # p5.js
|
|
268
|
+
│ ├── p5/ # p5.js adapter
|
|
248
269
|
│ ├── hyphenation/ # Language-specific hyphenation patterns
|
|
249
270
|
│ └── utils/ # Performance logging, data structures
|
|
250
271
|
├── examples/ # Demos for all adapters
|
|
@@ -961,14 +982,14 @@ The build generates multiple module formats for core and all adapters:
|
|
|
961
982
|
- `dist/three/react.js` - React component
|
|
962
983
|
- `dist/webgl/` - WebGL utility
|
|
963
984
|
- `dist/webgpu/` - WebGPU utility
|
|
964
|
-
- `dist/p5/` - p5.js
|
|
985
|
+
- `dist/p5/` - p5.js adapter
|
|
965
986
|
|
|
966
987
|
**Patterns:**
|
|
967
988
|
- `dist/patterns/` - Hyphenation patterns (ESM and UMD)
|
|
968
989
|
|
|
969
990
|
## Acknowledgements
|
|
970
991
|
|
|
971
|
-
`three-text` is built on HarfBuzz and TeX, and this library would not exist without the authors and communities who contribute to, support, and steward these projects. Thanks to Theo Honohan and Yasi Perera for advice on graphics
|
|
992
|
+
`three-text` is built on HarfBuzz and TeX, and started as a Three.js project; this library would not exist without the authors and communities who contribute to, support, and steward these projects. Thanks to Theo Honohan and Yasi Perera for the advice on graphics
|
|
972
993
|
|
|
973
994
|
## License
|
|
974
995
|
|
package/dist/index.cjs
CHANGED
package/dist/index.js
CHANGED
package/dist/index.min.cjs
CHANGED
package/dist/index.min.js
CHANGED
package/dist/index.umd.js
CHANGED
package/dist/index.umd.min.js
CHANGED
package/dist/p5/index.cjs
CHANGED
|
@@ -1,21 +1,30 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const P5Geometry = p5Instance.Geometry || window.p5?.Geometry;
|
|
8
|
-
const createVec = p5Instance.createVector || window.createVector;
|
|
9
|
-
if (!P5Geometry || !createVec) {
|
|
10
|
-
throw new Error('p5.js not found. Make sure p5.js is loaded before calling this function.');
|
|
11
|
-
}
|
|
12
|
-
const geom = new P5Geometry();
|
|
3
|
+
var Text = require('../index.cjs');
|
|
4
|
+
|
|
5
|
+
// p5.js adapter
|
|
6
|
+
function convertToP5Geometry(p5Instance, textGeometry) {
|
|
13
7
|
const { vertices, normals, indices } = textGeometry;
|
|
14
|
-
|
|
8
|
+
const P5GeometryClass = p5Instance.constructor?.Geometry ||
|
|
9
|
+
(typeof window !== 'undefined' && window.p5?.Geometry);
|
|
10
|
+
if (!P5GeometryClass) {
|
|
11
|
+
throw new Error('p5.Geometry not found. Ensure p5.js is loaded.');
|
|
12
|
+
}
|
|
13
|
+
const geom = new P5GeometryClass();
|
|
14
|
+
const createVec = (x, y, z) => {
|
|
15
|
+
if (typeof p5Instance.createVector === 'function') {
|
|
16
|
+
return p5Instance.createVector(x, y, z);
|
|
17
|
+
}
|
|
18
|
+
const globalCreateVector = (typeof window !== 'undefined' && window.createVector);
|
|
19
|
+
if (globalCreateVector) {
|
|
20
|
+
return globalCreateVector(x, y, z);
|
|
21
|
+
}
|
|
22
|
+
throw new Error('createVector not found');
|
|
23
|
+
};
|
|
24
|
+
// p5 uses +Y up, we use +Y down
|
|
15
25
|
for (let i = 0; i < vertices.length; i += 3) {
|
|
16
26
|
geom.vertices.push(createVec(vertices[i], -vertices[i + 1], vertices[i + 2]));
|
|
17
27
|
}
|
|
18
|
-
// Convert normals (flip Y)
|
|
19
28
|
for (let i = 0; i < normals.length; i += 3) {
|
|
20
29
|
geom.vertexNormals.push(createVec(normals[i], -normals[i + 1], normals[i + 2]));
|
|
21
30
|
}
|
|
@@ -29,5 +38,75 @@ function createP5Geometry(p5Instance, textGeometry) {
|
|
|
29
38
|
}
|
|
30
39
|
return geom;
|
|
31
40
|
}
|
|
41
|
+
let shaperInitialized = false;
|
|
42
|
+
if (typeof window !== 'undefined' && window.p5) {
|
|
43
|
+
const p5 = window.p5;
|
|
44
|
+
p5.prototype.loadThreeTextShaper = function (wasmPath) {
|
|
45
|
+
if (shaperInitialized) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
Text.Text.setHarfBuzzPath(wasmPath);
|
|
49
|
+
shaperInitialized = true;
|
|
50
|
+
Text.Text.init()
|
|
51
|
+
.then(() => {
|
|
52
|
+
this._decrementPreload();
|
|
53
|
+
})
|
|
54
|
+
.catch((err) => {
|
|
55
|
+
console.error('Failed to load text shaper:', err);
|
|
56
|
+
this._decrementPreload();
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
p5.prototype.loadThreeTextFont = function (fontPath, fontVariations) {
|
|
60
|
+
const fontRef = {
|
|
61
|
+
buffer: null,
|
|
62
|
+
path: fontPath,
|
|
63
|
+
variations: fontVariations
|
|
64
|
+
};
|
|
65
|
+
fetch(fontPath)
|
|
66
|
+
.then(res => {
|
|
67
|
+
if (!res.ok) {
|
|
68
|
+
throw new Error(`Failed to load font: HTTP ${res.status}`);
|
|
69
|
+
}
|
|
70
|
+
return res.arrayBuffer();
|
|
71
|
+
})
|
|
72
|
+
.then(buffer => {
|
|
73
|
+
fontRef.buffer = buffer;
|
|
74
|
+
this._decrementPreload();
|
|
75
|
+
})
|
|
76
|
+
.catch((err) => {
|
|
77
|
+
console.error(`Failed to load font ${fontPath}:`, err);
|
|
78
|
+
this._decrementPreload();
|
|
79
|
+
});
|
|
80
|
+
return fontRef;
|
|
81
|
+
};
|
|
82
|
+
p5.prototype.createThreeTextGeometry = async function (text, options) {
|
|
83
|
+
if (!options.font || !options.font.buffer) {
|
|
84
|
+
console.error('Font not loaded. Use loadThreeTextFont() in preload().');
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
const { font, ...coreOptions } = options;
|
|
88
|
+
try {
|
|
89
|
+
const result = await Text.Text.create({
|
|
90
|
+
text,
|
|
91
|
+
font: font.buffer,
|
|
92
|
+
fontVariations: font.variations,
|
|
93
|
+
...coreOptions
|
|
94
|
+
});
|
|
95
|
+
const p5Instance = this;
|
|
96
|
+
const geometry = convertToP5Geometry(p5Instance, result);
|
|
97
|
+
return {
|
|
98
|
+
geometry,
|
|
99
|
+
planeBounds: result.planeBounds,
|
|
100
|
+
glyphs: result.glyphs
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
console.error('Failed to create text geometry:', err);
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
p5.prototype.registerPreloadMethod('loadThreeTextShaper', p5.prototype);
|
|
109
|
+
p5.prototype.registerPreloadMethod('loadThreeTextFont', p5.prototype);
|
|
110
|
+
}
|
|
32
111
|
|
|
33
|
-
exports.createP5Geometry =
|
|
112
|
+
exports.createP5Geometry = convertToP5Geometry;
|
package/dist/p5/index.d.ts
CHANGED
|
@@ -13,7 +13,13 @@ interface P5Geometry {
|
|
|
13
13
|
interface P5Instance {
|
|
14
14
|
Geometry: new () => P5Geometry;
|
|
15
15
|
createVector(x: number, y: number, z: number): P5Vector;
|
|
16
|
+
_decrementPreload(): void;
|
|
16
17
|
}
|
|
17
|
-
declare
|
|
18
|
+
declare global {
|
|
19
|
+
interface Window {
|
|
20
|
+
p5?: any;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
declare function convertToP5Geometry(p5Instance: P5Instance, textGeometry: TextGeometryInfo): P5Geometry;
|
|
18
24
|
|
|
19
|
-
export { createP5Geometry };
|
|
25
|
+
export { convertToP5Geometry as createP5Geometry };
|
package/dist/p5/index.js
CHANGED
|
@@ -1,19 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const P5Geometry = p5Instance.Geometry || window.p5?.Geometry;
|
|
6
|
-
const createVec = p5Instance.createVector || window.createVector;
|
|
7
|
-
if (!P5Geometry || !createVec) {
|
|
8
|
-
throw new Error('p5.js not found. Make sure p5.js is loaded before calling this function.');
|
|
9
|
-
}
|
|
10
|
-
const geom = new P5Geometry();
|
|
1
|
+
import { Text } from '../index.js';
|
|
2
|
+
|
|
3
|
+
// p5.js adapter
|
|
4
|
+
function convertToP5Geometry(p5Instance, textGeometry) {
|
|
11
5
|
const { vertices, normals, indices } = textGeometry;
|
|
12
|
-
|
|
6
|
+
const P5GeometryClass = p5Instance.constructor?.Geometry ||
|
|
7
|
+
(typeof window !== 'undefined' && window.p5?.Geometry);
|
|
8
|
+
if (!P5GeometryClass) {
|
|
9
|
+
throw new Error('p5.Geometry not found. Ensure p5.js is loaded.');
|
|
10
|
+
}
|
|
11
|
+
const geom = new P5GeometryClass();
|
|
12
|
+
const createVec = (x, y, z) => {
|
|
13
|
+
if (typeof p5Instance.createVector === 'function') {
|
|
14
|
+
return p5Instance.createVector(x, y, z);
|
|
15
|
+
}
|
|
16
|
+
const globalCreateVector = (typeof window !== 'undefined' && window.createVector);
|
|
17
|
+
if (globalCreateVector) {
|
|
18
|
+
return globalCreateVector(x, y, z);
|
|
19
|
+
}
|
|
20
|
+
throw new Error('createVector not found');
|
|
21
|
+
};
|
|
22
|
+
// p5 uses +Y up, we use +Y down
|
|
13
23
|
for (let i = 0; i < vertices.length; i += 3) {
|
|
14
24
|
geom.vertices.push(createVec(vertices[i], -vertices[i + 1], vertices[i + 2]));
|
|
15
25
|
}
|
|
16
|
-
// Convert normals (flip Y)
|
|
17
26
|
for (let i = 0; i < normals.length; i += 3) {
|
|
18
27
|
geom.vertexNormals.push(createVec(normals[i], -normals[i + 1], normals[i + 2]));
|
|
19
28
|
}
|
|
@@ -27,5 +36,75 @@ function createP5Geometry(p5Instance, textGeometry) {
|
|
|
27
36
|
}
|
|
28
37
|
return geom;
|
|
29
38
|
}
|
|
39
|
+
let shaperInitialized = false;
|
|
40
|
+
if (typeof window !== 'undefined' && window.p5) {
|
|
41
|
+
const p5 = window.p5;
|
|
42
|
+
p5.prototype.loadThreeTextShaper = function (wasmPath) {
|
|
43
|
+
if (shaperInitialized) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
Text.setHarfBuzzPath(wasmPath);
|
|
47
|
+
shaperInitialized = true;
|
|
48
|
+
Text.init()
|
|
49
|
+
.then(() => {
|
|
50
|
+
this._decrementPreload();
|
|
51
|
+
})
|
|
52
|
+
.catch((err) => {
|
|
53
|
+
console.error('Failed to load text shaper:', err);
|
|
54
|
+
this._decrementPreload();
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
p5.prototype.loadThreeTextFont = function (fontPath, fontVariations) {
|
|
58
|
+
const fontRef = {
|
|
59
|
+
buffer: null,
|
|
60
|
+
path: fontPath,
|
|
61
|
+
variations: fontVariations
|
|
62
|
+
};
|
|
63
|
+
fetch(fontPath)
|
|
64
|
+
.then(res => {
|
|
65
|
+
if (!res.ok) {
|
|
66
|
+
throw new Error(`Failed to load font: HTTP ${res.status}`);
|
|
67
|
+
}
|
|
68
|
+
return res.arrayBuffer();
|
|
69
|
+
})
|
|
70
|
+
.then(buffer => {
|
|
71
|
+
fontRef.buffer = buffer;
|
|
72
|
+
this._decrementPreload();
|
|
73
|
+
})
|
|
74
|
+
.catch((err) => {
|
|
75
|
+
console.error(`Failed to load font ${fontPath}:`, err);
|
|
76
|
+
this._decrementPreload();
|
|
77
|
+
});
|
|
78
|
+
return fontRef;
|
|
79
|
+
};
|
|
80
|
+
p5.prototype.createThreeTextGeometry = async function (text, options) {
|
|
81
|
+
if (!options.font || !options.font.buffer) {
|
|
82
|
+
console.error('Font not loaded. Use loadThreeTextFont() in preload().');
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
const { font, ...coreOptions } = options;
|
|
86
|
+
try {
|
|
87
|
+
const result = await Text.create({
|
|
88
|
+
text,
|
|
89
|
+
font: font.buffer,
|
|
90
|
+
fontVariations: font.variations,
|
|
91
|
+
...coreOptions
|
|
92
|
+
});
|
|
93
|
+
const p5Instance = this;
|
|
94
|
+
const geometry = convertToP5Geometry(p5Instance, result);
|
|
95
|
+
return {
|
|
96
|
+
geometry,
|
|
97
|
+
planeBounds: result.planeBounds,
|
|
98
|
+
glyphs: result.glyphs
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
console.error('Failed to create text geometry:', err);
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
p5.prototype.registerPreloadMethod('loadThreeTextShaper', p5.prototype);
|
|
107
|
+
p5.prototype.registerPreloadMethod('loadThreeTextFont', p5.prototype);
|
|
108
|
+
}
|
|
30
109
|
|
|
31
|
-
export { createP5Geometry };
|
|
110
|
+
export { convertToP5Geometry as createP5Geometry };
|
package/dist/three/index.cjs
CHANGED
|
@@ -19,8 +19,8 @@ class Text {
|
|
|
19
19
|
const geometry = new three.BufferGeometry();
|
|
20
20
|
geometry.setAttribute('position', new three.Float32BufferAttribute(coreResult.vertices, 3));
|
|
21
21
|
geometry.setAttribute('normal', new three.Float32BufferAttribute(coreResult.normals, 3));
|
|
22
|
-
geometry.setIndex(
|
|
23
|
-
// Add optional
|
|
22
|
+
geometry.setIndex(new three.Uint32BufferAttribute(coreResult.indices, 1));
|
|
23
|
+
// Add optional color attribute (only if provided)
|
|
24
24
|
if (coreResult.colors) {
|
|
25
25
|
geometry.setAttribute('color', new three.Float32BufferAttribute(coreResult.colors, 3));
|
|
26
26
|
}
|
package/dist/three/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BufferGeometry, Float32BufferAttribute } from 'three';
|
|
1
|
+
import { BufferGeometry, Float32BufferAttribute, Uint32BufferAttribute } from 'three';
|
|
2
2
|
import { Text as Text$1 } from '../index.js';
|
|
3
3
|
|
|
4
4
|
// Three.js adapter - wraps core text processing and returns BufferGeometry
|
|
@@ -17,8 +17,8 @@ class Text {
|
|
|
17
17
|
const geometry = new BufferGeometry();
|
|
18
18
|
geometry.setAttribute('position', new Float32BufferAttribute(coreResult.vertices, 3));
|
|
19
19
|
geometry.setAttribute('normal', new Float32BufferAttribute(coreResult.normals, 3));
|
|
20
|
-
geometry.setIndex(
|
|
21
|
-
// Add optional
|
|
20
|
+
geometry.setIndex(new Uint32BufferAttribute(coreResult.indices, 1));
|
|
21
|
+
// Add optional color attribute (only if provided)
|
|
22
22
|
if (coreResult.colors) {
|
|
23
23
|
geometry.setAttribute('color', new Float32BufferAttribute(coreResult.colors, 3));
|
|
24
24
|
}
|
package/dist/three/react.cjs
CHANGED
|
@@ -72,13 +72,6 @@ const Text$1 = react.forwardRef(function Text(props, ref) {
|
|
|
72
72
|
font,
|
|
73
73
|
...memoizedTextOptions,
|
|
74
74
|
});
|
|
75
|
-
if (text.geometry &&
|
|
76
|
-
!text.geometry.attributes.color &&
|
|
77
|
-
vertexColors) {
|
|
78
|
-
const vertexCount = text.geometry.attributes.position.count;
|
|
79
|
-
const colors = new Float32Array(vertexCount * 3).fill(1.0);
|
|
80
|
-
text.geometry.setAttribute("color", new THREE__namespace.BufferAttribute(colors, 3));
|
|
81
|
-
}
|
|
82
75
|
if (!cancelled) {
|
|
83
76
|
setGeometry(text.geometry);
|
|
84
77
|
if (onLoad)
|
package/dist/three/react.js
CHANGED
|
@@ -51,13 +51,6 @@ const Text$1 = forwardRef(function Text(props, ref) {
|
|
|
51
51
|
font,
|
|
52
52
|
...memoizedTextOptions,
|
|
53
53
|
});
|
|
54
|
-
if (text.geometry &&
|
|
55
|
-
!text.geometry.attributes.color &&
|
|
56
|
-
vertexColors) {
|
|
57
|
-
const vertexCount = text.geometry.attributes.position.count;
|
|
58
|
-
const colors = new Float32Array(vertexCount * 3).fill(1.0);
|
|
59
|
-
text.geometry.setAttribute("color", new THREE.BufferAttribute(colors, 3));
|
|
60
|
-
}
|
|
61
54
|
if (!cancelled) {
|
|
62
55
|
setGeometry(text.geometry);
|
|
63
56
|
if (onLoad)
|
package/dist/types/p5/index.d.ts
CHANGED
|
@@ -12,6 +12,12 @@ interface P5Geometry {
|
|
|
12
12
|
interface P5Instance {
|
|
13
13
|
Geometry: new () => P5Geometry;
|
|
14
14
|
createVector(x: number, y: number, z: number): P5Vector;
|
|
15
|
+
_decrementPreload(): void;
|
|
15
16
|
}
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
declare global {
|
|
18
|
+
interface Window {
|
|
19
|
+
p5?: any;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
declare function convertToP5Geometry(p5Instance: P5Instance, textGeometry: TextGeometryInfo): P5Geometry;
|
|
23
|
+
export { convertToP5Geometry as createP5Geometry };
|