@appinternalleads/ui 0.4.1 → 0.4.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.
Files changed (70) hide show
  1. package/README.md +92 -0
  2. package/dist/cjs/motion/typesurface/TypeSurfaceCanvas.js +25 -2
  3. package/dist/cjs/motion/typesurface/TypeSurfaceCanvas.js.map +1 -1
  4. package/dist/cjs/motion/typesurface/config.js +21 -1
  5. package/dist/cjs/motion/typesurface/config.js.map +1 -1
  6. package/dist/cjs/motion/typesurface/construct.js +875 -0
  7. package/dist/cjs/motion/typesurface/construct.js.map +1 -0
  8. package/dist/cjs/motion/typesurface/engine.js +28 -4
  9. package/dist/cjs/motion/typesurface/engine.js.map +1 -1
  10. package/dist/cjs/motion/typesurface/index.js +9 -1
  11. package/dist/cjs/motion/typesurface/index.js.map +1 -1
  12. package/dist/cjs/motion/typesurface/presets.js +69 -2
  13. package/dist/cjs/motion/typesurface/presets.js.map +1 -1
  14. package/dist/cjs/motion/typesurface/renderer.js +81 -15
  15. package/dist/cjs/motion/typesurface/renderer.js.map +1 -1
  16. package/dist/cjs/motion/typesurface/shaders.js +23 -1
  17. package/dist/cjs/motion/typesurface/shaders.js.map +1 -1
  18. package/dist/cjs/motion/typesurface/surfaces.js +69 -0
  19. package/dist/cjs/motion/typesurface/surfaces.js.map +1 -1
  20. package/dist/esm/motion/typesurface/TypeSurfaceCanvas.d.ts +11 -1
  21. package/dist/esm/motion/typesurface/TypeSurfaceCanvas.d.ts.map +1 -1
  22. package/dist/esm/motion/typesurface/TypeSurfaceCanvas.js +25 -2
  23. package/dist/esm/motion/typesurface/TypeSurfaceCanvas.js.map +1 -1
  24. package/dist/esm/motion/typesurface/config.d.ts +13 -2
  25. package/dist/esm/motion/typesurface/config.d.ts.map +1 -1
  26. package/dist/esm/motion/typesurface/config.js +21 -1
  27. package/dist/esm/motion/typesurface/config.js.map +1 -1
  28. package/dist/esm/motion/typesurface/construct.d.ts +284 -0
  29. package/dist/esm/motion/typesurface/construct.d.ts.map +1 -0
  30. package/dist/esm/motion/typesurface/construct.js +866 -0
  31. package/dist/esm/motion/typesurface/construct.js.map +1 -0
  32. package/dist/esm/motion/typesurface/engine.d.ts +8 -0
  33. package/dist/esm/motion/typesurface/engine.d.ts.map +1 -1
  34. package/dist/esm/motion/typesurface/engine.js +28 -4
  35. package/dist/esm/motion/typesurface/engine.js.map +1 -1
  36. package/dist/esm/motion/typesurface/index.d.ts +7 -3
  37. package/dist/esm/motion/typesurface/index.d.ts.map +1 -1
  38. package/dist/esm/motion/typesurface/index.js +6 -2
  39. package/dist/esm/motion/typesurface/index.js.map +1 -1
  40. package/dist/esm/motion/typesurface/presets.d.ts +18 -0
  41. package/dist/esm/motion/typesurface/presets.d.ts.map +1 -1
  42. package/dist/esm/motion/typesurface/presets.js +68 -3
  43. package/dist/esm/motion/typesurface/presets.js.map +1 -1
  44. package/dist/esm/motion/typesurface/renderer.d.ts +10 -0
  45. package/dist/esm/motion/typesurface/renderer.d.ts.map +1 -1
  46. package/dist/esm/motion/typesurface/renderer.js +82 -16
  47. package/dist/esm/motion/typesurface/renderer.js.map +1 -1
  48. package/dist/esm/motion/typesurface/shaders.d.ts +1 -1
  49. package/dist/esm/motion/typesurface/shaders.d.ts.map +1 -1
  50. package/dist/esm/motion/typesurface/shaders.js +23 -1
  51. package/dist/esm/motion/typesurface/shaders.js.map +1 -1
  52. package/dist/esm/motion/typesurface/surfaces.d.ts +28 -1
  53. package/dist/esm/motion/typesurface/surfaces.d.ts.map +1 -1
  54. package/dist/esm/motion/typesurface/surfaces.js +67 -0
  55. package/dist/esm/motion/typesurface/surfaces.js.map +1 -1
  56. package/docs/TYPE-SURFACE.md +183 -0
  57. package/package.json +4 -2
  58. package/src/motion/typesurface/TypeSurfaceCanvas.tsx +30 -2
  59. package/src/motion/typesurface/config.ts +29 -3
  60. package/src/motion/typesurface/construct.ts +828 -0
  61. package/src/motion/typesurface/engine.ts +31 -5
  62. package/src/motion/typesurface/index.ts +7 -3
  63. package/src/motion/typesurface/presets.ts +75 -3
  64. package/src/motion/typesurface/renderer.ts +77 -17
  65. package/src/motion/typesurface/shaders.ts +23 -1
  66. package/src/motion/typesurface/surfaces.ts +78 -1
  67. package/tools/ask/dist/components.mjs +1138 -57
  68. package/tools/ask/dist/neon.js +69 -0
  69. package/tools/ask/mcp.mjs +90 -5
  70. package/tools/ask/neon-render.mjs +143 -0
@@ -7,7 +7,7 @@
7
7
  * mode, against the paper under them), its grain, ragged edges, and a halftone screen
8
8
  * depth the shadow pass (letters cast their shape while they float)
9
9
  */
