postext-folio 0.7.0 → 0.8.0

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 CHANGED
@@ -120,9 +120,9 @@ book.goToPage(2);
120
120
  <table>
121
121
  <thead><tr><th>Export</th><th>What it does</th></tr></thead>
122
122
  <tbody>
123
- <tr><td><code>createFolio(container, options)</code></td><td>The viewer over any pages. Options: <code>pages</code>, <code>firstPageRecto</code> (default true), <code>binding</code> (<code>'left'</code> | <code>'right'</code>), <code>at</code> (page to open on), <code>mode</code> (<code>'auto'</code> | <code>'single'</code> | <code>'double'</code>; auto shows one page at a time below 560 px), <code>paper</code> (blank-page colour), <code>animate</code>, <code>interaction</code> (what the left button does: <code>'hand'</code> turns pages, <code>'orbit'</code> turns the view, <code>'select'</code> leaves the pointer to the host), <code>controls</code>, <code>showCount</code> (false keeps the count for screen readers only), <code>labels</code>, <code>appearance</code> (<code>folio</code>, <code>pageWidthMm</code>, <code>extraPages</code>, <code>covers</code>, <code>spineImage</code>, <code>textureBaseUrl</code>), <code>onChange</code>, <code>onTarget</code>, <code>onLayout</code>. One page at a time the book is WebGL too: the spine runs along the page's inner edge and the leaf turns over it; a drag towards the spine turns forward, a swipe away from it goes back, a tap turns.</td></tr>
123
+ <tr><td><code>createFolio(container, options)</code></td><td>The viewer over any pages. Options: <code>pages</code>, <code>firstPageRecto</code> (default true), <code>binding</code> (<code>'left'</code> | <code>'right'</code>), <code>at</code> (page to open on), <code>mode</code> (<code>'auto'</code> | <code>'single'</code> | <code>'double'</code>; auto shows one page at a time below 560 px), <code>paper</code> (blank-page colour), <code>animate</code>, <code>interaction</code> (what the left button does: <code>'hand'</code> turns pages, <code>'orbit'</code> turns the view, <code>'select'</code> leaves the pointer to the host, <code>'magnify'</code> holds a magnifying glass over the book: wheel, + and − zoom, Esc puts it away; the pointer selects too, <code>pageAt</code> giving the point under the glass's centre), <code>magnifier</code> (<code>{ zoom, diameter }</code>), <code>detail</code> (<code>{ paint(index, deviceWidth), release() }</code>: sharper paintings for the glass; <code>createFolioFromDocument</code> supplies its own), <code>controls</code>, <code>showCount</code> (false keeps the count for screen readers only), <code>labels</code>, <code>appearance</code> (<code>folio</code>, <code>pageWidthMm</code>, <code>extraPages</code>, <code>covers</code>, <code>spineImage</code>, <code>textureBaseUrl</code>), <code>onChange</code>, <code>onTarget</code>, <code>onLayout</code>. One page at a time the book is WebGL too: the spine runs along the page's inner edge and the leaf turns over it; a drag towards the spine turns forward, a swipe away from it goes back, a tap turns.</td></tr>
124
124
  <tr><td><code>createFolioFromDocument(container, doc, options)</code></td><td>The same over a postext <code>VDTDocument</code>, painted lazily. Spreads, binding and paper come from the document. Adds <code>scale</code>, <code>window</code>, <code>singleInk</code>, <code>pageNegative</code>, <code>alt</code>, <code>videos</code>, <code>videoUrl</code>, <code>onVideo</code>, and on the viewer <code>setDocument(doc)</code>, <code>toggleVideoAt(point)</code> and <code>stopVideo()</code> (stops every video on the pages).</td></tr>
125
- <tr><td>viewer</td><td><code>goToPage(i, { instant })</code>, <code>goToSpread(i, { instant })</code> (instant opens there without turning), <code>next()</code>, <code>prev()</code>, <code>setPages(pages, opts)</code>, <code>setLabels(labels)</code>, <code>setAppearance(appearance)</code>, <code>resetView()</code> (eases the view back to the settings' <code>tilt</code> and <code>yaw</code> after the reader orbited it with a right-drag), <code>getView()</code> (the view as seen now, <code>{ tilt, yaw }</code> in degrees, to store as the settings), <code>setInteraction(mode)</code>, <code>pageAt(event)</code> (the page under a pointer and where on it, <code>{ page, x, y }</code>, on the book as seen), <code>pointOnScreen(point)</code> (the reverse, for drawing a caret or a selection), <code>refreshPage(src)</code>, <code>setPageVideo(video)</code> (draws a playing <code>&lt;video&gt;</code> on a page, at a place given in page fractions), <code>setPageVideos(videos)</code> (several at once, in place of those shown before), <code>onPageClick</code> / <code>isPageAction</code> options (a click on a page that acts instead of turning it), <code>pageSize</code>, <code>state</code> (<code>{ spread, pages }</code>), <code>element</code>, <code>dispose()</code>.</td></tr>
125
+ <tr><td>viewer</td><td><code>goToPage(i, { instant })</code>, <code>goToSpread(i, { instant })</code> (instant opens there without turning), <code>next()</code>, <code>prev()</code>, <code>setPages(pages, opts)</code>, <code>setLabels(labels)</code>, <code>setAppearance(appearance)</code>, <code>resetView()</code> (eases the view back to the settings' <code>tilt</code> and <code>yaw</code> after the reader orbited it with a right-drag), <code>getView()</code> (the view as seen now, <code>{ tilt, yaw }</code> in degrees, to store as the settings), <code>setInteraction(mode)</code>, <code>setMagnification(zoom)</code> (null for the default), <code>pageAt(event)</code> (the page under a pointer and where on it, <code>{ page, x, y }</code>, on the book as seen), <code>pointOnScreen(point)</code> (the reverse, for drawing a caret or a selection), <code>refreshPage(src)</code>, <code>setPageVideo(video)</code> (draws a playing <code>&lt;video&gt;</code> on a page, at a place given in page fractions), <code>setPageVideos(videos)</code> (several at once, in place of those shown before), <code>onPageClick</code> / <code>isPageAction</code> options (a click on a page that acts instead of turning it), <code>pageSize</code>, <code>state</code> (<code>{ spread, pages }</code>), <code>element</code>, <code>dispose()</code>.</td></tr>
126
126
  <tr><td><code>PageFlipper</code>, <code>canFlip()</code></td><td>The three.js engine alone: a canvas over a host's spread, <code>go(i)</code>, <code>grab</code>/<code>drag</code>/<code>release</code> for the hand (ray-cast onto the tilted pages), <code>hit</code>, <code>setBook</code>, <code>setAppearance</code>, <code>clear</code>, <code>dispose</code>; <code>{ persistent: true }</code> draws the book at rest too, <code>turnAt</code> sets how far a leaf let go must be to turn over.</td></tr>
127
127
  <tr><td><code>FlatPageFlipper</code></td><td>The flat page-turn that predates the 3D book, for a host whose DOM spread shows the pages at rest and must match the turning leaf pixel for pixel (the postext Cookbook's light table).</td></tr>
128
128
  <tr><td><code>pageVideoSpots(page, doc)</code>, <code>attachVideoSource(el, url, opts)</code></td><td>Where each video lies on a page as bound (turned, unmirrored, cropped as printed), and a source for a <code>&lt;video&gt;</code>: a file as it is, an HLS stream natively or through hls.js.</td></tr>
package/dist/index.d.ts CHANGED
@@ -5,7 +5,7 @@ export { MAX_PAGE_VIDEOS } from "./videoAtlas";
5
5
  export { spreadsOf, spreadOfPage } from "./spreads";
6
6
  export type { Spread } from "./spreads";
7
7
  export { createFolio } from "./viewer";
8
- export type { FolioAppearance, FolioInteraction, FolioLabels, FolioOptions, FolioPage, FolioPagePoint, FolioPageVideo, FolioState, FolioViewer } from "./viewer";
8
+ export type { FolioAppearance, FolioInteraction, FolioLabels, FolioMagnifier, FolioOptions, FolioPageDetail, FolioPage, FolioPagePoint, FolioPageVideo, FolioState, FolioViewer } from "./viewer";
9
9
  export type { FlipAppearance } from "./pageFlip";
10
10
  export { paperSpec, type PaperSpec } from "./paper";
11
11
  export { loadDeskMaps, type DeskMaps } from "./deskTextures";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACpD,YAAY,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACjK,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AACtE,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAC3E,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,cAAc,EAAE,YAAY,EAAE,UAAU,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACpD,YAAY,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,WAAW,EAAE,cAAc,EAAE,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,cAAc,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAClM,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AACtE,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAC3E,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,cAAc,EAAE,YAAY,EAAE,UAAU,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,46 @@
1
+ import { PerspectiveCamera, Scene, type WebGLRenderer } from "three";
2
+ /** A magnifying glass held over the book (#527): where its centre is on
3
+ * the canvas (device px from the top left), the radius of its glass and
4
+ * the width of its rim (device px), and how much it magnifies at its
5
+ * centre. */
6
+ export interface LoupeView {
7
+ x: number;
8
+ y: number;
9
+ radius: number;
10
+ rim: number;
11
+ zoom: number;
12
+ }
13
+ /** The share of the lens's field its centre takes: the sample radius at a
14
+ * point r (0 … 1) of the glass is r (A + (1 − A) r²), so the centre
15
+ * magnifies 1 / A times more than a flat lens of the same field and the
16
+ * rim gathers the field round it in, curving it as a real glass does. */
17
+ export declare const LOUPE_A = 0.58;
18
+ /** The magnifying glass: its picture of the book and the glass drawn over
19
+ * the screen. */
20
+ export declare class Loupe {
21
+ private target;
22
+ private camera;
23
+ private overlay;
24
+ private overlayCamera;
25
+ private mesh;
26
+ constructor();
27
+ /** How far from its centre (device px) the field the glass shows
28
+ * reaches on the screen. */
29
+ static field(view: LoupeView): number;
30
+ /**
31
+ * Draws the lens's picture: the book from the eye (`camera`, the main
32
+ * view) through the lens's field only, a square around the lens's centre
33
+ * as wide as the field, into a picture with about one texel for each
34
+ * screen pixel at the glass's centre (more towards the rim, which
35
+ * gathers the field in: no multisampling, which would cost more than the
36
+ * book's own frame). `before` and `after` run round the
37
+ * draw (the host swaps in its sharper paintings and turns off what reads
38
+ * the main view's screen).
39
+ */
40
+ capture(renderer: WebGLRenderer, scene: Scene, camera: PerspectiveCamera, view: LoupeView, before: () => void, after: () => void): void;
41
+ /** Draws the glass and its rim over the screen (`width` × `height`
42
+ * device px), its picture as `capture` drew it last. */
43
+ draw(renderer: WebGLRenderer, width: number, height: number, view: LoupeView): void;
44
+ dispose(): void;
45
+ }
46
+ //# sourceMappingURL=loupe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loupe.d.ts","sourceRoot":"","sources":["../src/loupe.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,iBAAiB,EAEjB,KAAK,EAKL,KAAK,aAAa,EACnB,MAAM,OAAO,CAAC;AAEf;;;cAGc;AACd,MAAM,WAAW,SAAS;IACxB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;0EAG0E;AAC1E,eAAO,MAAM,OAAO,OAAO,CAAC;AAiG5B;kBACkB;AAClB,qBAAa,KAAK;IAChB,OAAO,CAAC,MAAM,CAAkC;IAChD,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,aAAa,CAA6C;IAClE,OAAO,CAAC,IAAI,CAAsC;;IA2BlD;iCAC6B;IAC7B,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM;IAIrC;;;;;;;;;OASG;IACH,OAAO,CAAC,QAAQ,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,IAAI,EAAE,KAAK,EAAE,MAAM,IAAI;IA+BhI;6DACyD;IACzD,IAAI,CAAC,QAAQ,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS;IA+B5E,OAAO;CAMR"}
package/dist/loupe.js ADDED
@@ -0,0 +1,220 @@
1
+ import { HalfFloatType, LinearFilter, Mesh, NormalBlending, OrthographicCamera, PerspectiveCamera, PlaneGeometry, Scene, ShaderMaterial, Vector2, WebGLRenderTarget, } from "three";
2
+ /** The share of the lens's field its centre takes: the sample radius at a
3
+ * point r (0 … 1) of the glass is r (A + (1 − A) r²), so the centre
4
+ * magnifies 1 / A times more than a flat lens of the same field and the
5
+ * rim gathers the field round it in, curving it as a real glass does. */
6
+ export const LOUPE_A = 0.58;
7
+ /** The biggest picture the lens is drawn into (device px a side). */
8
+ const MAX_SIDE = 2048;
9
+ const VERTEX = /* glsl */ `
10
+ uniform vec2 uCenter;
11
+ varying vec2 vPos;
12
+ void main() {
13
+ vec4 world = modelMatrix * vec4(position, 1.0);
14
+ vPos = world.xy - uCenter;
15
+ gl_Position = projectionMatrix * viewMatrix * world;
16
+ }
17
+ `;
18
+ /**
19
+ * The glass and its rim, over the book as the screen shows it. The glass
20
+ * shows the lens's own picture of the book (drawn from the reader's eye
21
+ * through the lens's field, in linear light), refracted: magnified most at
22
+ * the centre, curving in towards the rim, the colours parting a little
23
+ * there; its edge darkens where the light bends away, and it catches a
24
+ * soft window and a bright arc on the side the light comes from. The rim
25
+ * is black plastic with a rounded section, lit by the same light, and
26
+ * casts a soft shadow on the book. Toned for the screen as the book is.
27
+ */
28
+ const FRAGMENT = /* glsl */ `
29
+ uniform sampler2D uScene;
30
+ uniform float uGlass;
31
+ uniform float uRim;
32
+ uniform float uShadow;
33
+ uniform vec2 uShadowOffset;
34
+ uniform float uA;
35
+ varying vec2 vPos;
36
+
37
+ vec4 over(vec4 src, vec4 dst) { return src + dst * (1.0 - src.a); }
38
+
39
+ void main() {
40
+ float d = length(vPos);
41
+ float R = uGlass;
42
+ float outer = R + uRim;
43
+ vec2 dir = d > 0.0 ? vPos / d : vec2(0.0);
44
+ vec2 light = normalize(vec2(-0.55, 0.65));
45
+ float lit = dot(dir, light);
46
+
47
+ // The rim's shadow on the page (premultiplied, as everything here).
48
+ float sd = length(vPos - uShadowOffset);
49
+ vec4 color = vec4(0.0, 0.0, 0.0, 0.42 * (1.0 - smoothstep(outer - 0.6 * uShadow, outer + uShadow, sd)));
50
+ // A thin dark edge round the rim, where it meets the page.
51
+ color = over(vec4(0.0, 0.0, 0.0, 0.35 * (1.0 - smoothstep(outer, outer + 2.0, d))), color);
52
+
53
+ // The rim: black plastic, a rounded section a little flatter on top.
54
+ if (d < outer + 1.0) {
55
+ float t = clamp((d - R) / uRim, 0.0, 1.0);
56
+ float c = 2.0 * t - 1.0;
57
+ vec3 n = normalize(vec3(dir * c * 1.15, sqrt(max(0.0, 1.0 - c * c)) + 0.2));
58
+ vec3 V = vec3(0.0, 0.0, 1.0);
59
+ vec3 L = normalize(vec3(light * 0.75, 0.66));
60
+ vec3 L2 = normalize(vec3(-light * 0.7, 0.7));
61
+ float diff = max(dot(n, L), 0.0);
62
+ float nh = max(dot(n, normalize(L + V)), 0.0);
63
+ float nh2 = max(dot(n, normalize(L2 + V)), 0.0);
64
+ vec3 plastic = vec3(0.008) + vec3(0.02) * diff + vec3(0.9) * pow(nh, 90.0) + vec3(0.06) * pow(nh, 10.0) + vec3(0.1) * pow(nh2, 50.0);
65
+ // The groove the glass sits in.
66
+ plastic *= mix(0.25, 1.0, smoothstep(0.0, 0.14, t));
67
+ float a = 1.0 - smoothstep(outer - 1.0, outer + 0.5, d);
68
+ color = over(vec4(plastic * a, a), color);
69
+ }
70
+
71
+ // The glass.
72
+ if (d < R + 1.0) {
73
+ float r = clamp(d / R, 0.0, 1.0);
74
+ float s = r * (uA + (1.0 - uA) * r * r);
75
+ float ca = 0.012 * r * r * r;
76
+ vec2 at = dir * 0.5;
77
+ vec4 g = texture2D(uScene, 0.5 + at * s);
78
+ g.r = texture2D(uScene, 0.5 + at * s * (1.0 + ca)).r;
79
+ g.b = texture2D(uScene, 0.5 + at * s * (1.0 - ca)).b;
80
+ // Darker towards the edge, where the light bends away, and in the
81
+ // rim's shadow on the side away from the light.
82
+ g.rgb *= mix(1.0, 0.7, smoothstep(0.8, 1.0, r));
83
+ g.rgb *= 1.0 - 0.3 * smoothstep(0.9, 1.0, r) * (0.5 - 0.5 * lit);
84
+ // What the glass mirrors: a soft window and an arc on its lit edge.
85
+ vec2 q = (vPos / R - vec2(-0.36, 0.42)) * vec2(2.3, 3.4);
86
+ float spot = 0.07 * exp(-dot(q, q));
87
+ float arc = 0.4 * smoothstep(0.85, 0.96, r) * (1.0 - smoothstep(0.96, 1.0, r)) * max(0.0, lit);
88
+ vec4 glass = vec4(g.rgb + vec3(spot + arc), clamp(g.a + spot + arc, 0.0, 1.0));
89
+ float a = 1.0 - smoothstep(R - 1.0, R + 0.5, d);
90
+ color = mix(color, glass, a);
91
+ }
92
+
93
+ if (color.a <= 0.0) discard;
94
+ gl_FragColor = vec4(color.rgb / color.a, color.a);
95
+ #include <tonemapping_fragment>
96
+ #include <colorspace_fragment>
97
+ gl_FragColor.rgb *= gl_FragColor.a;
98
+ }
99
+ `;
100
+ /** The magnifying glass: its picture of the book and the glass drawn over
101
+ * the screen. */
102
+ export class Loupe {
103
+ target = null;
104
+ camera = new PerspectiveCamera();
105
+ overlay = new Scene();
106
+ overlayCamera = new OrthographicCamera(0, 1, 1, 0, -1, 1);
107
+ mesh;
108
+ constructor() {
109
+ const material = new ShaderMaterial({
110
+ vertexShader: VERTEX,
111
+ fragmentShader: FRAGMENT,
112
+ uniforms: {
113
+ uScene: { value: null },
114
+ uCenter: { value: new Vector2() },
115
+ uGlass: { value: 1 },
116
+ uRim: { value: 1 },
117
+ uShadow: { value: 1 },
118
+ uShadowOffset: { value: new Vector2() },
119
+ uA: { value: LOUPE_A },
120
+ },
121
+ transparent: true,
122
+ premultipliedAlpha: true,
123
+ blending: NormalBlending,
124
+ depthTest: false,
125
+ depthWrite: false,
126
+ toneMapped: true,
127
+ });
128
+ this.mesh = new Mesh(new PlaneGeometry(1, 1), material);
129
+ this.mesh.frustumCulled = false;
130
+ this.overlay.add(this.mesh);
131
+ }
132
+ /** How far from its centre (device px) the field the glass shows
133
+ * reaches on the screen. */
134
+ static field(view) {
135
+ return view.radius / (LOUPE_A * Math.max(1, view.zoom));
136
+ }
137
+ /**
138
+ * Draws the lens's picture: the book from the eye (`camera`, the main
139
+ * view) through the lens's field only, a square around the lens's centre
140
+ * as wide as the field, into a picture with about one texel for each
141
+ * screen pixel at the glass's centre (more towards the rim, which
142
+ * gathers the field in: no multisampling, which would cost more than the
143
+ * book's own frame). `before` and `after` run round the
144
+ * draw (the host swaps in its sharper paintings and turns off what reads
145
+ * the main view's screen).
146
+ */
147
+ capture(renderer, scene, camera, view, before, after) {
148
+ const max = Math.min(MAX_SIDE, renderer.capabilities.maxRenderbufferSize ?? MAX_SIDE);
149
+ const side = Math.max(16, Math.min(max, Math.ceil((2 * view.radius) / LOUPE_A)));
150
+ let target = this.target;
151
+ if (!target) {
152
+ target = new WebGLRenderTarget(side, side, { type: HalfFloatType, minFilter: LinearFilter, magFilter: LinearFilter, generateMipmaps: false });
153
+ this.target = target;
154
+ }
155
+ else if (target.width !== side)
156
+ target.setSize(side, side);
157
+ const field = Loupe.field(view);
158
+ const cam = this.camera;
159
+ cam.copy(camera);
160
+ const v = camera.view;
161
+ const full = v ? { w: v.fullWidth, h: v.fullHeight, x: v.offsetX, y: v.offsetY } : { w: 1, h: 1, x: 0, y: 0 };
162
+ cam.setViewOffset(full.w, full.h, full.x + view.x - field, full.y + view.y - field, 2 * field, 2 * field);
163
+ cam.updateProjectionMatrix();
164
+ cam.updateMatrixWorld();
165
+ const shadows = renderer.shadowMap.autoUpdate;
166
+ // The key's shadow map as the main view drew it.
167
+ renderer.shadowMap.autoUpdate = false;
168
+ before();
169
+ try {
170
+ renderer.setRenderTarget(target);
171
+ renderer.clear();
172
+ renderer.render(scene, cam);
173
+ }
174
+ finally {
175
+ renderer.setRenderTarget(null);
176
+ renderer.shadowMap.autoUpdate = shadows;
177
+ after();
178
+ }
179
+ }
180
+ /** Draws the glass and its rim over the screen (`width` × `height`
181
+ * device px), its picture as `capture` drew it last. */
182
+ draw(renderer, width, height, view) {
183
+ if (!this.target)
184
+ return;
185
+ const cam = this.overlayCamera;
186
+ if (cam.right !== width || cam.top !== height) {
187
+ cam.right = width;
188
+ cam.top = height;
189
+ cam.updateProjectionMatrix();
190
+ }
191
+ const u = this.mesh.material.uniforms;
192
+ const shadow = Math.max(6, view.rim * 1.6);
193
+ const offset = new Vector2(view.rim * 0.35, -view.rim * 0.55);
194
+ const reach = view.radius + view.rim + shadow + offset.length() + 2;
195
+ // The overlay's y runs up from the bottom of the screen.
196
+ const cx = view.x;
197
+ const cy = height - view.y;
198
+ this.mesh.position.set(cx, cy, 0);
199
+ this.mesh.scale.set(2 * reach, 2 * reach, 1);
200
+ this.mesh.updateMatrixWorld();
201
+ u.uScene.value = this.target.texture;
202
+ u.uCenter.value.set(cx, cy);
203
+ u.uGlass.value = view.radius;
204
+ u.uRim.value = view.rim;
205
+ u.uShadow.value = shadow;
206
+ u.uShadowOffset.value.copy(offset);
207
+ const clear = renderer.autoClear;
208
+ renderer.autoClear = false;
209
+ renderer.setRenderTarget(null);
210
+ renderer.render(this.overlay, cam);
211
+ renderer.autoClear = clear;
212
+ }
213
+ dispose() {
214
+ this.target?.dispose();
215
+ this.target = null;
216
+ this.mesh.geometry.dispose();
217
+ this.mesh.material.dispose();
218
+ }
219
+ }
220
+ //# sourceMappingURL=loupe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loupe.js","sourceRoot":"","sources":["../src/loupe.ts"],"names":[],"mappings":"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"}
@@ -261,6 +261,12 @@ export declare class PageFlipper {
261
261
  * tilted by `pitch` (radians from straight above); null: the
262
262
  * settings' `yaw` and `tilt`. */
263
263
  private orbit;
264
+ /** The magnifying glass over the book (#527), in CSS px (client
265
+ * coordinates for its centre), and the sharper paintings it shows the
266
+ * pages in: page source → its painting and texture. */
267
+ private lens;
268
+ private loupe;
269
+ private details;
264
270
  private paper;
265
271
  constructor(canvas: HTMLCanvasElement, spread: HTMLElement, book: SpreadSrc[], at: number, onSettle: (index: number) => void,
266
272
  /** The reader's hand turned the book to another spread. */
@@ -470,6 +476,29 @@ export declare class PageFlipper {
470
476
  * speed, never jumping. */
471
477
  release(click?: boolean): void;
472
478
  private draw;
479
+ /** Holds a magnifying glass over the book: its centre (client px), the
480
+ * radius of its glass and the width of its rim (CSS px), and how much
481
+ * it magnifies at its centre; null puts it away. */
482
+ setLens(lens: {
483
+ x: number;
484
+ y: number;
485
+ radius: number;
486
+ rim: number;
487
+ zoom: number;
488
+ } | null): void;
489
+ /** The largest texture the book can show (a painting for the glass is
490
+ * kept within it). */
491
+ get maxTextureSize(): number;
492
+ /** The sharper paintings the glass shows the pages in: page source (as
493
+ * given in the book) → its painting; pages left out are shown as
494
+ * painted, and their sharper textures are freed. */
495
+ setDetail(details: ReadonlyMap<PageSource, PageSource>): void;
496
+ /** Draws the glass over the frame just drawn: the book once more
497
+ * through its field, the pages in their sharper paintings, then the
498
+ * glass and its rim. What reads the main view's screen (the light
499
+ * through a thin leaf, a gloss page's mirror) is left out of its
500
+ * picture. */
501
+ private drawLoupe;
473
502
  /**
474
503
  * Thin paper lets light through (#484). While translucent leaves are in
475
504
  * the air, the scene is drawn once more without them (at half the
@@ -1 +1 @@
1
- {"version":3,"file":"pageFlip.d.ts","sourceRoot":"","sources":["../src/pageFlip.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pageFlip.d.ts","sourceRoot":"","sources":["../src/pageFlip.ts"],"names":[],"mappings":"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"}
package/dist/pageFlip.js CHANGED
@@ -10,6 +10,7 @@ import { pagePaper, paperSpec } from "./paper";
10
10
  import { loadDeskMaps } from "./deskTextures";
11
11
  import { ATLAS_MAX, MAX_PAGE_VIDEOS, VideoAtlas } from "./videoAtlas";
12
12
  import { cachedDesk, cachedRelief } from "./procedural";
13
+ import { Loupe } from "./loupe";
13
14
  /** Columns and rows of a leaf's mesh: fine enough for a tight roll. */
14
15
  const NX = 96;
15
16
  /** How far a leaf's folded paper stays over its own paper beneath it. */
@@ -1021,6 +1022,12 @@ export class PageFlipper {
1021
1022
  * tilted by `pitch` (radians from straight above); null: the
1022
1023
  * settings' `yaw` and `tilt`. */
1023
1024
  orbit = { yaw: null, pitch: null };
1025
+ /** The magnifying glass over the book (#527), in CSS px (client
1026
+ * coordinates for its centre), and the sharper paintings it shows the
1027
+ * pages in: page source → its painting and texture. */
1028
+ lens = null;
1029
+ loupe = null;
1030
+ details = new Map();
1024
1031
  paper = [1, 1, 1];
1025
1032
  constructor(canvas, spread, book, at, onSettle,
1026
1033
  /** The reader's hand turned the book to another spread. */
@@ -2665,6 +2672,95 @@ export class PageFlipper {
2665
2672
  this.mirror(air.length > 0 || this.block !== null);
2666
2673
  this.behind(air.map((a) => a.mesh));
2667
2674
  this.composer.render();
2675
+ this.drawLoupe();
2676
+ }
2677
+ // ── The magnifying glass (#527) ──
2678
+ /** Holds a magnifying glass over the book: its centre (client px), the
2679
+ * radius of its glass and the width of its rim (CSS px), and how much
2680
+ * it magnifies at its centre; null puts it away. */
2681
+ setLens(lens) {
2682
+ if (!lens && !this.lens)
2683
+ return;
2684
+ this.lens = lens;
2685
+ if (!this.raf)
2686
+ this.redraw();
2687
+ }
2688
+ /** The largest texture the book can show (a painting for the glass is
2689
+ * kept within it). */
2690
+ get maxTextureSize() {
2691
+ return this.renderer.capabilities.maxTextureSize ?? 4096;
2692
+ }
2693
+ /** The sharper paintings the glass shows the pages in: page source (as
2694
+ * given in the book) → its painting; pages left out are shown as
2695
+ * painted, and their sharper textures are freed. */
2696
+ setDetail(details) {
2697
+ for (const [page, d] of this.details) {
2698
+ if (details.get(page) === d.src)
2699
+ continue;
2700
+ d.tex?.dispose();
2701
+ this.details.delete(page);
2702
+ }
2703
+ for (const [page, src] of details) {
2704
+ if (!page || !src || this.details.has(page))
2705
+ continue;
2706
+ const entry = { src, tex: null };
2707
+ this.details.set(page, entry);
2708
+ const prepare = (tex) => {
2709
+ tex.colorSpace = SRGBColorSpace;
2710
+ tex.minFilter = LinearMipmapLinearFilter;
2711
+ tex.anisotropy = this.renderer.capabilities.getMaxAnisotropy();
2712
+ if (this.details.get(page) !== entry)
2713
+ return tex.dispose();
2714
+ entry.tex = tex;
2715
+ this.redraw();
2716
+ };
2717
+ if (typeof src === "string")
2718
+ void this.loader.loadAsync(src).then(prepare, () => undefined);
2719
+ else {
2720
+ const decoded = src instanceof HTMLCanvasElement ? Promise.resolve() : src.decode();
2721
+ void decoded.then(() => {
2722
+ const tex = new Texture(src);
2723
+ tex.needsUpdate = true;
2724
+ prepare(tex);
2725
+ }, () => undefined);
2726
+ }
2727
+ }
2728
+ }
2729
+ /** Draws the glass over the frame just drawn: the book once more
2730
+ * through its field, the pages in their sharper paintings, then the
2731
+ * glass and its rim. What reads the main view's screen (the light
2732
+ * through a thin leaf, a gloss page's mirror) is left out of its
2733
+ * picture. */
2734
+ drawLoupe() {
2735
+ const lens = this.lens;
2736
+ if (!lens)
2737
+ return;
2738
+ const rect = this.canvas.getBoundingClientRect();
2739
+ const k = this.dpr;
2740
+ const view = { x: (lens.x - rect.left) * k, y: (lens.y - rect.top) * k, radius: lens.radius * k, rim: lens.rim * k, zoom: lens.zoom };
2741
+ this.loupe ??= new Loupe();
2742
+ const undo = [];
2743
+ const swap = (slot, value) => {
2744
+ const was = slot.value;
2745
+ slot.value = value;
2746
+ undo.push(() => (slot.value = was));
2747
+ };
2748
+ this.loupe.capture(this.renderer, this.scene, this.camera, view, () => {
2749
+ swap(behindUniforms.uBehindOn, 0);
2750
+ for (const mesh of this.pageMeshes()) {
2751
+ const u = mesh.material.userData.uniforms;
2752
+ swap(u.uReflectionOn, 0);
2753
+ for (const face of ["Front", "Back"]) {
2754
+ const tex = this.details.get(mesh.userData[face])?.tex;
2755
+ if (tex && u[`uHas${face}`].value === 1)
2756
+ swap(u[`u${face}`], tex);
2757
+ }
2758
+ }
2759
+ }, () => {
2760
+ for (const f of undo.reverse())
2761
+ f();
2762
+ });
2763
+ this.loupe.draw(this.renderer, this.buffer.x, this.buffer.y, view);
2668
2764
  }
2669
2765
  /**
2670
2766
  * Thin paper lets light through (#484). While translucent leaves are in
@@ -2860,6 +2956,10 @@ export class PageFlipper {
2860
2956
  tex.dispose();
2861
2957
  this.shadowTarget?.dispose();
2862
2958
  this.composer.dispose();
2959
+ this.loupe?.dispose();
2960
+ for (const d of this.details.values())
2961
+ d.tex?.dispose();
2962
+ this.details.clear();
2863
2963
  this.mirrors.left?.dispose();
2864
2964
  this.mirrors.right?.dispose();
2865
2965
  this.behindTarget?.depthTexture?.dispose();