postext-folio 0.7.1 → 0.8.1

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. */
@@ -1940,9 +1947,19 @@ export class PageFlipper {
1940
1947
  if (!src || typeof src === "string")
1941
1948
  return;
1942
1949
  const tex = this.ready.get(src);
1943
- if (!tex)
1950
+ // A sharper painting for the glass too (its decorations drawn again,
1951
+ // #543).
1952
+ let detail = false;
1953
+ for (const d of this.details.values()) {
1954
+ if (d.src !== src || !d.tex)
1955
+ continue;
1956
+ d.tex.needsUpdate = true;
1957
+ detail = true;
1958
+ }
1959
+ if (!tex && !detail)
1944
1960
  return;
1945
- tex.needsUpdate = true;
1961
+ if (tex)
1962
+ tex.needsUpdate = true;
1946
1963
  this.redraw();
1947
1964
  }
1948
1965
  /** Starts loading the pages of these spreads as textures. */
@@ -2665,6 +2682,95 @@ export class PageFlipper {
2665
2682
  this.mirror(air.length > 0 || this.block !== null);
2666
2683
  this.behind(air.map((a) => a.mesh));
2667
2684
  this.composer.render();
2685
+ this.drawLoupe();
2686
+ }
2687
+ // ── The magnifying glass (#527) ──
2688
+ /** Holds a magnifying glass over the book: its centre (client px), the
2689
+ * radius of its glass and the width of its rim (CSS px), and how much
2690
+ * it magnifies at its centre; null puts it away. */
2691
+ setLens(lens) {
2692
+ if (!lens && !this.lens)
2693
+ return;
2694
+ this.lens = lens;
2695
+ if (!this.raf)
2696
+ this.redraw();
2697
+ }
2698
+ /** The largest texture the book can show (a painting for the glass is
2699
+ * kept within it). */
2700
+ get maxTextureSize() {
2701
+ return this.renderer.capabilities.maxTextureSize ?? 4096;
2702
+ }
2703
+ /** The sharper paintings the glass shows the pages in: page source (as
2704
+ * given in the book) → its painting; pages left out are shown as
2705
+ * painted, and their sharper textures are freed. */
2706
+ setDetail(details) {
2707
+ for (const [page, d] of this.details) {
2708
+ if (details.get(page) === d.src)
2709
+ continue;
2710
+ d.tex?.dispose();
2711
+ this.details.delete(page);
2712
+ }
2713
+ for (const [page, src] of details) {
2714
+ if (!page || !src || this.details.has(page))
2715
+ continue;
2716
+ const entry = { src, tex: null };
2717
+ this.details.set(page, entry);
2718
+ const prepare = (tex) => {
2719
+ tex.colorSpace = SRGBColorSpace;
2720
+ tex.minFilter = LinearMipmapLinearFilter;
2721
+ tex.anisotropy = this.renderer.capabilities.getMaxAnisotropy();
2722
+ if (this.details.get(page) !== entry)
2723
+ return tex.dispose();
2724
+ entry.tex = tex;
2725
+ this.redraw();
2726
+ };
2727
+ if (typeof src === "string")
2728
+ void this.loader.loadAsync(src).then(prepare, () => undefined);
2729
+ else {
2730
+ const decoded = src instanceof HTMLCanvasElement ? Promise.resolve() : src.decode();
2731
+ void decoded.then(() => {
2732
+ const tex = new Texture(src);
2733
+ tex.needsUpdate = true;
2734
+ prepare(tex);
2735
+ }, () => undefined);
2736
+ }
2737
+ }
2738
+ }
2739
+ /** Draws the glass over the frame just drawn: the book once more
2740
+ * through its field, the pages in their sharper paintings, then the
2741
+ * glass and its rim. What reads the main view's screen (the light
2742
+ * through a thin leaf, a gloss page's mirror) is left out of its
2743
+ * picture. */
2744
+ drawLoupe() {
2745
+ const lens = this.lens;
2746
+ if (!lens)
2747
+ return;
2748
+ const rect = this.canvas.getBoundingClientRect();
2749
+ const k = this.dpr;
2750
+ 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 };
2751
+ this.loupe ??= new Loupe();
2752
+ const undo = [];
2753
+ const swap = (slot, value) => {
2754
+ const was = slot.value;
2755
+ slot.value = value;
2756
+ undo.push(() => (slot.value = was));
2757
+ };
2758
+ this.loupe.capture(this.renderer, this.scene, this.camera, view, () => {
2759
+ swap(behindUniforms.uBehindOn, 0);
2760
+ for (const mesh of this.pageMeshes()) {
2761
+ const u = mesh.material.userData.uniforms;
2762
+ swap(u.uReflectionOn, 0);
2763
+ for (const face of ["Front", "Back"]) {
2764
+ const tex = this.details.get(mesh.userData[face])?.tex;
2765
+ if (tex && u[`uHas${face}`].value === 1)
2766
+ swap(u[`u${face}`], tex);
2767
+ }
2768
+ }
2769
+ }, () => {
2770
+ for (const f of undo.reverse())
2771
+ f();
2772
+ });
2773
+ this.loupe.draw(this.renderer, this.buffer.x, this.buffer.y, view);
2668
2774
  }
2669
2775
  /**
2670
2776
  * Thin paper lets light through (#484). While translucent leaves are in
@@ -2860,6 +2966,10 @@ export class PageFlipper {
2860
2966
  tex.dispose();
2861
2967
  this.shadowTarget?.dispose();
2862
2968
  this.composer.dispose();
2969
+ this.loupe?.dispose();
2970
+ for (const d of this.details.values())
2971
+ d.tex?.dispose();
2972
+ this.details.clear();
2863
2973
  this.mirrors.left?.dispose();
2864
2974
  this.mirrors.right?.dispose();
2865
2975
  this.behindTarget?.depthTexture?.dispose();