10
- export declare const COMMON = "#version 300 es\nprecision highp float;\nprecision highp sampler2DShadow;\nuniform vec3 uLightDir;\nuniform vec3 uEye;\nuniform mat4 uLightVP;\nuniform sampler2DShadow uShadow;\nuniform vec3 uKey;\nuniform float uAmb;\nuniform vec3 uBackdrop;\nuniform vec3 uTarget;\nuniform float uRadius;\n\nvec3 toLin(vec3 c) { return pow(max(c, 0.0), vec3(2.2)); }\nvec3 toSrgb(vec3 c) { return pow(max(c, 0.0), vec3(1.0 / 2.2)); }\nvec3 tone(vec3 c) { c *= 0.92; return clamp((c * (2.51 * c + 0.03)) / (c * (2.43 * c + 0.59) + 0.14), 0.0, 1.0); }\n\nfloat shadowAt(vec3 wp, vec3 n) {\n vec4 lp = uLightVP * vec4(wp + n * 0.003, 1.0);\n vec3 c = lp.xyz / lp.w * 0.5 + 0.5;\n if (c.x < 0.0 || c.x > 1.0 || c.y < 0.0 || c.y > 1.0 || c.z > 1.0) return 1.0;\n vec2 texel = 1.0 / vec2(textureSize(uShadow, 0));\n float s = 0.0;\n for (int x = -2; x <= 2; x++) for (int y = -2; y <= 2; y++) s += texture(uShadow, vec3(c.xy + vec2(x, y) * texel * 1.5, c.z - 0.0012));\n return s / 25.0;\n}\n\nvec3 shade(vec3 alb, vec3 n, vec3 wp, float cav, float spec, float rough, float translucency) {\n float sh = shadowAt(wp, n);\n float nl = dot(n, uLightDir);\n float diff = max(nl, 0.0) * sh;\n float back = max(-nl, 0.0) * translucency;\n vec3 sky = vec3(0.66, 0.68, 0.74), gnd = vec3(0.3, 0.27, 0.23);\n vec3 amb = mix(gnd, sky, n.z * 0.5 + 0.5) * (1.0 - max(cav, 0.0) * 0.6) * (0.75 + 0.25 * sh);\n vec3 V = normalize(uEye - wp);\n vec3 H = normalize(uLightDir + V);\n float sp = pow(max(dot(n, H), 0.0), mix(6.0, 160.0, 1.0 - rough)) * spec * sh;\n return alb * (uKey * (diff + back) + amb * uAmb) + uKey * sp;\n}\n\n/** A photo studio, as seen in a reflection: dim room, the key softbox toward the light, a long strip light opposite. */\nvec3 envAt(vec3 r) {\n vec3 base = mix(vec3(0.05, 0.05, 0.055), vec3(0.42, 0.43, 0.45), smoothstep(-0.3, 0.9, r.z));\n float key = smoothstep(0.9, 0.965, dot(r, uLightDir));\n vec3 sd = normalize(vec3(0.72, -0.25, 0.64));\n vec3 ax = normalize(cross(sd, vec3(0.0, 0.0, 1.0)));\n float along = dot(r, ax);\n float strip = smoothstep(0.975, 0.992, dot(normalize(r - ax * along), sd)) * (1.0 - smoothstep(0.4, 0.62, abs(along)));\n return base + vec3(1.0, 0.98, 0.95) * key * 3.2 + vec3(0.95, 0.97, 1.0) * strip * 2.4;\n}\nfloat fresnel(float ndv, float f0) { return f0 + (1.0 - f0) * pow(1.0 - ndv, 5.0); }\n\nfloat hash12(vec2 p) { vec3 p3 = fract(vec3(p.xyx) * 0.1031); p3 += dot(p3, p3.yzx + 33.33); return fract((p3.x + p3.y) * p3.z); }\nfloat vnoise(vec2 p) {\n vec2 i = floor(p), f = fract(p); f = f * f * (3.0 - 2.0 * f);\n return mix(mix(hash12(i), hash12(i + vec2(1, 0)), f.x), mix(hash12(i + vec2(0, 1)), hash12(i + vec2(1, 1)), f.x), f.y);\n}\nfloat fbm(vec2 p) { float s = 0.0, a = 0.5; for (int i = 0; i < 5; i++) { s += a * vnoise(p); p *= 2.03; a *= 0.5; } return s; }\n";
10
+ export declare const COMMON = "#version 300 es\nprecision highp float;\nprecision highp sampler2DShadow;\nuniform vec3 uLightDir;\nuniform vec3 uEye;\nuniform mat4 uLightVP;\nuniform sampler2DShadow uShadow;\nuniform vec3 uKey;\nuniform float uAmb;\nuniform vec3 uBackdrop;\nuniform vec3 uTarget;\nuniform float uRadius;\n\nvec3 toLin(vec3 c) { return pow(max(c, 0.0), vec3(2.2)); }\nvec3 toSrgb(vec3 c) { return pow(max(c, 0.0), vec3(1.0 / 2.2)); }\nvec3 tone(vec3 c) { c *= 0.92; return clamp((c * (2.51 * c + 0.03)) / (c * (2.43 * c + 0.59) + 0.14), 0.0, 1.0); }\n\nfloat shadowAt(vec3 wp, vec3 n) {\n vec4 lp = uLightVP * vec4(wp + n * 0.003, 1.0);\n vec3 c = lp.xyz / lp.w * 0.5 + 0.5;\n if (c.x < 0.0 || c.x > 1.0 || c.y < 0.0 || c.y > 1.0 || c.z > 1.0) return 1.0;\n vec2 texel = 1.0 / vec2(textureSize(uShadow, 0));\n float s = 0.0;\n for (int x = -2; x <= 2; x++) for (int y = -2; y <= 2; y++) s += texture(uShadow, vec3(c.xy + vec2(x, y) * texel * 1.5, c.z - 0.0012));\n return s / 25.0;\n}\n\nvec3 shade(vec3 alb, vec3 n, vec3 wp, float cav, float spec, float rough, float translucency) {\n float sh = shadowAt(wp, n);\n float nl = dot(n, uLightDir);\n float diff = max(nl, 0.0) * sh;\n float back = max(-nl, 0.0) * translucency;\n vec3 sky = vec3(0.66, 0.68, 0.74), gnd = vec3(0.3, 0.27, 0.23);\n vec3 amb = mix(gnd, sky, n.z * 0.5 + 0.5) * (1.0 - max(cav, 0.0) * 0.6) * (0.75 + 0.25 * sh);\n vec3 V = normalize(uEye - wp);\n vec3 H = normalize(uLightDir + V);\n float sp = pow(max(dot(n, H), 0.0), mix(6.0, 160.0, 1.0 - rough)) * spec * sh;\n return alb * (uKey * (diff + back) + amb * uAmb) + uKey * sp;\n}\n\n/** A photo studio, as seen in a reflection: dim room, the key softbox toward the light, a long strip light opposite. */\nvec3 envAt(vec3 r) {\n vec3 base = mix(vec3(0.05, 0.05, 0.055), vec3(0.42, 0.43, 0.45), smoothstep(-0.3, 0.9, r.z));\n float key = smoothstep(0.9, 0.965, dot(r, uLightDir));\n vec3 sd = normalize(vec3(0.72, -0.25, 0.64));\n vec3 ax = normalize(cross(sd, vec3(0.0, 0.0, 1.0)));\n float along = dot(r, ax);\n float strip = smoothstep(0.975, 0.992, dot(normalize(r - ax * along), sd)) * (1.0 - smoothstep(0.4, 0.62, abs(along)));\n return base + vec3(1.0, 0.98, 0.95) * key * 3.2 + vec3(0.95, 0.97, 1.0) * strip * 2.4;\n}\n/** The same studio seen in a rough surface: the lights spread into a broad glow. */\nvec3 envSoft(vec3 r) {\n vec3 base = mix(vec3(0.07, 0.07, 0.075), vec3(0.36, 0.37, 0.39), smoothstep(-0.6, 1.0, r.z));\n float key = smoothstep(0.3, 1.0, dot(r, uLightDir));\n return base + vec3(1.0, 0.98, 0.95) * key * key * 0.9;\n}\nfloat fresnel(float ndv, float f0) { return f0 + (1.0 - f0) * pow(1.0 - ndv, 5.0); }\n\nfloat hash12(vec2 p) { vec3 p3 = fract(vec3(p.xyx) * 0.1031); p3 += dot(p3, p3.yzx + 33.33); return fract((p3.x + p3.y) * p3.z); }\nfloat vnoise(vec2 p) {\n vec2 i = floor(p), f = fract(p); f = f * f * (3.0 - 2.0 * f);\n return mix(mix(hash12(i), hash12(i + vec2(1, 0)), f.x), mix(hash12(i + vec2(0, 1)), hash12(i + vec2(1, 1)), f.x), f.y);\n}\nfloat fbm(vec2 p) { float s = 0.0, a = 0.5; for (int i = 0; i < 5; i++) { s += a * vnoise(p); p *= 2.03; a *= 0.5; } return s; }\n";
11
11
  export declare const SURFACE_VS = "#version 300 es\nlayout(location = 0) in vec3 aPos;\nlayout(location = 1) in vec3 aNrm;\nlayout(location = 2) in vec2 aUv;\nlayout(location = 3) in vec4 aAttr;\nuniform mat4 uVP;\nout vec3 vW; out vec3 vN; out vec2 vUv; out vec4 vAttr;\nvoid main() { vW = aPos; vN = aNrm; vUv = aUv; vAttr = aAttr; gl_Position = uVP * vec4(aPos, 1.0); }\n";
