three-text 0.2.0 → 0.2.2

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/dist/p5/index.cjs CHANGED
@@ -1,21 +1,30 @@
1
1
  'use strict';
2
2
 
3
- // p5.js adapter - converts core geometry to p5.Geometry
4
- function createP5Geometry(p5Instance, textGeometry) {
5
- // In global mode, p5.Geometry exists but createVector is global
6
- // In instance mode, both are on the instance
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
- // Convert vertices (flip Y for p5.js coordinate system)
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 = createP5Geometry;
112
+ exports.createP5Geometry = convertToP5Geometry;
@@ -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 function createP5Geometry(p5Instance: P5Instance | any, textGeometry: TextGeometryInfo): P5Geometry;
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
- // p5.js adapter - converts core geometry to p5.Geometry
2
- function createP5Geometry(p5Instance, textGeometry) {
3
- // In global mode, p5.Geometry exists but createVector is global
4
- // In instance mode, both are on the instance
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
- // Convert vertices (flip Y for p5.js coordinate system)
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 };
@@ -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
- export declare function createP5Geometry(p5Instance: P5Instance | any, textGeometry: TextGeometryInfo): P5Geometry;
17
- export {};
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 };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "three-text",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "3D font rendering and text layout engine for the web",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",