postext-folio 0.6.0 → 0.6.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/dist/pageFlip.d.ts +4 -2
- package/dist/pageFlip.d.ts.map +1 -1
- package/dist/pageFlip.js +123 -35
- package/dist/pageFlip.js.map +1 -1
- package/dist/styles.d.ts +1 -1
- package/dist/styles.d.ts.map +1 -1
- package/dist/styles.js +4 -1
- package/dist/styles.js.map +1 -1
- package/dist/viewer.d.ts.map +1 -1
- package/dist/viewer.js +6 -1
- package/dist/viewer.js.map +1 -1
- package/package.json +3 -3
package/dist/pageFlip.d.ts
CHANGED
|
@@ -172,6 +172,7 @@ export declare class PageFlipper {
|
|
|
172
172
|
private renderer;
|
|
173
173
|
private scene;
|
|
174
174
|
private camera;
|
|
175
|
+
private composer;
|
|
175
176
|
private left;
|
|
176
177
|
private right;
|
|
177
178
|
private desk;
|
|
@@ -430,8 +431,9 @@ export declare class PageFlipper {
|
|
|
430
431
|
/** A board turns on the joint at the top of the spine; other leaves on
|
|
431
432
|
* the gutter. */
|
|
432
433
|
private rigidOf;
|
|
433
|
-
/** The page under the pointer
|
|
434
|
-
* recto), −1 the other, 0
|
|
434
|
+
/** The page under the pointer, by its outer part (where a hand takes
|
|
435
|
+
* it): +1 the one a forward turn takes (the recto), −1 the other, 0
|
|
436
|
+
* none (off the pages, or nearer the spine). */
|
|
435
437
|
hit(event: {
|
|
436
438
|
clientX: number;
|
|
437
439
|
clientY: number;
|
package/dist/pageFlip.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pageFlip.d.ts","sourceRoot":"","sources":["../src/pageFlip.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,cAAc,EAoBd,KAAK,EAoBN,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"pageFlip.d.ts","sourceRoot":"","sources":["../src/pageFlip.ts"],"names":[],"mappings":"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"}
|
package/dist/pageFlip.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { BoxGeometry, BufferAttribute, BufferGeometry, Color, CustomBlending, DepthTexture, DirectionalLight, DoubleSide, Group, HalfFloatType, LinearMipmapLinearFilter, MaxEquation, Mesh, MeshPhysicalMaterial, MeshStandardMaterial, LinearFilter, Matrix4, NeutralToneMapping, OneFactor, OrthographicCamera, PCFShadowMap, PerspectiveCamera, Plane, PlaneGeometry, PMREMGenerator, Raycaster, Scene, ShaderChunk, ShaderMaterial, ShadowMaterial, SRGBColorSpace, Texture, TextureLoader, Vector2, Vector3, Vector4, VideoTexture, WebGLRenderer, WebGLRenderTarget, } from "three";
|
|
2
|
+
import { EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer.js";
|
|
3
|
+
import { OutputPass } from "three/examples/jsm/postprocessing/OutputPass.js";
|
|
4
|
+
import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass.js";
|
|
5
|
+
import { SMAAPass } from "three/examples/jsm/postprocessing/SMAAPass.js";
|
|
2
6
|
import { resolveFolioConfig } from "postext";
|
|
3
7
|
import { along, BINDINGS, gutterOcclusion, profiles, stackGeometry, topAt } from "./bookGeometry";
|
|
4
8
|
import { environment } from "./environments";
|
|
@@ -7,6 +11,10 @@ import { loadDeskMaps } from "./deskTextures";
|
|
|
7
11
|
import { cachedDesk, cachedRelief } from "./procedural";
|
|
8
12
|
/** Columns and rows of a leaf's mesh: fine enough for a tight roll. */
|
|
9
13
|
const NX = 96;
|
|
14
|
+
/** How far a leaf's folded paper stays over its own paper beneath it. */
|
|
15
|
+
const OWN_GAP = 1.2;
|
|
16
|
+
/** How much higher than at rest a leaf in the air stays over a block. */
|
|
17
|
+
const BLOCK_GAP = 1.5;
|
|
10
18
|
const NY = 120;
|
|
11
19
|
/** Columns of a page lying open (its curve runs across only). */
|
|
12
20
|
const NX_OPEN = 72;
|
|
@@ -23,6 +31,9 @@ export const BLOCK_PAGES = 10;
|
|
|
23
31
|
/** How long a block of leaves takes to go over (ms), a little longer for
|
|
24
32
|
* a thicker one. */
|
|
25
33
|
const BLOCK_DURATION = 1150;
|
|
34
|
+
/** A page is taken by its outer part only: from this fraction of its
|
|
35
|
+
* width from the spine out to the fore-edge (#494). */
|
|
36
|
+
const GRIP = 0.5;
|
|
26
37
|
/** A leaf follows the one before it once that one is this far through its turn. */
|
|
27
38
|
const GAP = 0.14;
|
|
28
39
|
// Ambient occlusion from the book's own shape: each frame the book is
|
|
@@ -623,12 +634,33 @@ export function foldOf(G, P, W, H, roll = 1) {
|
|
|
623
634
|
// straight, lands over the hand: R sinθ + (c − Rθ) cosθ = c − D.
|
|
624
635
|
const arc = R * theta;
|
|
625
636
|
const k = arc > 0 ? Math.min(1, D / arc) : 0;
|
|
626
|
-
|
|
637
|
+
const free = (D + k * (R * Math.sin(theta) - arc * Math.cos(theta))) / (1 - Math.cos(theta));
|
|
638
|
+
let c = free;
|
|
627
639
|
for (const S of [-H / 2, H / 2])
|
|
628
640
|
c = Math.min(c, G.u * n.u + (G.v - S) * n.v);
|
|
629
641
|
if (c <= 0)
|
|
630
642
|
return null;
|
|
631
|
-
|
|
643
|
+
const F = { u: G.u - n.u * c, v: G.v - n.v * c };
|
|
644
|
+
// Never all at once (#502). Paper lying beyond the point taken, along
|
|
645
|
+
// the pull (a page taken by the middle of an edge and pulled across),
|
|
646
|
+
// turns over as the hand carries it away, not the moment it moves (a
|
|
647
|
+
// pixel's pull stood half the page up). A fold held off the spine short
|
|
648
|
+
// of the hand turns the less the nearer it comes to the point taken, so
|
|
649
|
+
// that it is gone, not dropped, when it reaches it.
|
|
650
|
+
let beyond = 0;
|
|
651
|
+
for (const u of [0, W])
|
|
652
|
+
for (const v of [-H / 2, H / 2])
|
|
653
|
+
beyond = Math.max(beyond, (u - G.u) * n.u + (v - G.v) * n.v);
|
|
654
|
+
const turns = (c / free) * (beyond > 0 ? smooth(0, 0.5 * beyond, D) : 1);
|
|
655
|
+
return { F, n, R, theta: theta * turns };
|
|
656
|
+
}
|
|
657
|
+
/** Paper `d` past the fold, round a roll of radius R and straight on at
|
|
658
|
+
* θ: how far it reaches back across the page, and how high it stands. */
|
|
659
|
+
function rollOf(d, R, theta) {
|
|
660
|
+
if (R > 1e-3 && d < R * theta)
|
|
661
|
+
return [R * Math.sin(d / R), R * (1 - Math.cos(d / R))];
|
|
662
|
+
const rest = d - R * theta;
|
|
663
|
+
return [R * Math.sin(theta) + rest * Math.cos(theta), R * (1 - Math.cos(theta)) + rest * Math.sin(theta)];
|
|
632
664
|
}
|
|
633
665
|
/** How far through its turn a leaf is: the point taken, from where it
|
|
634
666
|
* was to its mirror image across the spine. */
|
|
@@ -704,13 +736,17 @@ export function layLeaf(geometry, fold, forward, W, H, lift, book, rigidity, q,
|
|
|
704
736
|
// corner barely lifted, a few degrees through the middle of the turn.
|
|
705
737
|
const inAir = smooth(0.02, 0.22, q) * smooth(0.02, 0.22, 1 - q);
|
|
706
738
|
const lean = LEAN * inAir;
|
|
707
|
-
const cosA = Math.cos(lean);
|
|
708
|
-
const sinA = Math.sin(lean);
|
|
709
739
|
// Each side's chord, from the spine to its fore-edge: a side hanging
|
|
710
740
|
// from a standing spine slopes down to the desk, and a leaf leaning off
|
|
711
741
|
// it leans off that slope, not off a level plane over it.
|
|
712
742
|
const chordR = (zr - zr0) / (xr || 1);
|
|
713
743
|
const chordL = (zl - zl0) / (xl || 1);
|
|
744
|
+
// The plane a leaf lifts off along, by side: the chord turned up by the
|
|
745
|
+
// lean. A leaf keeps its width along it (stepping the chord's rise per
|
|
746
|
+
// unit across, on a side sloping to the desk, stretched it by a tenth
|
|
747
|
+
// and more, #495).
|
|
748
|
+
const tiltR = Math.atan(chordR) + lean;
|
|
749
|
+
const tiltL = Math.atan(chordL) + lean;
|
|
714
750
|
// Onto the book. At rest (and as it lands) the leaf lies on the open
|
|
715
751
|
// book's surface, into the gutter and out. In the air it is lifted off
|
|
716
752
|
// at the spine: its own plane rises from the gutter's floor at a small
|
|
@@ -721,8 +757,9 @@ export function layLeaf(geometry, fold, forward, W, H, lift, book, rigidity, q,
|
|
|
721
757
|
let px = rx;
|
|
722
758
|
let pz = rz + z + lift;
|
|
723
759
|
if (inAir > 0) {
|
|
724
|
-
const
|
|
725
|
-
const
|
|
760
|
+
const tilt = s >= 0 ? tiltR : tiltL;
|
|
761
|
+
const fx = (s >= 0 ? 1 : -1) * Math.abs(s) * Math.cos(tilt);
|
|
762
|
+
const plane = (s >= 0 ? zr0 : zl0) + Math.abs(s) * Math.sin(tilt) + z + lift;
|
|
726
763
|
const under = surfaceAt(book, fx)[1] + lift + 0.6;
|
|
727
764
|
const flying = smoothMax(plane, under, 0.006 * W);
|
|
728
765
|
px += (fx - px) * inAir;
|
|
@@ -730,6 +767,33 @@ export function layLeaf(geometry, fold, forward, W, H, lift, book, rigidity, q,
|
|
|
730
767
|
}
|
|
731
768
|
return [px, pz];
|
|
732
769
|
};
|
|
770
|
+
// Thin paper ripples in the air, more towards its free edge. Never
|
|
771
|
+
// down into the pages under it: the ripple dies away where the leaf
|
|
772
|
+
// lies close over them (it stays at least `lift` above them), or a
|
|
773
|
+
// leaf held low over its stack dipped into the page under it, whose
|
|
774
|
+
// print then showed through (#447).
|
|
775
|
+
const ripple = (u, v, px, pz) => {
|
|
776
|
+
const amp = flutter * W * (u / W) * (u / W);
|
|
777
|
+
if (flutter <= 0 || amp <= 1e-6)
|
|
778
|
+
return 0;
|
|
779
|
+
const clear = pz - surfaceAt(book, px)[1] - lift;
|
|
780
|
+
return amp * smooth(0, 2 * amp, clear) * Math.sin(2 * Math.PI * (time / 520) - (3 * u) / W + (2 * v) / H);
|
|
781
|
+
};
|
|
782
|
+
// Where the leaf's paper lies unfolded, column by column (before it
|
|
783
|
+
// ripples): [out from the spine, u, height].
|
|
784
|
+
const clearing = BLOCK_GAP * smooth(0, 0.06, q) * smooth(0, 0.06, 1 - q);
|
|
785
|
+
const own = [];
|
|
786
|
+
if (fold) {
|
|
787
|
+
for (let ix = 0; ix <= NX; ix++) {
|
|
788
|
+
const u = column(ix / NX) * W;
|
|
789
|
+
let [ox, oz] = onBook(sx * u, 0);
|
|
790
|
+
if (r > 0) {
|
|
791
|
+
ox += (u * Math.cos(phi) - offset * Math.sin(phi) - ox) * r;
|
|
792
|
+
oz += (hinge + lift + u * Math.sin(phi) + offset * Math.cos(phi) - oz) * r;
|
|
793
|
+
}
|
|
794
|
+
own.push([sx * ox, u, oz]);
|
|
795
|
+
}
|
|
796
|
+
}
|
|
733
797
|
for (let iy = 0; iy <= NY; iy++) {
|
|
734
798
|
const v = (0.5 - iy / NY) * H;
|
|
735
799
|
for (let ix = 0; ix <= NX; ix++) {
|
|
@@ -740,22 +804,13 @@ export function layLeaf(geometry, fold, forward, W, H, lift, book, rigidity, q,
|
|
|
740
804
|
let d = 0;
|
|
741
805
|
let dd = 0;
|
|
742
806
|
if (fold) {
|
|
743
|
-
const { F, n
|
|
807
|
+
const { F, n } = fold;
|
|
744
808
|
d = (u - F.u) * n.u + (v - F.v) * n.v;
|
|
745
809
|
if (d > 0) {
|
|
746
810
|
// Round the roll, then straight on at the fold's angle.
|
|
747
|
-
|
|
748
|
-
if (R > 1e-3 && d < R * theta) {
|
|
749
|
-
dd = R * Math.sin(d / R);
|
|
750
|
-
z = R * (1 - Math.cos(d / R));
|
|
751
|
-
}
|
|
752
|
-
else {
|
|
753
|
-
const rest = d - R * theta;
|
|
754
|
-
dd = R * Math.sin(theta) + rest * Math.cos(theta);
|
|
755
|
-
z = R * (1 - Math.cos(theta)) + rest * Math.sin(theta);
|
|
756
|
-
}
|
|
757
|
-
x = u - n.u * (d - dd);
|
|
811
|
+
[dd, z] = rollOf(d, fold.R, fold.theta);
|
|
758
812
|
y = v - n.v * (d - dd);
|
|
813
|
+
x = u - n.u * (d - dd);
|
|
759
814
|
}
|
|
760
815
|
}
|
|
761
816
|
let [px, pz] = onBook(sx * x, z);
|
|
@@ -775,24 +830,42 @@ export function layLeaf(geometry, fold, forward, W, H, lift, book, rigidity, q,
|
|
|
775
830
|
y += (v - y) * r;
|
|
776
831
|
pz += (hinge + lift + u * Math.sin(phi) + offset * Math.cos(phi) - pz) * r;
|
|
777
832
|
}
|
|
778
|
-
|
|
779
|
-
//
|
|
780
|
-
//
|
|
781
|
-
//
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
if (
|
|
787
|
-
|
|
833
|
+
pz += ripple(u, v, px, pz);
|
|
834
|
+
// Never through the leaf's own paper not yet folded, as it ripples
|
|
835
|
+
// too: carried level from a fold low on a side sloping up to the
|
|
836
|
+
// spine, the paper folded back over it ran under it, crossing it.
|
|
837
|
+
if (fold && d > 0) {
|
|
838
|
+
const at = sx * px;
|
|
839
|
+
// (A row past the head and foot too: a triangle reaching past them
|
|
840
|
+
// from paper kept over sagged through.)
|
|
841
|
+
if (at > own[0][0] && at < own[NX][0] && Math.abs(y) <= H / 2 + (1.5 * H) / NY) {
|
|
842
|
+
let lo = 0;
|
|
843
|
+
let hi = NX;
|
|
844
|
+
while (hi - lo > 1) {
|
|
845
|
+
const mid = (lo + hi) >> 1;
|
|
846
|
+
if (own[mid][0] <= at)
|
|
847
|
+
lo = mid;
|
|
848
|
+
else
|
|
849
|
+
hi = mid;
|
|
850
|
+
}
|
|
851
|
+
const f = (at - own[lo][0]) / (own[hi][0] - own[lo][0] || 1);
|
|
852
|
+
const ou = own[lo][1] + (own[hi][1] - own[lo][1]) * f;
|
|
853
|
+
if ((ou - fold.F.u) * fold.n.u + (y - fold.F.v) * fold.n.v < 0) {
|
|
854
|
+
const oz = own[lo][2] + (own[hi][2] - own[lo][2]) * f;
|
|
855
|
+
pz = Math.max(pz, oz + ripple(ou, y, px, oz) + OWN_GAP);
|
|
856
|
+
}
|
|
857
|
+
}
|
|
788
858
|
}
|
|
789
859
|
// Never into the book: over a block (and past its head or foot) a
|
|
790
860
|
// leaf stands at least just over its top. A fold's flap is carried
|
|
791
861
|
// level from the foot of its fold, and on a thin side hanging from
|
|
792
862
|
// the spine that foot lies low: the flap went through the tall block
|
|
793
863
|
// on the other side (#489).
|
|
864
|
+
// In the air a little higher still (until it lands): half a pixel
|
|
865
|
+
// over the block is hardly any depth at the view's distance, and a
|
|
866
|
+
// leaf lying over a tall block's top drew through its page in teeth.
|
|
794
867
|
if (!board && Math.abs(px) < (px >= 0 ? xr : xl))
|
|
795
|
-
pz = Math.max(pz, topAt(px >= 0 ? book.right : book.left, Math.abs(px)) + Math.min(lift, 0.5));
|
|
868
|
+
pz = Math.max(pz, topAt(px >= 0 ? book.right : book.left, Math.abs(px)) + Math.min(lift, 0.5) + clearing);
|
|
796
869
|
pos.setXYZ(iy * (NX + 1) + ix, px, y, pz);
|
|
797
870
|
}
|
|
798
871
|
}
|
|
@@ -857,6 +930,7 @@ export class PageFlipper {
|
|
|
857
930
|
renderer;
|
|
858
931
|
scene = new Scene();
|
|
859
932
|
camera = new PerspectiveCamera(FOV, 1, 1, 10000);
|
|
933
|
+
composer;
|
|
860
934
|
left;
|
|
861
935
|
right;
|
|
862
936
|
desk;
|
|
@@ -965,10 +1039,20 @@ export class PageFlipper {
|
|
|
965
1039
|
this.staticCaster = casterMaterial(false);
|
|
966
1040
|
// `__postextFolioPreserve`: keep the drawing buffer (to read the canvas back while debugging).
|
|
967
1041
|
const preserveDrawingBuffer = !!globalThis.__postextFolioPreserve;
|
|
968
|
-
this.renderer = new WebGLRenderer({ canvas, alpha: true, antialias:
|
|
1042
|
+
this.renderer = new WebGLRenderer({ canvas, alpha: true, antialias: false, premultipliedAlpha: true, preserveDrawingBuffer });
|
|
969
1043
|
this.renderer.outputColorSpace = SRGBColorSpace;
|
|
970
1044
|
this.renderer.toneMapping = NeutralToneMapping;
|
|
971
1045
|
this.renderer.setClearColor(0x000000, 0);
|
|
1046
|
+
// Edges smoothed by SMAA over the finished picture (#503), not by the
|
|
1047
|
+
// canvas's own four samples a pixel: those left steps on long, nearly
|
|
1048
|
+
// level edges of strong contrast (a light page over the dark block)
|
|
1049
|
+
// and cost the most of a frame (resolved into a preserved drawing
|
|
1050
|
+
// buffer); SMAA smooths them better for a fraction of it. The scene
|
|
1051
|
+
// is drawn into a float picture, toned for the screen, then smoothed.
|
|
1052
|
+
this.composer = new EffectComposer(this.renderer, new WebGLRenderTarget(1, 1, { type: HalfFloatType }));
|
|
1053
|
+
this.composer.addPass(new RenderPass(this.scene, this.camera));
|
|
1054
|
+
this.composer.addPass(new OutputPass());
|
|
1055
|
+
this.composer.addPass(new SMAAPass());
|
|
972
1056
|
if (this.renderer.shadowMap) {
|
|
973
1057
|
this.renderer.shadowMap.enabled = true;
|
|
974
1058
|
this.renderer.shadowMap.type = PCFShadowMap;
|
|
@@ -1555,6 +1639,8 @@ export class PageFlipper {
|
|
|
1555
1639
|
const dpr = Math.min(window.devicePixelRatio || 1, 3);
|
|
1556
1640
|
this.renderer.setPixelRatio(1);
|
|
1557
1641
|
this.renderer.setSize(Math.round(cw * dpr), Math.round(ch * dpr), false);
|
|
1642
|
+
this.composer.setPixelRatio(1);
|
|
1643
|
+
this.composer.setSize(Math.round(cw * dpr), Math.round(ch * dpr));
|
|
1558
1644
|
this.buffer.set(Math.round(cw * dpr), Math.round(ch * dpr));
|
|
1559
1645
|
this.dpr = dpr;
|
|
1560
1646
|
const spread = this.spread.getBoundingClientRect();
|
|
@@ -2266,13 +2352,14 @@ export class PageFlipper {
|
|
|
2266
2352
|
rigidOf(k) {
|
|
2267
2353
|
return this.specOf(k).rigidity > 0.5;
|
|
2268
2354
|
}
|
|
2269
|
-
/** The page under the pointer
|
|
2270
|
-
* recto), −1 the other, 0
|
|
2355
|
+
/** The page under the pointer, by its outer part (where a hand takes
|
|
2356
|
+
* it): +1 the one a forward turn takes (the recto), −1 the other, 0
|
|
2357
|
+
* none (off the pages, or nearer the spine). */
|
|
2271
2358
|
hit(event) {
|
|
2272
2359
|
if (!this.surfaces)
|
|
2273
2360
|
this.layout();
|
|
2274
2361
|
const { x, y } = this.toWorld(event);
|
|
2275
|
-
if (Math.abs(y) > this.H / 2 || Math.abs(x) > this.W * 1.05)
|
|
2362
|
+
if (Math.abs(y) > this.H / 2 || Math.abs(x) > this.W * 1.05 || Math.abs(x) < GRIP * this.W)
|
|
2276
2363
|
return 0;
|
|
2277
2364
|
return x > 0 ? 1 : -1;
|
|
2278
2365
|
}
|
|
@@ -2286,7 +2373,7 @@ export class PageFlipper {
|
|
|
2286
2373
|
const at = this.settledAt();
|
|
2287
2374
|
const forward = x > 0;
|
|
2288
2375
|
const k = forward ? at : at - 1;
|
|
2289
|
-
if (k < 0 || k >= this.turned.length || Math.abs(x) > this.W * 1.05 || Math.abs(y) > this.H / 2)
|
|
2376
|
+
if (k < 0 || k >= this.turned.length || Math.abs(x) > this.W * 1.05 || Math.abs(x) < GRIP * this.W || Math.abs(y) > this.H / 2)
|
|
2290
2377
|
return false;
|
|
2291
2378
|
const G = { u: Math.max(0.15 * this.W, Math.min(this.W, Math.abs(x))), v: y };
|
|
2292
2379
|
this.turns.set(k, { forward, G, P: { ...G }, held: { aim: { ...G }, samples: [] }, rigid: this.rigidOf(k) });
|
|
@@ -2531,7 +2618,7 @@ export class PageFlipper {
|
|
|
2531
2618
|
}
|
|
2532
2619
|
this.mirror(air.length > 0 || this.block !== null);
|
|
2533
2620
|
this.behind(air.map((a) => a.mesh));
|
|
2534
|
-
this.
|
|
2621
|
+
this.composer.render();
|
|
2535
2622
|
}
|
|
2536
2623
|
/**
|
|
2537
2624
|
* Thin paper lets light through (#484). While translucent leaves are in
|
|
@@ -2726,6 +2813,7 @@ export class PageFlipper {
|
|
|
2726
2813
|
for (const tex of this.ready.values())
|
|
2727
2814
|
tex.dispose();
|
|
2728
2815
|
this.shadowTarget?.dispose();
|
|
2816
|
+
this.composer.dispose();
|
|
2729
2817
|
this.mirrors.left?.dispose();
|
|
2730
2818
|
this.mirrors.right?.dispose();
|
|
2731
2819
|
this.behindTarget?.depthTexture?.dispose();
|