12
12
  export declare const SURFACE_FS: string;
13
13
  export declare const TEXT_VS = "#version 300 es\nlayout(location = 0) in vec3 aPos;\nlayout(location = 1) in vec3 aNrm;\nlayout(location = 2) in vec2 aUv;\nlayout(location = 3) in vec4 aAttr;\nlayout(location = 4) in vec2 aTuv;\nuniform mat4 uVP;\nout vec3 vW; out vec3 vN; out vec2 vUv; out vec4 vAttr; out vec2 vTuv;\nvoid main() { vW = aPos; vN = aNrm; vUv = aUv; vAttr = aAttr; vTuv = aTuv; gl_Position = uVP * vec4(aPos, 1.0); }\n";
@@ -1 +1 @@
1
- {"version":3,"file":"shaders.d.ts","sourceRoot":"","sources":["../../../../src/motion/typesurface/shaders.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,eAAO,MAAM,MAAM,6wFA0DlB,CAAC;AAEF,eAAO,MAAM,UAAU,wVAQtB,CAAC;AAEF,eAAO,MAAM,UAAU,QAgFtB,CAAC;AAEF,eAAO,MAAM,OAAO,wZASnB,CAAC;AAmCF,eAAO,MAAM,OAAO,QAuEnB,CAAC;AAEF,eAAO,MAAM,QAAQ,iRAOpB,CAAC;AAEF,eAAO,MAAM,QAAQ,QAepB,CAAC"}
1
+ {"version":3,"file":"shaders.d.ts","sourceRoot":"","sources":["../../../../src/motion/typesurface/shaders.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,eAAO,MAAM,MAAM,ilGAgElB,CAAC;AAEF,eAAO,MAAM,UAAU,wVAQtB,CAAC;AAEF,eAAO,MAAM,UAAU,QAgGtB,CAAC;AAEF,eAAO,MAAM,OAAO,wZASnB,CAAC;AAmCF,eAAO,MAAM,OAAO,QAuEnB,CAAC;AAEF,eAAO,MAAM,QAAQ,iRAOpB,CAAC;AAEF,eAAO,MAAM,QAAQ,QAepB,CAAC"}
@@ -57,6 +57,12 @@ vec3 envAt(vec3 r) {
57
57
  float strip = smoothstep(0.975, 0.992, dot(normalize(r - ax * along), sd)) * (1.0 - smoothstep(0.4, 0.62, abs(along)));
58
58
  return base + vec3(1.0, 0.98, 0.95) * key * 3.2 + vec3(0.95, 0.97, 1.0) * strip * 2.4;
59
59
  }
60
+ /** The same studio seen in a rough surface: the lights spread into a broad glow. */
61
+ vec3 envSoft(vec3 r) {
62
+ vec3 base = mix(vec3(0.07, 0.07, 0.075), vec3(0.36, 0.37, 0.39), smoothstep(-0.6, 1.0, r.z));
63
+ float key = smoothstep(0.3, 1.0, dot(r, uLightDir));
64
+ return base + vec3(1.0, 0.98, 0.95) * key * key * 0.9;
65
+ }
60
66
  float fresnel(float ndv, float f0) { return f0 + (1.0 - f0) * pow(1.0 - ndv, 5.0); }
61
67
 
62
68
  float hash12(vec2 p) { vec3 p3 = fract(vec3(p.xyx) * 0.1031); p3 += dot(p3, p3.yzx + 33.33); return fract((p3.x + p3.y) * p3.z); }
@@ -77,7 +83,9 @@ void main() { vW = aPos; vN = aNrm; vUv = aUv; vAttr = aAttr; gl_Position = uVP
77
83
  `;
78
84
  export const SURFACE_FS = COMMON + /* glsl */ `
79
85
  in vec3 vW; in vec3 vN; in vec2 vUv; in vec4 vAttr;
80
- uniform int uMode; // 0 sheet, 1 table, 2 prop (bottle)
86
+ uniform int uMode; // 0 sheet, 1 table, 2 prop (the bottle, or a constructed part)
87
+ uniform int uPartOn; // 1: a constructed part, shaded by uPart; 0: the wine bottle
88
+ uniform vec4 uPart; // metalness, roughness, reflection, albedo gain
81
89
  uniform int uShading; // 0 paper, 1 label, 2 film, 3 fabric
82
90
  uniform vec3 uPropColor;
83
91
  uniform vec3 uCapColor;
@@ -117,6 +125,20 @@ void main() {
117
125
  return;
118
126
  }
119
127
  vec3 V = normalize(uEye - vW);
128
+ if (uMode == 2 && uPartOn == 1) {
129
+ if (!gl_FrontFacing) n = -n;
130
+ float ndv = max(dot(n, V), 0.0);
131
+ vec3 alb = toLin(uPropColor) * uPart.w;
132
+ float metal = uPart.x, rough = uPart.y;
133
+ vec3 body = shade(alb * (1.0 - metal), n, vW, 0.0, uPart.z * (1.0 - rough) * 1.2, rough, 0.0);
134
+ // A dielectric reflects the studio through its Fresnel term; a metal reflects it in its own colour.
135
+ vec3 F = mix(vec3(fresnel(ndv, 0.05)), alb + (1.0 - alb) * pow(1.0 - ndv, 5.0), metal);
136
+ vec3 R = reflect(-V, n);
137
+ vec3 env = mix(envAt(R), envSoft(R), smoothstep(0.08, 0.5, rough));
138
+ col = body + env * F * uPart.z;
139
+ outColor = vec4(toSrgb(tone(col)), 1.0);
140
+ return;
141
+ }
120
142
  if (uMode == 2) {
121
143
  float ndv = max(dot(n, V), 0.0);
122
144
  vec3 R = reflect(-V, n);
@@ -1 +1 @@
1
- {"version":3,"file":"shaders.js","sourceRoot":"","sources":["../../../../src/motion/typesurface/shaders.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0DhC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,UAAU,CAAC;;;;;;;;CAQpC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgF7C,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAG,UAAU,CAAC;;;;;;;;;CASjC,CAAC;AAEF,oGAAoG;AACpG,MAAM,UAAU,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8B7B,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuEvD,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAAC;;;;;;;CAOlC,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAAC;;CAElC,GAAG,UAAU,GAAG,UAAU,CAAC;;;;;;;;;;;;;CAa3B,CAAC"}
1
+ {"version":3,"file":"shaders.js","sourceRoot":"","sources":["../../../../src/motion/typesurface/shaders.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgEhC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,UAAU,CAAC;;;;;;;;CAQpC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgG7C,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAG,UAAU,CAAC;;;;;;;;;CASjC,CAAC;AAEF,oGAAoG;AACpG,MAAM,UAAU,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8B7B,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuEvD,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAAC;;;;;;;CAOlC,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAAC;;CAElC,GAAG,UAAU,GAAG,UAAU,CAAC;;;;;;;;;;;;;CAa3B,CAAC"}
@@ -9,7 +9,8 @@
9
9
  * Its `id` becomes a valid `surface.type`, and the renderer paints it with the named `art` (or a
10
10
  * plain colour if it has no painter). Pure; no React.
11
11
  */
12
- import type { TSDeformation, TSMaterial, TSSurfaceType, TSView } from './config';
12
+ import type { TSDeformation, TSMaterial, TSSurfaceType, TSView, TypeSurfaceConfig } from './config';
13
+ import { type PartRange, type TSObjectSpec } from './construct';
13
14
  import { type Vec3 } from './ops';
14
15
  /** How the substrate itself shades. The renderer maps each to a lighting model. */
15
16
  export type SurfaceShading = 'newsprint' | 'paper' | 'label' | 'film' | 'fabric';
@@ -57,6 +58,23 @@ export type SurfaceDef = {
57
58
  looseSheet?: boolean;
58
59
  /** A solid object the surface is wrapped on. */
59
60
  prop?: 'bottle';
61
+ /**
62
+ * A constructed object the surface is wrapped on (`objectSurface`): its mesh, already in the
63
+ * sheet's frame (the wrap axis parallel to y at z = −curveRadius), one triangle range per part.
64
+ */
65
+ solid?: {
66
+ positions: Float32Array;
67
+ normals: Float32Array;
68
+ indices: Uint32Array;
69
+ count: number;
70
+ ranges: PartRange[];
71
+ };
72
+ /** The wrapped sheet's radius at a height y (world): it follows a tapered or bulged part. */
73
+ radiusAt?: (y: number) => number;
74
+ /** `hidden`: the sheet is not drawn, so the text reads as printed straight onto the object. */
75
+ sheet?: 'visible' | 'hidden';
76
+ /** Radius that frames the object (camera fit); sheets work theirs out from their size. */
77
+ frameRadius?: number;
60
78
  /** How much fine wrinkles lift the surface, as a share of its width. */
61
79
  wrinkleDepth: number;
62
80
  /** The surface's own shape, before the shared operators. `x, y` are sheet units (1 wide). */
@@ -77,5 +95,14 @@ export declare function registerSurface(def: SurfaceDef): SurfaceDef;
77
95
  export declare function getSurface(id: string): SurfaceDef;
78
96
  export declare function hasSurface(id: string): boolean;
79
97
  export declare function listSurfaces(): SurfaceDef[];
98
+ /**
99
+ * A constructed object as a surface: the parts become the solid, and a sheet the size of the text
100
+ * area wraps the part that carries the text, following its radius at every height. The sheet is
101
+ * hidden unless the object asks for a paper label, so the words read as printed on the object. An
102
+ * invalid spec is repaired first (`sanitizeObject`), so this always returns something drawable.
103
+ */
104
+ export declare function objectSurface(input: TSObjectSpec): SurfaceDef;
105
+ /** What a config's text meets: its constructed `object` when it has one, else the surface it names. */
106
+ export declare function surfaceFor(config: Pick<TypeSurfaceConfig, 'surface' | 'object'>): SurfaceDef;
80
107
  export {};
81
108
  //# sourceMappingURL=surfaces.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"surfaces.d.ts","sourceRoot":"","sources":["../../../../src/motion/typesurface/surfaces.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"surfaces.d.ts","sourceRoot":"","sources":["../../../../src/motion/typesurface/surfaces.ts"],"names":[],"mappings":"AACA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AACpG,OAAO,EAA6C,KAAK,SAAS,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3G,OAAO,EAAc,KAAK,IAAI,EAAE,MAAM,OAAO,CAAC;AAE9C,mFAAmF;AACnF,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;AACjF,+BAA+B;AAC/B,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEpD,KAAK,WAAW,CAAC,CAAC,IAAI,CAAC,SAAS,MAAM,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,GAAG,CAAC,CAAC;AAEpF,MAAM,MAAM,YAAY,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,WAAW,CAAC,aAAa,CAAC,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;CAAE,CAAC;AAE9G,MAAM,MAAM,UAAU,GAAG;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvB,sEAAsE;IACtE,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,cAAc,CAAC;IACxB,KAAK,EAAE,UAAU,CAAC;IAClB,uCAAuC;IACvC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B,yEAAyE;IACzE,KAAK,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG;QAAE,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,CAAA;KAAE,CAAC;IAC7D,4DAA4D;IAC5D,WAAW,EAAE,MAAM,CAAC;IACpB,4DAA4D;IAC5D,SAAS,EAAE,UAAU,GAAG,SAAS,CAAC;IAClC,iEAAiE;IACjE,KAAK,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,gDAAgD;IAChD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,gDAAgD;IAChD,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB;;;OAGG;IACH,KAAK,CAAC,EAAE;QAAE,SAAS,EAAE,YAAY,CAAC;QAAC,OAAO,EAAE,YAAY,CAAC;QAAC,OAAO,EAAE,WAAW,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,SAAS,EAAE,CAAA;KAAE,CAAC;IACrH,6FAA6F;IAC7F,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IACjC,+FAA+F;IAC/F,KAAK,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,0FAA0F;IAC1F,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,YAAY,EAAE,MAAM,CAAC;IACrB,6FAA6F;IAC7F,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAClG,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACrC,YAAY,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACxC,CAAC;AAgJF,oCAAoC;AACpC,eAAO,MAAM,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,aAAa,EAAE,UAAU,CAAC,CAA2F,CAAC;AAE7J,yEAAyE;AACzE,wBAAgB,eAAe,CAAC,GAAG,EAAE,UAAU,GAAG,UAAU,CAG3D;AACD,yFAAyF;AACzF,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,UAAU,CAEjD;AACD,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAE9C;AACD,wBAAgB,YAAY,IAAI,UAAU,EAAE,CAE3C;AAQD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,YAAY,GAAG,UAAU,CAwC7D;AAQD,uGAAuG;AACvG,wBAAgB,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,iBAAiB,EAAE,SAAS,GAAG,QAAQ,CAAC,GAAG,UAAU,CAE5F"}
@@ -1,3 +1,4 @@
1
+ import { buildObject, createObject, sanitizeObject } from './construct';
1
2
  import { smoothstep } from './ops';
2
3
  /* ---------------- shapes ---------------- */
3
4
  /** A newspaper remembers the fold it was delivered in: a faint ridge across the middle. */
@@ -146,4 +147,70 @@ export function hasSurface(id) {
146
147
  export function listSurfaces() {
147
148
  return [...REGISTRY.values()];
148
149
  }
150
+ /* ---------------- constructed objects ---------------- */
151
+ /** The gap between a part and the text area wrapped on it: enough depth to keep them apart. */
152
+ const OBJECT_GAP = 0.0025;
153
+ const OBJECTS = new Map();
154
+ /**
155
+ * A constructed object as a surface: the parts become the solid, and a sheet the size of the text
156
+ * area wraps the part that carries the text, following its radius at every height. The sheet is
157
+ * hidden unless the object asks for a paper label, so the words read as printed on the object. An
158
+ * invalid spec is repaired first (`sanitizeObject`), so this always returns something drawable.
159
+ */
160
+ export function objectSurface(input) {
161
+ const key = JSON.stringify(input);
162
+ const hit = OBJECTS.get(key);
163
+ if (hit)
164
+ return hit;
165
+ const spec = sanitizeObject(input).object ?? sanitizeObject(createObject('')).object;
166
+ const built = buildObject(spec);
167
+ const { host } = built;
168
+ const hostH = host.y1 - host.y0;
169
+ const height = Math.max(0.02, spec.text.height * hostH);
170
+ // Keep the text area on the part.
171
+ const yc = Math.min(host.y1 - height / 2, Math.max(host.y0 + height / 2, host.y0 + spec.text.y * hostH));
172
+ const R = host.radiusAt(yc) + OBJECT_GAP;
173
+ const width = (spec.text.arc * Math.PI / 180) * R;
174
+ // Into the sheet's frame: the text area's centre at the origin, the axis behind it.
175
+ const positions = new Float32Array(built.positions);
176
+ for (let k = 0; k < built.count; k++) {
177
+ positions[k * 3 + 1] = positions[k * 3 + 1] - yc;
178
+ positions[k * 3 + 2] = positions[k * 3 + 2] - R;
179
+ }
180
+ const { min, max } = built.bounds;
181
+ const nu = Math.round(Math.min(260, Math.max(96, spec.text.arc * 1.1)));
182
+ const def = {
183
+ id: `object:${hashString(key)}`, name: spec.name, blurb: `Built from ${spec.parts.map((p) => p.shape).join(' + ')}.`,
184
+ width, height, grid: [nu, Math.round(Math.min(220, Math.max(24, (nu * height) / width)))],
185
+ art: 'plain', shading: 'label', table: spec.scene.table, backdrop: spec.scene.backdrop,
186
+ color: spec.text.label ?? host.color,
187
+ material: { type: 'print', halftone: 0, grainInfluence: spec.text.label ? 0.25 : 0.05, paperInfluence: spec.text.label ? 0.35 : 0.15 },
188
+ curveRadius: R, curveMode: 'cylinder', wrinkleDepth: 0.004,
189
+ solid: { positions, normals: built.normals, indices: built.indices, count: built.count, ranges: built.ranges },
190
+ radiusAt: (y) => host.radiusAt(y + yc) + OBJECT_GAP,
191
+ sheet: spec.text.label ? 'visible' : 'hidden',
192
+ frameRadius: 0.5 * Math.hypot(max[0] - min[0], max[1] - min[1], max[2] - min[2]) * 1.06,
193
+ states: {
194
+ wrapped: s('Standing', { curve: 1 }),
195
+ lying: s('Lying on the table', { curve: 1 }, { roll: -28 }),
196
+ turned: s('Turned away', { curve: 1, tiltX: 0.5 }),
197
+ tipped: s('Tipped toward you', { curve: 1, tiltY: -0.7 }),
198
+ },
199
+ defaultState: 'wrapped', camera: { flat: 0, deep: 48 },
200
+ };
201
+ if (OBJECTS.size >= 12)
202
+ OBJECTS.delete(OBJECTS.keys().next().value);
203
+ OBJECTS.set(key, def);
204
+ return def;
205
+ }
206
+ function hashString(v) {
207
+ let h = 0x811c9dc5;
208
+ for (let i = 0; i < v.length; i++)
209
+ h = Math.imul(h ^ v.charCodeAt(i), 0x01000193);
210
+ return (h >>> 0).toString(36);
211
+ }
212
+ /** What a config's text meets: its constructed `object` when it has one, else the surface it names. */
213
+ export function surfaceFor(config) {
214
+ return config.object ? objectSurface(config.object) : getSurface(config.surface.type);
215
+ }
149
216
  //# sourceMappingURL=surfaces.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"surfaces.js","sourceRoot":"","sources":["../../../../src/motion/typesurface/surfaces.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"surfaces.js","sourceRoot":"","sources":["../../../../src/motion/typesurface/surfaces.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,183 @@
1
+ # Typography × Surface — a lab for text that physically meets a surface
2
+
3
+ **Live:** `/animations/type-surface` · **Code:** `src/motion/typesurface/` (exported from `@comppack/ui/motion` as `TypeSurface`, plus `TypeSurfaceCanvas`)
4
+ · **Playground:** `site/components/TypeSurfaceStudio.tsx` · **Tests:** `tests/motion/typeSurface.test.ts`, `typeSurfaceConstruct.test.ts` · **Decisions:** `DECISIONS.md` §30
5
+
6
+ Type any words and they meet a surface. They wrap around it, land letter by letter, fold across a crease, crumple with the
7
+ paper, roll up with it, and finally sink into it as printed ink. The text is never painted into the artwork. It stays its own
8
+ editable layer the whole time, so changing BREAKING NEWS to SUMMER SALE, or the font, colour or size, never touches the newspaper.
9
+
10
+ Surfaces: **newspaper** (the detailed one), paper, bottle, wrapper and fabric. The lab also shows the library's existing
11
+ **paper-fold promo** (`PaperFoldPlayer`, unchanged) with the lab's text as its headline. Its result is the fold performed (the
12
+ middle of its folded hold), and it covers the stage. Neon has its own page
13
+ (`/animations/neon-text`) and is not part of the lab. Glass and metal were removed at the user's request.
14
+
15
+ Presets and states open on their **result**, with the operation already performed. **Replay** plays the transformation, and the timeline scrubs it.
16
+ The camera looks straight down with a narrow lens. Perspective was removed from every preset and state (`deformation.perspective` stays 0),
17
+ because it looked bad.
18
+
19
+ ---
20
+
21
+ ## 1. How text geometry is represented
22
+
23
+ `layout.ts` lays the text out once into a **block** in *surface units* (every surface is 1000 wide). The block has lines, and each
24
+ glyph's box on its line, with kerning kept: a glyph starts where the width of everything before it ends. `text.ts` rasterises exactly
25
+ this layout, as white letters on nothing, into an alpha texture, using the live font. Colour, gradient, blend mode and ink are applied
26
+ in the shader on top of that mask. So a colour change repaints nothing, and only new words or a new font repaint the raster.
27
+
28
+ ## 2. How surfaces are represented
29
+
30
+ `surfaces.ts`: a surface is **data**. It has a size in world units, a mesh resolution, an artwork painter (`art.ts`), a shading
31
+ model, what it lies on, its natural text material, and named **states** (flat, folded, double folded, rolled, partially folded,
32
+ crumpled, heavily crumpled…). Only a few have their own shape: a wrapper inflates and has crimped seals, and fabric drapes. Everything else comes from shared operators.
33
+ Every surface has full artwork, procedural and seeded (`art.ts`):
34
+
35
+ | surface | artwork | shading |
36
+ |---|---|---|
37
+ | newspaper | masthead, dateline, justified columns of real words, halftoned photos, advert, markets, delivery crease, fibres, the next page showing through; a back page, stacked pages, a loose page on the desk | newsprint: matte, a little light through the sheet |
38
+ | bottle | a paper label: winery line, descriptors, a red pen scribble, vintage and volume, a back label with a barcode where it wraps behind. The bottle is geometry: dark glass reflecting a studio (key softbox and strip light) with a crinkled foil capsule | label: satin paper; glass and foil use the studio reflection |
39
+ | wrapper | a glossy snack pack: brand band, sale burst behind the words, crisps, flavour ribbon, net weight, silver crimped seals | film: sharp specular plus studio reflection |
40
+ | paper | a ruled note sheet: blue rules, red margin, three real punched holes (the table shows through) | paper |
41
+ | fabric | twill-woven cotton with slubs, a hemmed edge with running stitch, a woven care label | cloth: rough, with sheen at grazing angles |
42
+
43
+ ## 3. How deformation is applied
44
+
45
+ `ops.ts` holds the shared operators, and every one is an isometry of the sheet or close to one:
46
+
47
+ | operator | what it does |
48
+ |---|---|
49
+ | `bend` | a crease: one side turns about a line through a rounded zone. Height above the sheet is carried through, so stacked layers fold together (`core` stops an inner layer from turning inside out on a second fold) |
50
+ | `roll` | winds the sheet up from an edge onto a tightening spiral, printed side outward |
51
+ | `cylinder` | wraps a cylinder, keeping arc length (a bottle label) |
52
+ | `crumpleField` | a seeded network of straight ridges and valleys with planar flanks, plus the in-plane pull the ridges take up |
53
+ | `rotate` | rigid turns of the whole object |
54
+
55
+ **Up to four folds and four wraps.** `fold`, `fold2`, `fold3` and `fold4` are creases. Each has a position, angle, crease width,
56
+ orientation, direction (over/under) and `side` (which part moves). `wrap1`–`wrap4` wrap the sheet round a rod from a line, with
57
+ a radius and an angle up to 360°. All eight are the same `bend` operator, applied in that order. A later one in the same
58
+ direction wraps the layers the earlier ones laid on its inner side. Parallel creases fold correctly when the farthest is
59
+ listed first, as the accordion preset does. Each has its own timeline key (`fold`…`fold4`, `wrap1`…`wrap4`).
60
+
61
+ `engine.ts` runs every sheet vertex through **shape → wrinkles → crumple → fold → second fold → roll → cylinder → turns**,
62
+ then computes normals, cavity (valleys darken) and crease light. The crumple field is cached per seed, and every buffer is
63
+ allocated once per surface, so a frame allocates nothing.
64
+
65
+ **The text mesh is made of the sheet's own cells** under the text block, with the same triangle diagonals. Each text vertex
66
+ blends from its *floating* position (the flat sheet, lifted above everything) to *the sheet vertex it belongs to*. A conformed
67
+ letter therefore lies on exactly the paper's triangles, crease for crease, and depth testing hides it behind folds. This is tested.
68
+
69
+ - **wrap** conforms the block, sweeping slightly left to right.
70
+ - **morph** lands glyphs one at a time: each glyph has its own window, the letters spread apart mid-way (`morphGap`), and in-flight letters arc up.
71
+
72
+ ## 4. How material blending works
73
+
74
+ `material.blend` runs 0 → 1: **floating** (a flat graphic that casts a real shadow in the shadow map) → **surface** (takes the
75
+ key light, shadow and crease light) → **printed** (the blend mode is computed against the paper's own albedo under the letter, and
76
+ the paper grain breaks the ink up) → **embedded** (ragged edges, spread into the fibres, misregistration, and an optional halftone screen).
77
+ The sliders are ink strength, spread, roughness, paper influence, grain influence, halftone, displacement, surface contrast, float height,
78
+ float shadow, gloss and emboss.
79
+
80
+ ## 5. How animation states are interpolated
81
+
82
+ `timeline.ts`: sliders say how **far** each transformation goes, and `animation.stages` say **when**. At progress p, a driven amount is
83
+ `value × envelope(p)`. The envelope is an eased ramp between `start` and `end`, optionally falling back between `outStart` and `outEnd`.
84
+ Envelopes are continuous, so scrubbing never jumps. The test samples every preset at 400 points to prove it.
85
+
86
+ ## 6. Adding a surface
87
+
88
+ ```ts
89
+ TypeSurface.registerSurface({ ...TypeSurface.SURFACES.paper, id: 'poster', name: 'Poster', width: 1, height: 1.4,
90
+ states: { flat: { label: 'Flat', deformation: {} }, curled: { label: 'Curled', deformation: { roll: { amount: 0.3 } } } }, defaultState: 'flat' });
91
+ ```
92
+
93
+ The id becomes a valid `surface.type`, and it gets every operator, the text mesh and the materials. The typography code is not touched.
94
+
95
+ ## 7. Configuring an experiment (agents)
96
+
97
+ The whole experiment is one JSON object: `text`, `typography`, `placement`, `surface`, `deformation`, `material`, `view` and `animation`.
98
+
99
+ ```ts
100
+ import { TypeSurface, TypeSurfaceCanvas } from '@comppack/ui/motion';
101
+ const config = TypeSurface.createTypeSurface({ text: 'SUMMER SALE', surface: 'newspaper', state: 'crumpled', font: 'Anton', color: '#E0271B' });
102
+ TypeSurface.validateTypeSurface(config); // [] or [{ path, message }] — never throws
103
+ TypeSurface.TS_CONTROLS; // every knob: path, range, unit, what it does
104
+ <TypeSurfaceCanvas config={config} progress={1} />
105
+ ```
106
+
107
+ `sanitizeTypeSurface` replaces each bad field with its default and names it, so a config always draws.
108
+
109
+ ## 8. Constructing objects (agents)
110
+
111
+ A surface catalogue never covers what a user asks for, so objects are **built, not listed**. `construct.ts` is the construction
112
+ layer, and an object is JSON in the config's `object` field. When `object` is set it is what the text meets, and `surface.type` is ignored.
113
+
114
+ | level | what | where |
115
+ |---|---|---|
116
+ | primitives | `cylinder` (optionally hollow), `sphere`, `ring`, `revolve` (any `[radius, y]` profile), `tube` (a bar along a path), `box` | `TS_PRIMITIVES` |
117
+ | manipulators | `taper`, `flare`, `bulge`, `twist`, `bend`, `scale`, applied to a part in order | `TS_MANIPULATORS` |
118
+ | materials | `plastic`, `matte`, `ceramic`, `glass`, `metal`, `chrome`, in any colour | `TS_OBJECT_MATERIALS` |
119
+ | recipes | `tumbler`, `mug`, `can`, `bottle`: compositions of the above, returned as a plain spec to edit | `TS_RECIPES`, `createObject` |
120
+ | presets | the config an agent ends up with; save the JSON, edit it later | `object-tumbler`, `object-mug` |
121
+
122
+ `TypeSurface.describeConstruction()` is the machine-readable manifest: every primitive with its parameters (type, range, default,
123
+ hint) and the manipulators it accepts, every material, how text attaches, and a `limits` list of what cannot be done. Validation
124
+ reads the same tables, so the manifest cannot drift from what is accepted.
125
+
126
+ ```ts
127
+ // "a teal tumbler with Shekhar on it": a recipe, then edits
128
+ const cfg = TypeSurface.createTypeSurface({ text: 'Shekhar', object: 'tumbler', objectColor: '#1F8A8A', color: '#FFFFFF' });
129
+
130
+ // something with no recipe: compose it from the manifest
131
+ const vase: TypeSurface.TSObjectSpec = {
132
+ name: 'Vase',
133
+ parts: [
134
+ { id: 'body', shape: 'revolve', params: { profile: [[0, 0], [0.22, 0], [0.4, 0.45], [0.3, 0.95], [0.16, 1.25], [0.2, 1.5]], smooth: true },
135
+ ops: [], material: { type: 'ceramic', color: '#2E5E8C' }, at: [0, 0, 0], rotate: [0, 0, 0] },
136
+ { id: 'lip', shape: 'ring', params: { radius: 0.2, thickness: 0.018 }, ops: [], material: { type: 'ceramic', color: '#2E5E8C' }, at: [0, 1.5, 0], rotate: [0, 0, 0] },
137
+ ],
138
+ text: { on: 'body', y: 0.3, height: 0.3, arc: 140, label: null }, // label: a hex colour for a paper label, null prints on the part
139
+ scene: { table: 'studio', backdrop: ['#d9dadc', '#b9bbbf'] },
140
+ };
141
+ TypeSurface.validateObject(vase); // [] or [{ path: 'object.parts.0.params.radius', message }]; never throws
142
+ const onVase = TypeSurface.createTypeSurface({ text: 'Iris', object: vase });
143
+ ```
144
+
145
+ **How it draws.** `objectSurface(spec)` turns the spec into a `SurfaceDef`: the parts become the solid (one triangle range and one
146
+ material per part), and a sheet the size of the text area wraps the part named in `text.on`. The sheet follows that part's radius at
147
+ every height (`radiusAt`), so text sits on a taper or a bulge. The sheet is hidden unless `text.label` asks for a paper label, so the
148
+ words read as printed on the object. Everything else is unchanged: the text is still its own layer with every typography, placement,
149
+ material and timeline control.
150
+
151
+ **Repair, not rejection.** `sanitizeObject` clamps numbers into range, fills omitted parameters from the manifest, drops parts and
152
+ manipulators that make no sense, moves the text to a part that can carry it, and names each fix by path. `object` becomes null only
153
+ when nothing in it can be drawn, and the config then falls back to its surface.
154
+
155
+ **Text size and ink.** `fitObjectText(config)` sets the font size to the largest that fits the part's front face (`OBJECT_FRONT_ARC`,
156
+ 110° of the circumference) and the text area's height. `createTypeSurface({ object })` calls it, and with no `color` picks near-white
157
+ or near-black against the part. The rule itself is in the manifest under `text.sizing`.
158
+
159
+ **Looking at an object.** Turn the object, not the camera: the states `wrapped`, `lying`, `turned` and `tipped`, or `deformation.tiltX`
160
+ (turn) and `tiltY` (tip; negative shows the top). `view.yaw` and `view.pitch` orbit about the table and are wrong for a standing
161
+ object. The manifest's `view` section says this.
162
+
163
+ **Ready.** `TypeSurfaceCanvas` calls `onReady` and sets `data-ts-ready="true"` after the frame drawn with the loaded fonts
164
+ (`renderer.whenReady(config)` underneath). A screenshot script waits for that instead of a timeout.
165
+
166
+ **An object config says so.** `withObject` sets `surface.type` to `object`; no built-in surface name is left beside the object.
167
+
168
+ **Limits** (also in the manifest): no boolean cut or union; text wraps round parts only (cylinder, sphere, revolve, on the axis, kept
169
+ round); one text block per object; materials are opaque (glass is dark and reflective, not see-through); the lighting is fixed.
170
+
171
+ Rendered from this code: `docs/type-surface/constructed-objects.png` (tumbler, mug, steel tumbler, can, bottle, a vase with no recipe, a labelled bottle).
172
+
173
+ ## 9. Debug view
174
+
175
+ The Debug tab shows the surface mesh, fold and roll lines, a deformation heat map, text bounds, baselines, surface normals,
176
+ control points and a mapping-coordinate checker, and can switch shadows off. **MOVE TEXT** drags the text across the surface by picking the nearest sheet vertex.
177
+
178
+ ## 10. Known limits
179
+
180
+ - Renders with WebGL2. Without it, the component says so and does not draw.
181
+ - `next dev` returns 500 on this page, the same pre-existing CJS/React-Refresh bug as the neon page (DECISIONS §29). Use `next build && next start`.
182
+ - From the straight-down camera, gentle relief (a shallow accordion) reads through shading only. Orbit (drag) to see it from the side.
183
+ - A second fold over a stack is not strictly length-preserving on the inner layer (real stacked paper slips too).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@appinternalleads/ui",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "description": "React + React Native component library. Components are generated from JSON; see SPEC.md.",
5
5
  "workspaces": [
6
6
  "site"
@@ -56,7 +56,7 @@
56
56
  "say": "vite-node -c vite.tools.config.ts tools/say-block.ts --",
57
57
  "say:detect": "node tools/speak.mjs --detect",
58
58
  "ask": "node tools/ask/cli.mjs",
59
- "ask:build": "vite build --config tools/ask/vite.config.ts && esbuild tools/speech/speakable.ts --bundle --format=esm --platform=node --outfile=tools/ask/dist/speakable.mjs --log-level=error && esbuild tools/ask/elicit.ts --bundle --format=esm --platform=node --outfile=tools/ask/dist/elicit.mjs --log-level=error && esbuild tools/ask/components.ts --bundle --format=esm --platform=node --outfile=tools/ask/dist/components.mjs --log-level=error && node tools/ask/build-support.mjs",
59
+ "ask:build": "vite build --config tools/ask/vite.config.ts && esbuild tools/speech/speakable.ts --bundle --format=esm --platform=node --outfile=tools/ask/dist/speakable.mjs --log-level=error && esbuild tools/ask/elicit.ts --bundle --format=esm --platform=node --outfile=tools/ask/dist/elicit.mjs --log-level=error && esbuild tools/ask/components.ts --bundle --format=esm --platform=node --outfile=tools/ask/dist/components.mjs --log-level=error && esbuild tools/ask/neon-page.tsx --bundle --format=esm --platform=browser --jsx=automatic --minify --define:process.env.NODE_ENV=\\\"production\\\" --outfile=tools/ask/dist/neon.js --log-level=error && node tools/ask/build-support.mjs",
60
60
  "ask:check": "node tools/ask/check.mjs",
61
61
  "ask:tui": "vite-node -c vite.tools.config.ts tools/ask/tui/index.tsx --",
62
62
  "ask:mcp": "node tools/ask/mcp.mjs",
@@ -171,6 +171,7 @@
171
171
  "dist",
172
172
  "src",
173
173
  "spec",
174
+ "docs/TYPE-SURFACE.md",
174
175
  "!src/**/*.test.*",
175
176
  "!src/**/*.stories.*",
176
177
  "!src/agent/search/wordvectors.json",
@@ -178,6 +179,7 @@
178
179
  "tools/ask/serve.mjs",
179
180
  "tools/ask/stale.mjs",
180
181
  "tools/ask/policy.mjs",
182
+ "tools/ask/neon-render.mjs",
181
183
  "tools/ask/dist",
182
184
  "tools/speak.mjs"
183
185
  ],
@@ -3,6 +3,7 @@
3
3
  import { useEffect, useRef, useState, type CSSProperties } from 'react';
4
4
  import { sanitizeTypeSurface, type TypeSurfaceConfig } from './config';
5
5
  import { drawDebugOverlay, TypeSurfaceRenderer, type TSDebug } from './renderer';
6
+ import { cssFont } from './text';
6
7
  import { configAt } from './timeline';
7
8
 
8
9
  export type TypeSurfaceCanvasProps = {
@@ -16,6 +17,16 @@ export type TypeSurfaceCanvasProps = {
16
17
  style?: CSSProperties;
17
18
  /** Called with the renderer once it exists (picking, export). */
18
19
  onRenderer?: (r: TypeSurfaceRenderer | null) => void;
20
+ /**
21
+ * Called once the picture is final for this text and font: fonts loaded, frame drawn. Until then
22
+ * the element has `data-ts-ready="false"`; a screenshot or `toDataURL()` is safe when it is `"true"`.
23
+ */
24
+ onReady?: () => void;
25
+ /**
26
+ * Fetch a lab font (`TS_FONTS`) from Google Fonts when the page has not declared it. Default true;
27
+ * set false to keep the canvas off the network and load fonts yourself.
28
+ */
29
+ loadFonts?: boolean;
19
30
  };
20
31
 
21
32
  /**
@@ -23,12 +34,15 @@ export type TypeSurfaceCanvasProps = {
23
34
  * progress and time always draw the same picture, so a playground, a scrubber or a video render can
24
35
  * drive it.
25
36
  */
26
- export function TypeSurfaceCanvas({ config, progress, timeMs = 0, debug, className, style, onRenderer }: TypeSurfaceCanvasProps) {
37
+ export function TypeSurfaceCanvas({ config, progress, timeMs = 0, debug, className, style, onRenderer, onReady, loadFonts = true }: TypeSurfaceCanvasProps) {
27
38
  const canvas = useRef<HTMLCanvasElement>(null);
28
39
  const overlay = useRef<HTMLCanvasElement>(null);
40
+ const root = useRef<HTMLDivElement>(null);
41
+ const notified = useRef<string | null>(null);
29
42
  const renderer = useRef<TypeSurfaceRenderer | null>(null);
30
43
  const [error, setError] = useState<string | null>(null);
31
44
  const [tick, setTick] = useState(0);
45
+ const [readyFor, setReadyFor] = useState<string | null>(null);
32
46
  const { config: safe, invalid } = sanitizeTypeSurface(config);
33
47
 
34
48
  useEffect(() => {
@@ -50,6 +64,17 @@ export function TypeSurfaceCanvas({ config, progress, timeMs = 0, debug, classNa
50
64
  };
51
65
  }, []);
52
66
 
67
+ // Ready is per text and font: new words or a new face wait for their font again.
68
+ const fontKey = `${safe.text}|${cssFont(safe.typography, 100)}`;
69
+ useEffect(() => {
70
+ const r = renderer.current;
71
+ if (!r) return;
72
+ let live = true;
73
+ void r.whenReady(safe, loadFonts).then(() => { if (live) setReadyFor(fontKey); });
74
+ return () => { live = false; };
75
+ }, [fontKey]);
76
+ const ready = readyFor === fontKey && !error;
77
+
53
78
  const drawn = progress === undefined ? safe : configAt(safe, progress);
54
79
  useEffect(() => {
55
80
  const r = renderer.current;
@@ -58,13 +83,16 @@ export function TypeSurfaceCanvas({ config, progress, timeMs = 0, debug, classNa
58
83
  r.render(drawn, timeMs, debug);
59
84
  const o = overlay.current?.getContext('2d');
60
85
  if (o) drawDebugOverlay(o, r, debug ?? {});
86
+ // Marked only after the frame that drew with the loaded fonts, so a watcher never captures too early.
87
+ if (root.current) root.current.dataset.tsReady = ready ? 'true' : 'false';
88
+ if (ready && notified.current !== fontKey) { notified.current = fontKey; onReady?.(); }
61
89
  } catch (e) {
62
90
  setError((e as Error).message);
63
91
  }
64
92
  });
65
93
 
66
94
  return (
67
- <div className={className} style={{ position: 'relative', ...style }} data-ts-invalid={invalid.join(' ') || undefined} data-tick={tick}>
95
+ <div ref={root} className={className} style={{ position: 'relative', ...style }} data-ts-invalid={invalid.join(' ') || undefined} data-tick={tick}>
68
96
  <canvas ref={canvas} style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', display: 'block' }} aria-label={`“${safe.text}” on ${safe.surface.type}`} role="img" />
69
97
  <canvas ref={overlay} style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', pointerEvents: 'none' }} aria-hidden />
70
98
  {error ? <p role="alert" style={{ position: 'absolute', inset: 0, margin: 0, display: 'grid', placeItems: 'center', padding: 16, textAlign: 'center' }}>{error}</p> : null}