leafthrough 0.1.5 → 0.1.7
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 +95 -10
- package/dist/LeafThroughObject.d.ts +10 -2
- package/dist/{chunk-GYSQO7QZ.js → chunk-KCIOFDSW.js} +259 -87
- package/dist/chunk-KCIOFDSW.js.map +1 -0
- package/dist/element.js +1 -1
- package/dist/engine.d.ts +5 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +49 -7
- package/dist/index.js.map +1 -1
- package/dist/options.d.ts +32 -1
- package/dist/paper/paperMaterial.d.ts +7 -5
- package/dist/paper/paperPattern.d.ts +6 -0
- package/dist/react.js +1 -1
- package/dist/shared.d.ts +19 -0
- package/dist/single/SingleEngine.d.ts +4 -0
- package/dist/single/singleSheet.d.ts +8 -0
- package/dist/spread/SpreadEngine.d.ts +2 -0
- package/dist/spread/spreadSheet.d.ts +8 -0
- package/dist/svelte.js +1 -1
- package/dist/textures.d.ts +5 -0
- package/dist/vue.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-GYSQO7QZ.js.map +0 -1
|
@@ -33,8 +33,11 @@ function resolveSettings(options, layout, prefersReducedMotion) {
|
|
|
33
33
|
backColor: paper.backColor ?? "#fcfcf9",
|
|
34
34
|
wrinkles: paper.wrinkles ?? 1,
|
|
35
35
|
bulge: paper.bulge ?? 1,
|
|
36
|
-
cutout: paper.cutout ?? false
|
|
36
|
+
cutout: paper.cutout ?? false,
|
|
37
|
+
sheetGap: Math.max(0, paper.sheetGap ?? 0),
|
|
38
|
+
depthBias: paper.depthBias ?? true
|
|
37
39
|
},
|
|
40
|
+
deform: null,
|
|
38
41
|
lighting: {
|
|
39
42
|
ambient: {
|
|
40
43
|
sky: lighting.ambient?.sky ?? "#ffffff",
|
|
@@ -247,11 +250,11 @@ function displayImage(source, alt = "") {
|
|
|
247
250
|
return img;
|
|
248
251
|
}
|
|
249
252
|
if (typeof HTMLCanvasElement !== "undefined" && (drawable instanceof HTMLCanvasElement || drawable instanceof ImageBitmap)) {
|
|
250
|
-
const
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
return describe(
|
|
253
|
+
const canvas2 = document.createElement("canvas");
|
|
254
|
+
canvas2.width = drawable.width;
|
|
255
|
+
canvas2.height = drawable.height;
|
|
256
|
+
canvas2.getContext("2d")?.drawImage(drawable, 0, 0);
|
|
257
|
+
return describe(canvas2, alt, style);
|
|
255
258
|
}
|
|
256
259
|
return describe(document.createElement("div"), alt, style);
|
|
257
260
|
}
|
|
@@ -423,6 +426,10 @@ import * as THREE7 from "three";
|
|
|
423
426
|
// src/textures.ts
|
|
424
427
|
import * as THREE4 from "three";
|
|
425
428
|
var CONCURRENCY = 4;
|
|
429
|
+
var NEAR = 1;
|
|
430
|
+
var UPLOADS_PER_FRAME = 1;
|
|
431
|
+
var IDLE_SPARE = 8;
|
|
432
|
+
var UPLOAD_TIMEOUT = 100;
|
|
426
433
|
var PageLoader = class {
|
|
427
434
|
constructor(sources, renderer, radius, events) {
|
|
428
435
|
this.sources = sources;
|
|
@@ -440,6 +447,9 @@ var PageLoader = class {
|
|
|
440
447
|
owned = /* @__PURE__ */ new Set();
|
|
441
448
|
inFlight = /* @__PURE__ */ new Map();
|
|
442
449
|
failed = /* @__PURE__ */ new Set();
|
|
450
|
+
// decoded pages waiting for their turn on the GPU
|
|
451
|
+
pending = /* @__PURE__ */ new Map();
|
|
452
|
+
cancelUploads = null;
|
|
443
453
|
// `first` pages load before the rest; the rest go nearest first
|
|
444
454
|
first = [];
|
|
445
455
|
// the pages in view, and the one being read, which loads first among them
|
|
@@ -488,6 +498,15 @@ var PageLoader = class {
|
|
|
488
498
|
this.owned.delete(texture);
|
|
489
499
|
texture.dispose();
|
|
490
500
|
});
|
|
501
|
+
for (const [i, texture] of this.pending) {
|
|
502
|
+
if (this.distance(i) > keep) {
|
|
503
|
+
this.pending.delete(i);
|
|
504
|
+
if (this.owned.delete(texture)) texture.dispose();
|
|
505
|
+
} else if (this.distance(i) <= NEAR) {
|
|
506
|
+
this.pending.delete(i);
|
|
507
|
+
this.show(i, texture);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
491
510
|
this.pump();
|
|
492
511
|
}
|
|
493
512
|
setWrap(wrap) {
|
|
@@ -506,6 +525,9 @@ var PageLoader = class {
|
|
|
506
525
|
}
|
|
507
526
|
dispose() {
|
|
508
527
|
this.disposed = true;
|
|
528
|
+
this.cancelUploads?.();
|
|
529
|
+
this.cancelUploads = null;
|
|
530
|
+
this.pending.clear();
|
|
509
531
|
for (const request of this.inFlight.values()) request.abort();
|
|
510
532
|
for (const texture of this.owned) texture.dispose();
|
|
511
533
|
this.owned.clear();
|
|
@@ -520,7 +542,7 @@ var PageLoader = class {
|
|
|
520
542
|
// starts the most wanted pages while there's room
|
|
521
543
|
pump() {
|
|
522
544
|
if (this.disposed || this.inFlight.size >= CONCURRENCY) return;
|
|
523
|
-
const wanted = (i) => !this.textures[i] && !this.inFlight.has(i) && !this.failed.has(i) && this.distance(i) <= this.radius;
|
|
545
|
+
const wanted = (i) => !this.textures[i] && !this.inFlight.has(i) && !this.pending.has(i) && !this.failed.has(i) && this.distance(i) <= this.radius;
|
|
524
546
|
const queue = [
|
|
525
547
|
...this.first.filter((i) => this.waiting.has(i)),
|
|
526
548
|
...this.sources.map((_, i) => i).sort((a, b) => this.distance(a) - this.distance(b) || Math.abs(a - this.around) - Math.abs(b - this.around))
|
|
@@ -538,13 +560,17 @@ var PageLoader = class {
|
|
|
538
560
|
if (this.owned.delete(texture)) texture.dispose();
|
|
539
561
|
return;
|
|
540
562
|
}
|
|
541
|
-
texture
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
this.
|
|
563
|
+
if (this.owned.has(texture)) {
|
|
564
|
+
texture.colorSpace = THREE4.SRGBColorSpace;
|
|
565
|
+
texture.premultiplyAlpha = true;
|
|
566
|
+
texture.anisotropy = this.renderer.capabilities.getMaxAnisotropy();
|
|
567
|
+
texture.needsUpdate = true;
|
|
568
|
+
}
|
|
569
|
+
if (this.waiting.has(page) || this.distance(page) <= NEAR) this.show(page, texture);
|
|
570
|
+
else {
|
|
571
|
+
this.pending.set(page, texture);
|
|
572
|
+
this.scheduleUploads();
|
|
573
|
+
}
|
|
548
574
|
}).catch((error) => {
|
|
549
575
|
if (this.disposed || request.signal.aborted) return;
|
|
550
576
|
this.failed.add(page);
|
|
@@ -555,6 +581,41 @@ var PageLoader = class {
|
|
|
555
581
|
this.pump();
|
|
556
582
|
});
|
|
557
583
|
}
|
|
584
|
+
// Puts the page's texture on the GPU and hands it over. A texture passed in is taken as it
|
|
585
|
+
// is, so one that's on the GPU already, or shared with the caller's own material, isn't
|
|
586
|
+
// uploaded again: initTexture only uploads what the renderer hasn't got.
|
|
587
|
+
show(page, texture) {
|
|
588
|
+
this.renderer.initTexture(texture);
|
|
589
|
+
this.textures[page] = texture;
|
|
590
|
+
this.events.onLoad(page, texture);
|
|
591
|
+
}
|
|
592
|
+
// the next pending pages, in idle time where the browser offers it, else before the next frame
|
|
593
|
+
scheduleUploads() {
|
|
594
|
+
if (this.cancelUploads || !this.pending.size) return;
|
|
595
|
+
if (typeof requestIdleCallback === "function") {
|
|
596
|
+
const id = requestIdleCallback((deadline) => this.uploadSome(deadline), { timeout: UPLOAD_TIMEOUT });
|
|
597
|
+
this.cancelUploads = () => cancelIdleCallback(id);
|
|
598
|
+
} else {
|
|
599
|
+
const id = requestAnimationFrame(() => this.uploadSome());
|
|
600
|
+
this.cancelUploads = () => cancelAnimationFrame(id);
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
// nearest the reader first
|
|
604
|
+
uploadSome(deadline) {
|
|
605
|
+
this.cancelUploads = null;
|
|
606
|
+
const queue = [...this.pending.keys()].sort(
|
|
607
|
+
(a, b) => this.distance(a) - this.distance(b) || Math.abs(a - this.around) - Math.abs(b - this.around)
|
|
608
|
+
);
|
|
609
|
+
let count = 0;
|
|
610
|
+
for (const page of queue) {
|
|
611
|
+
if (count >= UPLOADS_PER_FRAME && !(deadline && deadline.timeRemaining() > IDLE_SPARE)) break;
|
|
612
|
+
const texture = this.pending.get(page);
|
|
613
|
+
this.pending.delete(page);
|
|
614
|
+
this.show(page, texture);
|
|
615
|
+
count++;
|
|
616
|
+
}
|
|
617
|
+
this.scheduleUploads();
|
|
618
|
+
}
|
|
558
619
|
async createTexture(source, signal) {
|
|
559
620
|
if (source instanceof THREE4.Texture) return source;
|
|
560
621
|
const own = (texture) => (this.owned.add(texture), texture);
|
|
@@ -564,11 +625,11 @@ var PageLoader = class {
|
|
|
564
625
|
if (!source.complete || !source.naturalWidth) await source.decode();
|
|
565
626
|
return own(new THREE4.Texture(source));
|
|
566
627
|
}
|
|
567
|
-
const
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
return own(new THREE4.CanvasTexture(
|
|
628
|
+
const canvas2 = document.createElement("canvas");
|
|
629
|
+
canvas2.width = source.width;
|
|
630
|
+
canvas2.height = source.height;
|
|
631
|
+
canvas2.getContext("2d").drawImage(source, 0, 0);
|
|
632
|
+
return own(new THREE4.CanvasTexture(canvas2));
|
|
572
633
|
}
|
|
573
634
|
};
|
|
574
635
|
function loadImage(url, signal) {
|
|
@@ -632,27 +693,37 @@ function createPaperMaterials(uniforms, shader, settings) {
|
|
|
632
693
|
`
|
|
633
694
|
);
|
|
634
695
|
const noiseAt = (component) => shader.noise ? `aNoise.${component}` : "0.0";
|
|
696
|
+
const deform = settings.deform;
|
|
697
|
+
const deformChunk = deform ? `#include <common>
|
|
698
|
+
uniform vec3 uSheetOrigin;
|
|
699
|
+
${deform.glsl}
|
|
700
|
+
vec3 sheetDeformed(vec3 p, vec2 uv) {
|
|
701
|
+
return deformSheet(p + uSheetOrigin, uv) - uSheetOrigin;
|
|
702
|
+
}` : "#include <common>";
|
|
703
|
+
const deformed = (p, uv) => deform ? `sheetDeformed(${p}, ${uv})` : p;
|
|
704
|
+
const deformUniforms = deform ? { ...deform.uniforms, uSheetOrigin: uniforms.uSheetOrigin } : {};
|
|
635
705
|
const material = new THREE5.MeshStandardMaterial({
|
|
636
706
|
side: THREE5.DoubleSide,
|
|
637
707
|
metalness: paper.metalness,
|
|
638
708
|
roughness: paper.roughness
|
|
639
709
|
});
|
|
640
710
|
material.onBeforeCompile = (program) => {
|
|
641
|
-
Object.assign(program.uniforms, uniforms);
|
|
711
|
+
Object.assign(program.uniforms, uniforms, deformUniforms);
|
|
642
712
|
program.vertexShader = constants + shader.vertexChunk + "varying vec2 vSheetUv;\nvarying vec3 vSheetPosition;\n" + program.vertexShader;
|
|
643
|
-
program.vertexShader = program.vertexShader.replace(
|
|
713
|
+
program.vertexShader = program.vertexShader.replace("#include <common>", deformChunk).replace(
|
|
644
714
|
"#include <beginnormal_vertex>",
|
|
645
715
|
`#include <beginnormal_vertex>
|
|
646
716
|
vec2 sheetStep = vec2(NORMAL_EPSILON, NORMAL_EPSILON / SHEET_ASPECT);
|
|
647
|
-
vec3
|
|
648
|
-
vec3
|
|
649
|
-
vec3
|
|
717
|
+
vec3 sheetShaped = sheetPosition(uv, ${noiseAt("x")});
|
|
718
|
+
vec3 sheetP = ${deformed("sheetShaped", "uv")};
|
|
719
|
+
vec3 sheetPx = ${deformed(`sheetPosition(uv + vec2(sheetStep.x, 0.0), ${noiseAt("y")})`, "uv + vec2(sheetStep.x, 0.0)")};
|
|
720
|
+
vec3 sheetPy = ${deformed(`sheetPosition(uv + vec2(0.0, sheetStep.y), ${noiseAt("z")})`, "uv + vec2(0.0, sheetStep.y)")};
|
|
650
721
|
objectNormal = normalize(cross(sheetPx - sheetP, sheetPy - sheetP));`
|
|
651
722
|
).replace(
|
|
652
723
|
"#include <begin_vertex>",
|
|
653
724
|
`vec3 transformed = sheetP;
|
|
654
725
|
vSheetUv = uv;
|
|
655
|
-
vSheetPosition =
|
|
726
|
+
vSheetPosition = sheetShaped;`
|
|
656
727
|
);
|
|
657
728
|
program.fragmentShader = constants + `uniform sampler2D uFront;
|
|
658
729
|
uniform sampler2D uBack;
|
|
@@ -732,13 +803,13 @@ function createPaperMaterials(uniforms, shader, settings) {
|
|
|
732
803
|
});
|
|
733
804
|
const distanceMaterial = new THREE5.MeshDistanceMaterial({ side: THREE5.DoubleSide });
|
|
734
805
|
depthMaterial.onBeforeCompile = distanceMaterial.onBeforeCompile = (program) => {
|
|
735
|
-
Object.assign(program.uniforms, uniforms);
|
|
806
|
+
Object.assign(program.uniforms, uniforms, deformUniforms);
|
|
736
807
|
program.vertexShader = constants + shader.vertexChunk + "varying vec2 vSheetUv;\nvarying vec3 vSheetPosition;\n" + program.vertexShader;
|
|
737
|
-
program.vertexShader = program.vertexShader.replace(
|
|
808
|
+
program.vertexShader = program.vertexShader.replace("#include <common>", deformChunk).replace(
|
|
738
809
|
"#include <begin_vertex>",
|
|
739
810
|
`vSheetUv = uv;
|
|
740
811
|
vSheetPosition = sheetPosition(uv, ${noiseAt("x")});
|
|
741
|
-
vec3 transformed = vSheetPosition - vec3(SHADOW_OFFSET_X, 0.0, 0.0);`
|
|
812
|
+
vec3 transformed = ${deformed("vSheetPosition - vec3(SHADOW_OFFSET_X, 0.0, 0.0)", "uv")};`
|
|
742
813
|
);
|
|
743
814
|
program.fragmentShader = constants + `
|
|
744
815
|
uniform sampler2D uFront;
|
|
@@ -753,7 +824,7 @@ function createPaperMaterials(uniforms, shader, settings) {
|
|
|
753
824
|
${shader.fragmentChunk ? "if (sheetHidden(vSheetPosition)) discard;" : ""}`
|
|
754
825
|
);
|
|
755
826
|
};
|
|
756
|
-
const cacheKey = constants + shader.vertexChunk + (shader.fragmentChunk ?? "") + (paper.cutout ? "cutout" : "");
|
|
827
|
+
const cacheKey = constants + shader.vertexChunk + (shader.fragmentChunk ?? "") + (paper.cutout ? "cutout" : "") + (deform?.glsl ?? "");
|
|
757
828
|
material.customProgramCacheKey = () => cacheKey;
|
|
758
829
|
depthMaterial.customProgramCacheKey = () => cacheKey;
|
|
759
830
|
distanceMaterial.customProgramCacheKey = () => cacheKey;
|
|
@@ -777,11 +848,11 @@ function createSheetMesh(geometry, uniforms, shader, settings) {
|
|
|
777
848
|
mesh.frustumCulled = false;
|
|
778
849
|
return mesh;
|
|
779
850
|
}
|
|
780
|
-
function layerSheet(mesh, depth, count, moving) {
|
|
851
|
+
function layerSheet(mesh, depth, count, moving, bias) {
|
|
781
852
|
const material = mesh.material;
|
|
782
|
-
material.polygonOffset =
|
|
853
|
+
material.polygonOffset = bias;
|
|
783
854
|
material.polygonOffsetFactor = 0;
|
|
784
|
-
material.polygonOffsetUnits = moving ? -(count + 4) : -(count - Math.min(depth, count));
|
|
855
|
+
material.polygonOffsetUnits = bias ? moving ? -(count + 4) : -(count - Math.min(depth, count)) : 0;
|
|
785
856
|
mesh.renderOrder = depth;
|
|
786
857
|
}
|
|
787
858
|
function disposeSheetMesh(mesh) {
|
|
@@ -802,6 +873,37 @@ function solidTexture(color) {
|
|
|
802
873
|
return texture;
|
|
803
874
|
}
|
|
804
875
|
|
|
876
|
+
// src/shared.ts
|
|
877
|
+
var SharedResources = class {
|
|
878
|
+
entries = /* @__PURE__ */ new Map();
|
|
879
|
+
/** The resource under `key`, made by `make` for the first user. Pair every call with `release`. */
|
|
880
|
+
acquire(key, make) {
|
|
881
|
+
let entry = this.entries.get(key);
|
|
882
|
+
if (!entry) {
|
|
883
|
+
entry = { value: make(), users: 0 };
|
|
884
|
+
this.entries.set(key, entry);
|
|
885
|
+
}
|
|
886
|
+
entry.users++;
|
|
887
|
+
return entry.value;
|
|
888
|
+
}
|
|
889
|
+
/** Lets go of `key`; the last user's release frees it. */
|
|
890
|
+
release(key) {
|
|
891
|
+
const entry = this.entries.get(key);
|
|
892
|
+
if (!entry || --entry.users > 0) return;
|
|
893
|
+
this.entries.delete(key);
|
|
894
|
+
entry.value.dispose();
|
|
895
|
+
}
|
|
896
|
+
};
|
|
897
|
+
var byRenderer = /* @__PURE__ */ new WeakMap();
|
|
898
|
+
function sharedResources(renderer) {
|
|
899
|
+
let shared = byRenderer.get(renderer);
|
|
900
|
+
if (!shared) {
|
|
901
|
+
shared = new SharedResources();
|
|
902
|
+
byRenderer.set(renderer, shared);
|
|
903
|
+
}
|
|
904
|
+
return shared;
|
|
905
|
+
}
|
|
906
|
+
|
|
805
907
|
// src/paper/paperPattern.ts
|
|
806
908
|
import * as THREE6 from "three";
|
|
807
909
|
var SIZE = 384;
|
|
@@ -852,7 +954,9 @@ function spread(values) {
|
|
|
852
954
|
for (const v of values) variance += (v - mean) ** 2;
|
|
853
955
|
return Math.sqrt(variance / values.length) || 1;
|
|
854
956
|
}
|
|
855
|
-
|
|
957
|
+
var canvas = null;
|
|
958
|
+
function paperPatternCanvas() {
|
|
959
|
+
if (canvas) return canvas;
|
|
856
960
|
let s = 7;
|
|
857
961
|
const random = () => (s = s * 1664525 + 1013904223 >>> 0) / 4294967296;
|
|
858
962
|
const noise = new Float32Array(SIZE * SIZE);
|
|
@@ -880,7 +984,7 @@ function createPaperPattern(renderer) {
|
|
|
880
984
|
const cloudScale = CLOUD * spread(grain) / spread(cloud);
|
|
881
985
|
for (let i = 0; i < grain.length; i++) grain[i] += cloud[i] * cloudScale;
|
|
882
986
|
const order = Array.from(grain.keys()).sort((a, b) => grain[a] - grain[b]);
|
|
883
|
-
|
|
987
|
+
canvas = document.createElement("canvas");
|
|
884
988
|
canvas.width = canvas.height = SIZE;
|
|
885
989
|
const ctx = canvas.getContext("2d");
|
|
886
990
|
const image = ctx.createImageData(SIZE, SIZE);
|
|
@@ -896,13 +1000,17 @@ function createPaperPattern(renderer) {
|
|
|
896
1000
|
image.data[o + 3] = 255;
|
|
897
1001
|
});
|
|
898
1002
|
ctx.putImageData(image, 0, 0);
|
|
899
|
-
|
|
1003
|
+
return canvas;
|
|
1004
|
+
}
|
|
1005
|
+
function createPaperPattern(renderer) {
|
|
1006
|
+
const texture = new THREE6.CanvasTexture(paperPatternCanvas());
|
|
900
1007
|
texture.wrapS = texture.wrapT = THREE6.RepeatWrapping;
|
|
901
1008
|
texture.anisotropy = renderer.capabilities.getMaxAnisotropy();
|
|
902
1009
|
return texture;
|
|
903
1010
|
}
|
|
904
1011
|
|
|
905
1012
|
// src/paper/paperTextures.ts
|
|
1013
|
+
var BUILTIN_PATTERN = "paper-pattern";
|
|
906
1014
|
var PaperTextures = class {
|
|
907
1015
|
constructor(backColor, events) {
|
|
908
1016
|
this.events = events;
|
|
@@ -927,30 +1035,34 @@ var PaperTextures = class {
|
|
|
927
1035
|
const grain = settings.paper.grain;
|
|
928
1036
|
const key = grain === true || grain === void 0 ? "builtin" : grain === false ? "none" : grain;
|
|
929
1037
|
if (this.pattern?.key === key) return this.pattern.texture;
|
|
930
|
-
this.pattern?.
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
texture
|
|
1038
|
+
this.pattern?.release();
|
|
1039
|
+
if (key === "builtin") {
|
|
1040
|
+
const shared = sharedResources(renderer);
|
|
1041
|
+
const texture = shared.acquire(BUILTIN_PATTERN, () => createPaperPattern(renderer));
|
|
1042
|
+
this.pattern = { texture, key, release: () => shared.release(BUILTIN_PATTERN) };
|
|
1043
|
+
return texture;
|
|
1044
|
+
}
|
|
1045
|
+
const pattern = { texture: solidTexture("#000000"), key, release: () => pattern.texture.dispose() };
|
|
1046
|
+
this.pattern = pattern;
|
|
1047
|
+
if (key !== "none") {
|
|
936
1048
|
loadGrain(key).then(
|
|
937
1049
|
(loaded) => {
|
|
938
|
-
if (this.pattern
|
|
939
|
-
|
|
940
|
-
|
|
1050
|
+
if (this.pattern !== pattern || this.disposed) return loaded.dispose();
|
|
1051
|
+
pattern.texture.dispose();
|
|
1052
|
+
pattern.texture = loaded;
|
|
941
1053
|
this.events.onGrain();
|
|
942
1054
|
},
|
|
943
1055
|
(error) => {
|
|
944
|
-
if (this.pattern
|
|
1056
|
+
if (this.pattern === pattern && !this.disposed) this.events.onError(error);
|
|
945
1057
|
}
|
|
946
1058
|
);
|
|
947
1059
|
}
|
|
948
|
-
|
|
949
|
-
return texture;
|
|
1060
|
+
return pattern.texture;
|
|
950
1061
|
}
|
|
951
1062
|
dispose() {
|
|
952
1063
|
this.disposed = true;
|
|
953
|
-
this.pattern?.
|
|
1064
|
+
this.pattern?.release();
|
|
1065
|
+
this.pattern = null;
|
|
954
1066
|
this.blank.dispose();
|
|
955
1067
|
this.backBlank.texture.dispose();
|
|
956
1068
|
}
|
|
@@ -1085,6 +1197,7 @@ var vertexChunk = (
|
|
|
1085
1197
|
uniform float uTailBend; // how far the free end bows back
|
|
1086
1198
|
uniform vec3 uCone; // radius change per unit of y, radius at the top, how far to wrap
|
|
1087
1199
|
uniform vec2 uFlipRotation;
|
|
1200
|
+
uniform float uStackGap; // how far the sheet stands off the spine, along its own normal
|
|
1088
1201
|
|
|
1089
1202
|
float sheetPileLift(float x) {
|
|
1090
1203
|
float t = 1.0 - min(x / uPileLift.x, 1.0);
|
|
@@ -1170,7 +1283,7 @@ var vertexChunk = (
|
|
|
1170
1283
|
}
|
|
1171
1284
|
|
|
1172
1285
|
// spin about the spine
|
|
1173
|
-
float z = shape.z + pile.z;
|
|
1286
|
+
float z = shape.z + pile.z + uStackGap;
|
|
1174
1287
|
return vec3(
|
|
1175
1288
|
shape.x * uFlipRotation.x - z * uFlipRotation.y,
|
|
1176
1289
|
shape.y,
|
|
@@ -1196,6 +1309,10 @@ var fragmentChunk = (
|
|
|
1196
1309
|
function createSingleGeometry(aspect) {
|
|
1197
1310
|
return new THREE9.PlaneGeometry(1, aspect, 64, Math.round(64 * aspect));
|
|
1198
1311
|
}
|
|
1312
|
+
function sharedSingleGeometry(shared, aspect) {
|
|
1313
|
+
const key = `single-geometry:${aspect}`;
|
|
1314
|
+
return { geometry: shared.acquire(key, () => createSingleGeometry(aspect)), release: () => shared.release(key) };
|
|
1315
|
+
}
|
|
1199
1316
|
function createSingleSheet(geometry, front, back, pattern, settings, shading) {
|
|
1200
1317
|
const uniforms = {
|
|
1201
1318
|
uPileLift: { value: new THREE9.Vector3(1, 0, 0) },
|
|
@@ -1206,11 +1323,13 @@ function createSingleSheet(geometry, front, back, pattern, settings, shading) {
|
|
|
1206
1323
|
uCone: { value: new THREE9.Vector3(0, 1, 0) },
|
|
1207
1324
|
uFlipRotation: { value: new THREE9.Vector2(1, 0) },
|
|
1208
1325
|
uTrim: { value: new THREE9.Vector3(0, 1, 1) },
|
|
1326
|
+
uStackGap: { value: 0 },
|
|
1209
1327
|
uFront: { value: front },
|
|
1210
1328
|
uBack: { value: back },
|
|
1211
1329
|
uPattern: { value: pattern },
|
|
1212
1330
|
uSpineContact: shading.spineContact,
|
|
1213
|
-
uLightDirection: shading.lightDirection
|
|
1331
|
+
uLightDirection: shading.lightDirection,
|
|
1332
|
+
uSheetOrigin: shading.origin
|
|
1214
1333
|
};
|
|
1215
1334
|
const mesh = createSheetMesh(
|
|
1216
1335
|
geometry,
|
|
@@ -1294,6 +1413,7 @@ var SingleEngine = class {
|
|
|
1294
1413
|
metrics;
|
|
1295
1414
|
requestFrame;
|
|
1296
1415
|
geometry;
|
|
1416
|
+
releaseGeometry;
|
|
1297
1417
|
sheets;
|
|
1298
1418
|
count;
|
|
1299
1419
|
radiusSpacing;
|
|
@@ -1301,6 +1421,7 @@ var SingleEngine = class {
|
|
|
1301
1421
|
fallDelay;
|
|
1302
1422
|
fallDuration;
|
|
1303
1423
|
abort = new AbortController();
|
|
1424
|
+
shading;
|
|
1304
1425
|
current;
|
|
1305
1426
|
turned = 0;
|
|
1306
1427
|
// sum of every sheet's progress, as of the last update
|
|
@@ -1321,10 +1442,13 @@ var SingleEngine = class {
|
|
|
1321
1442
|
this.input = ctx.input;
|
|
1322
1443
|
this.metrics = ctx.metrics;
|
|
1323
1444
|
this.requestFrame = ctx.requestFrame;
|
|
1445
|
+
this.shading = ctx.shading;
|
|
1324
1446
|
this.count = ctx.textures.length;
|
|
1325
1447
|
this.maxPosition = this.count;
|
|
1326
1448
|
this.current = clamp(Math.round(ctx.position), 0, Math.max(this.count - 1, 0));
|
|
1327
|
-
|
|
1449
|
+
const { geometry, release } = sharedSingleGeometry(ctx.shared, ctx.settings.pageAspect);
|
|
1450
|
+
this.geometry = geometry;
|
|
1451
|
+
this.releaseGeometry = release;
|
|
1328
1452
|
this.sheets = ctx.textures.map((front, index) => {
|
|
1329
1453
|
const { mesh, uniforms } = createSingleSheet(this.geometry, front, ctx.blank, ctx.pattern, ctx.settings, ctx.shading);
|
|
1330
1454
|
this.group.add(mesh);
|
|
@@ -1399,11 +1523,16 @@ var SingleEngine = class {
|
|
|
1399
1523
|
if (this.press) this.release(new PointerEvent("pointercancel", { pointerId: this.press.id }));
|
|
1400
1524
|
this.wake();
|
|
1401
1525
|
}
|
|
1526
|
+
setShadows(on) {
|
|
1527
|
+
this.settings.lighting.shadows = on;
|
|
1528
|
+
for (const sheet of this.sheets) sheet.mesh.castShadow = sheet.mesh.receiveShadow = on;
|
|
1529
|
+
this.wake();
|
|
1530
|
+
}
|
|
1402
1531
|
dispose() {
|
|
1403
1532
|
this.cancelHold();
|
|
1404
1533
|
this.abort.abort();
|
|
1405
1534
|
for (const sheet of this.sheets) disposeSheetMesh(sheet.mesh);
|
|
1406
|
-
this.
|
|
1535
|
+
this.releaseGeometry();
|
|
1407
1536
|
}
|
|
1408
1537
|
// --- helpers ----------------------------------------------------------------
|
|
1409
1538
|
randomWobble() {
|
|
@@ -1453,6 +1582,10 @@ var SingleEngine = class {
|
|
|
1453
1582
|
shutting(turned) {
|
|
1454
1583
|
return smooth((this.closing(turned) - 0.6) / 0.4);
|
|
1455
1584
|
}
|
|
1585
|
+
// how far a read page has settled flat under the pile: 0 still on the roll, 1 flat
|
|
1586
|
+
fallOf(sheet, paced, shut) {
|
|
1587
|
+
return Math.max(smooth((paced - (sheet.index + 1) - this.fallDelay) / this.fallDuration), shut);
|
|
1588
|
+
}
|
|
1456
1589
|
inFlight(sheet) {
|
|
1457
1590
|
return this.flights.some((f) => f.sheet === sheet);
|
|
1458
1591
|
}
|
|
@@ -1755,15 +1888,19 @@ var SingleEngine = class {
|
|
|
1755
1888
|
sheet.uniforms.uTrim.value.set(sheet === top || this.busy(sheet) ? 0 : 1, edge.bottom, edge.top);
|
|
1756
1889
|
}
|
|
1757
1890
|
const closing = this.closing(turned) > 0;
|
|
1891
|
+
const paced = this.paced(turned);
|
|
1892
|
+
const shut = this.shutting(turned);
|
|
1758
1893
|
const pileFrom = Math.max(this.current, top?.index ?? this.current);
|
|
1759
1894
|
for (const sheet of this.sheets) {
|
|
1760
1895
|
const i = sheet.index;
|
|
1761
1896
|
sheet.mesh.visible = closing || i <= pileFrom + PILE.renderDepth || this.busy(sheet);
|
|
1762
|
-
|
|
1897
|
+
const depth = i >= this.current ? i - this.current : this.fallOf(sheet, paced, shut) >= 1 ? this.count - this.current + i : this.current - 1 - i;
|
|
1898
|
+
layerSheet(sheet.mesh, depth, this.count, this.busy(sheet), this.settings.paper.depthBias);
|
|
1763
1899
|
}
|
|
1764
1900
|
const read = smooth(this.count > 1 ? this.paced(turned) / (this.count - 1) : 0) * (1 - this.shutting(turned));
|
|
1765
1901
|
this.group.position.x = BOOK.pushRight * read;
|
|
1766
1902
|
this.group.position.z = -BOOK.pushBack * read;
|
|
1903
|
+
this.shading.origin.value.copy(this.group.position);
|
|
1767
1904
|
this.dirty = false;
|
|
1768
1905
|
return true;
|
|
1769
1906
|
}
|
|
@@ -1790,10 +1927,7 @@ var SingleEngine = class {
|
|
|
1790
1927
|
const spineOpen = (ROLL.spineOpenStartDeg + (ROLL.spineOpenEndDeg - ROLL.spineOpenStartDeg) * Math.pow(openFraction, ROLL.spineOpenPower)) * Math.PI / 180;
|
|
1791
1928
|
const shut = this.shutting(turned);
|
|
1792
1929
|
const closed = this.closing(turned) >= 1 ? 1 : 0;
|
|
1793
|
-
const fall =
|
|
1794
|
-
smooth((paced - (sheet.index + 1) - this.fallDelay) / this.fallDuration),
|
|
1795
|
-
shut
|
|
1796
|
-
);
|
|
1930
|
+
const fall = this.fallOf(sheet, paced, shut);
|
|
1797
1931
|
const spacing = this.radiusSpacing[sheet.index] ?? 0;
|
|
1798
1932
|
const topR = ROLL.coverTopRadius + (ROLL.backTopRadius - ROLL.coverTopRadius) * spacing;
|
|
1799
1933
|
const bottomR = ROLL.coverBottomRadius + (ROLL.backBottomRadius - ROLL.coverBottomRadius) * spacing;
|
|
@@ -1833,6 +1967,11 @@ var SingleEngine = class {
|
|
|
1833
1967
|
topReach = Math.min(topReach, edge.top);
|
|
1834
1968
|
}
|
|
1835
1969
|
u.uPileReach.value.set(bottomReach, topReach);
|
|
1970
|
+
const under = P - 1 - sheet.index;
|
|
1971
|
+
const before = Math.max(0, turned - 1 - sheet.index);
|
|
1972
|
+
const around = smooth(T);
|
|
1973
|
+
const offset = fallen ? -(sheet.index + 1) : under + (before - under) * around;
|
|
1974
|
+
u.uStackGap.value = this.settings.paper.sheetGap * (offset + (under - offset) * shut);
|
|
1836
1975
|
}
|
|
1837
1976
|
// a turning page: swing round the spine up to the open angle, then roll round the cone
|
|
1838
1977
|
shapeTurn(sheet, T, spineOpen, radii, tilt) {
|
|
@@ -1891,6 +2030,7 @@ var vertexChunk2 = (settings) => (
|
|
|
1891
2030
|
|
|
1892
2031
|
const float BULGE = ${settings.paper.bulge.toFixed(4)};
|
|
1893
2032
|
const float WRINKLE = ${(0.13 * settings.paper.wrinkles).toFixed(4)};
|
|
2033
|
+
const bool NESTED = ${settings.paper.depthBias ? "false" : "true"};
|
|
1894
2034
|
|
|
1895
2035
|
uniform float uFlipProgress;
|
|
1896
2036
|
uniform float uWrinkleSide;
|
|
@@ -1900,6 +2040,7 @@ var vertexChunk2 = (settings) => (
|
|
|
1900
2040
|
uniform vec2 uFlipRotation;
|
|
1901
2041
|
uniform float uDirection;
|
|
1902
2042
|
uniform float uStackLift;
|
|
2043
|
+
uniform float uStackGap;
|
|
1903
2044
|
|
|
1904
2045
|
attribute vec3 aNoise;
|
|
1905
2046
|
|
|
@@ -1916,8 +2057,11 @@ var vertexChunk2 = (settings) => (
|
|
|
1916
2057
|
float y = (uv.y - 0.5) * SHEET_ASPECT;
|
|
1917
2058
|
|
|
1918
2059
|
// Every sheet shares the same wrinkles and bulge, scaled by its place in the stack,
|
|
1919
|
-
// so stacked sheets nest inside each other instead of crossing.
|
|
1920
|
-
|
|
2060
|
+
// so stacked sheets nest inside each other instead of crossing. Where a wrinkle dips, a
|
|
2061
|
+
// bigger one dips below the sheets under it, which only the depth bias hides; without it
|
|
2062
|
+
// the dips are the same on every sheet.
|
|
2063
|
+
float wrinkle = uWrinkleSide * (mix(noise, 1.0 - noise, uFlipProgress) - 0.5) * smoothstep(0.0, 0.35, x) * WRINKLE;
|
|
2064
|
+
wrinkle *= NESTED && wrinkle < 0.0 ? 1.0 : uStackLift;
|
|
1921
2065
|
float lift = sheetRestingLift(x) * BULGE * uStackLift;
|
|
1922
2066
|
|
|
1923
2067
|
// bend with constant curvature past the fold line, trailing against the turn
|
|
@@ -1935,7 +2079,7 @@ var vertexChunk2 = (settings) => (
|
|
|
1935
2079
|
// turn about the spine
|
|
1936
2080
|
p = vec3(p.x * uFlipRotation.x - p.z * uFlipRotation.y, p.y, p.x * uFlipRotation.y + p.z * uFlipRotation.x);
|
|
1937
2081
|
|
|
1938
|
-
p.z += lift +
|
|
2082
|
+
p.z += lift + wrinkle + uStackGap;
|
|
1939
2083
|
return p;
|
|
1940
2084
|
}
|
|
1941
2085
|
`
|
|
@@ -1968,20 +2112,29 @@ function wrinkleNoise(u, v, aspect) {
|
|
|
1968
2112
|
}
|
|
1969
2113
|
return value;
|
|
1970
2114
|
}
|
|
2115
|
+
var noiseByAspect = /* @__PURE__ */ new Map();
|
|
1971
2116
|
function createSpreadGeometry(aspect) {
|
|
1972
2117
|
const geometry = new THREE11.PlaneGeometry(1, aspect, 64, Math.round(64 * aspect));
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
2118
|
+
let noise = noiseByAspect.get(aspect);
|
|
2119
|
+
if (!noise) {
|
|
2120
|
+
const uv = geometry.attributes.uv;
|
|
2121
|
+
noise = new Float32Array(uv.count * 3);
|
|
2122
|
+
for (let i = 0; i < uv.count; i++) {
|
|
2123
|
+
const u = uv.getX(i);
|
|
2124
|
+
const v = uv.getY(i);
|
|
2125
|
+
noise[i * 3] = wrinkleNoise(u, v, aspect);
|
|
2126
|
+
noise[i * 3 + 1] = wrinkleNoise(u + NORMAL_EPSILON2, v, aspect);
|
|
2127
|
+
noise[i * 3 + 2] = wrinkleNoise(u, v + NORMAL_EPSILON2 / aspect, aspect);
|
|
2128
|
+
}
|
|
2129
|
+
noiseByAspect.set(aspect, noise);
|
|
1981
2130
|
}
|
|
1982
2131
|
geometry.setAttribute("aNoise", new THREE11.BufferAttribute(noise, 3));
|
|
1983
2132
|
return geometry;
|
|
1984
2133
|
}
|
|
2134
|
+
function sharedSpreadGeometry(shared, aspect) {
|
|
2135
|
+
const key = `spread-geometry:${aspect}`;
|
|
2136
|
+
return { geometry: shared.acquire(key, () => createSpreadGeometry(aspect)), release: () => shared.release(key) };
|
|
2137
|
+
}
|
|
1985
2138
|
function createSpreadSheet(geometry, front, back, pattern, settings, shading) {
|
|
1986
2139
|
const uniforms = {
|
|
1987
2140
|
uFlipProgress: { value: 0 },
|
|
@@ -1992,11 +2145,13 @@ function createSpreadSheet(geometry, front, back, pattern, settings, shading) {
|
|
|
1992
2145
|
uFlipRotation: { value: new THREE11.Vector2(1, 0) },
|
|
1993
2146
|
uDirection: { value: 1 },
|
|
1994
2147
|
uStackLift: { value: 1 },
|
|
2148
|
+
uStackGap: { value: 0 },
|
|
1995
2149
|
uFront: { value: front },
|
|
1996
2150
|
uBack: { value: back },
|
|
1997
2151
|
uPattern: { value: pattern },
|
|
1998
2152
|
uSpineContact: shading.spineContact,
|
|
1999
|
-
uLightDirection: shading.lightDirection
|
|
2153
|
+
uLightDirection: shading.lightDirection,
|
|
2154
|
+
uSheetOrigin: shading.origin
|
|
2000
2155
|
};
|
|
2001
2156
|
const mesh = createSheetMesh(
|
|
2002
2157
|
geometry,
|
|
@@ -2037,6 +2192,10 @@ function stackLift(index, count, progress) {
|
|
|
2037
2192
|
if (count <= 1) return 1;
|
|
2038
2193
|
return 0.31 + 0.69 * (index + (count - 1 - 2 * index) * (1 - progress)) / (count - 1);
|
|
2039
2194
|
}
|
|
2195
|
+
function sheetsUnder(index, count, progress) {
|
|
2196
|
+
const t = clamp2((progress - 0.25) / 0.5, 0, 1);
|
|
2197
|
+
return count - 1 - index + (2 * index - count + 1) * t * t * (3 - 2 * t);
|
|
2198
|
+
}
|
|
2040
2199
|
var SpreadEngine = class {
|
|
2041
2200
|
group = new THREE12.Group();
|
|
2042
2201
|
maxPosition;
|
|
@@ -2046,6 +2205,7 @@ var SpreadEngine = class {
|
|
|
2046
2205
|
metrics;
|
|
2047
2206
|
requestFrame;
|
|
2048
2207
|
geometry;
|
|
2208
|
+
releaseGeometry;
|
|
2049
2209
|
sheets;
|
|
2050
2210
|
abort = new AbortController();
|
|
2051
2211
|
shading;
|
|
@@ -2073,7 +2233,9 @@ var SpreadEngine = class {
|
|
|
2073
2233
|
const count = Math.ceil(ctx.textures.length / 2);
|
|
2074
2234
|
this.maxPosition = count;
|
|
2075
2235
|
this.current = clamp2(Math.round(ctx.position), 0, count);
|
|
2076
|
-
|
|
2236
|
+
const { geometry, release } = sharedSpreadGeometry(ctx.shared, ctx.settings.pageAspect);
|
|
2237
|
+
this.geometry = geometry;
|
|
2238
|
+
this.releaseGeometry = release;
|
|
2077
2239
|
this.sheets = [];
|
|
2078
2240
|
for (let i = 0; i < count; i++) {
|
|
2079
2241
|
const front = ctx.textures[2 * i];
|
|
@@ -2133,11 +2295,16 @@ var SpreadEngine = class {
|
|
|
2133
2295
|
if (this.press) this.release(new PointerEvent("pointercancel", { pointerId: this.press.id }));
|
|
2134
2296
|
this.wake();
|
|
2135
2297
|
}
|
|
2298
|
+
setShadows(on) {
|
|
2299
|
+
this.settings.lighting.shadows = on;
|
|
2300
|
+
for (const sheet of this.sheets) sheet.mesh.receiveShadow = on;
|
|
2301
|
+
this.wake();
|
|
2302
|
+
}
|
|
2136
2303
|
dispose() {
|
|
2137
2304
|
this.cancelHold();
|
|
2138
2305
|
this.abort.abort();
|
|
2139
2306
|
for (const sheet of this.sheets) disposeSheetMesh(sheet.mesh);
|
|
2140
|
-
this.
|
|
2307
|
+
this.releaseGeometry();
|
|
2141
2308
|
}
|
|
2142
2309
|
// --- helpers ----------------------------------------------------------------
|
|
2143
2310
|
randomWobble() {
|
|
@@ -2495,7 +2662,7 @@ var SpreadEngine = class {
|
|
|
2495
2662
|
const depth = i >= this.current ? i - this.current : this.current - 1 - i;
|
|
2496
2663
|
const turning = this.inFlight(i) || this.drag?.index === i;
|
|
2497
2664
|
sheet.mesh.castShadow = this.settings.lighting.shadows && (depth < 3 || turning);
|
|
2498
|
-
layerSheet(sheet.mesh, depth, this.sheets.length, turning);
|
|
2665
|
+
layerSheet(sheet.mesh, depth, this.sheets.length, turning, this.settings.paper.depthBias);
|
|
2499
2666
|
const lift = Math.abs(sheet.uniforms.uFlipRotation.value.y);
|
|
2500
2667
|
if (turning && lift > upright) {
|
|
2501
2668
|
upright = lift;
|
|
@@ -2526,6 +2693,7 @@ var SpreadEngine = class {
|
|
|
2526
2693
|
u.uWrinkleSide.value = -Math.cos(turn);
|
|
2527
2694
|
u.uDirection.value = sheet.directionSmooth;
|
|
2528
2695
|
u.uStackLift.value = sheet.liftBase + sheet.liftSpan * sheet.progress;
|
|
2696
|
+
u.uStackGap.value = this.settings.paper.sheetGap * sheetsUnder(sheet.index, this.sheets.length, sheet.progress);
|
|
2529
2697
|
u.uBendAngle.value = bend;
|
|
2530
2698
|
u.uFold.value.set(cos, sin);
|
|
2531
2699
|
u.uCurl.value.set(curlStart, curlLength);
|
|
@@ -2806,7 +2974,8 @@ var LeafThrough = class extends EventTarget {
|
|
|
2806
2974
|
scene.add(sun, sun.target);
|
|
2807
2975
|
const shading = {
|
|
2808
2976
|
spineContact: { value: new THREE13.Vector3(1, 0, 0) },
|
|
2809
|
-
lightDirection: { value: sun.position.clone().sub(sun.target.position).normalize() }
|
|
2977
|
+
lightDirection: { value: sun.position.clone().sub(sun.target.position).normalize() },
|
|
2978
|
+
origin: { value: new THREE13.Vector3() }
|
|
2810
2979
|
};
|
|
2811
2980
|
let floor2 = null;
|
|
2812
2981
|
if (layout === "spread" && shadows && settings.lighting.floorShadow > 0) {
|
|
@@ -2828,6 +2997,7 @@ var LeafThrough = class extends EventTarget {
|
|
|
2828
2997
|
textures,
|
|
2829
2998
|
blank: layout === "single" ? this.paper.back(settings.paper.backColor) : blank,
|
|
2830
2999
|
pattern: this.paper.grain(settings, renderer),
|
|
3000
|
+
shared: sharedResources(renderer),
|
|
2831
3001
|
position: this.pageToPosition(page, layout),
|
|
2832
3002
|
metrics: this.metrics,
|
|
2833
3003
|
shading,
|
|
@@ -2880,18 +3050,18 @@ var LeafThrough = class extends EventTarget {
|
|
|
2880
3050
|
const right = Math.min(placed.view.x + placed.view.width, (documentWidth - pageLeft) / scaleX);
|
|
2881
3051
|
const top = Math.max(placed.view.y, -pageTop / scaleY);
|
|
2882
3052
|
const bottom = placed.view.y + placed.view.height;
|
|
2883
|
-
const
|
|
3053
|
+
const canvas2 = { x: left, y: top, width: Math.max(1, right - left), height: Math.max(1, bottom - top) };
|
|
2884
3054
|
const px = (n) => `${Math.round(n * 100) / 100}px`;
|
|
2885
3055
|
Object.assign(this.canvas.style, {
|
|
2886
|
-
left: px(
|
|
2887
|
-
top: px(
|
|
2888
|
-
width: px(
|
|
2889
|
-
height: px(
|
|
3056
|
+
left: px(canvas2.x),
|
|
3057
|
+
top: px(canvas2.y),
|
|
3058
|
+
width: px(canvas2.width),
|
|
3059
|
+
height: px(canvas2.height)
|
|
2890
3060
|
});
|
|
2891
3061
|
const maxRatio = Math.min(devicePixelRatio, settings.maxPixelRatio);
|
|
2892
|
-
const budget = Math.sqrt(15e6 / Math.max(1,
|
|
3062
|
+
const budget = Math.sqrt(15e6 / Math.max(1, canvas2.width * canvas2.height));
|
|
2893
3063
|
this.renderer.setPixelRatio(Math.min(maxRatio, budget));
|
|
2894
|
-
this.renderer.setSize(Math.max(1, Math.round(
|
|
3064
|
+
this.renderer.setSize(Math.max(1, Math.round(canvas2.width)), Math.max(1, Math.round(canvas2.height)), false);
|
|
2895
3065
|
const { eye, view, distance } = framing;
|
|
2896
3066
|
const halfWidth = Math.max(eye.x - view.x, view.x + view.width - eye.x);
|
|
2897
3067
|
const halfHeight = Math.max(eye.y - view.y, view.y + view.height - eye.y);
|
|
@@ -2903,10 +3073,10 @@ var LeafThrough = class extends EventTarget {
|
|
|
2903
3073
|
camera.setViewOffset(
|
|
2904
3074
|
2 * halfWidth * scale,
|
|
2905
3075
|
2 * halfHeight * scale,
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
3076
|
+
canvas2.x - frustumLeft,
|
|
3077
|
+
canvas2.y - frustumTop,
|
|
3078
|
+
canvas2.width,
|
|
3079
|
+
canvas2.height
|
|
2910
3080
|
);
|
|
2911
3081
|
camera.updateProjectionMatrix();
|
|
2912
3082
|
}
|
|
@@ -3074,10 +3244,10 @@ var LeafThrough = class extends EventTarget {
|
|
|
3074
3244
|
this.syncContent(view);
|
|
3075
3245
|
}
|
|
3076
3246
|
};
|
|
3077
|
-
function createRenderer(
|
|
3247
|
+
function createRenderer(canvas2) {
|
|
3078
3248
|
let renderer;
|
|
3079
3249
|
try {
|
|
3080
|
-
renderer = new THREE13.WebGLRenderer({ canvas, antialias: true, alpha: true });
|
|
3250
|
+
renderer = new THREE13.WebGLRenderer({ canvas: canvas2, antialias: true, alpha: true });
|
|
3081
3251
|
} catch {
|
|
3082
3252
|
return null;
|
|
3083
3253
|
}
|
|
@@ -3097,6 +3267,7 @@ export {
|
|
|
3097
3267
|
LIVE_OPTIONS,
|
|
3098
3268
|
preloadRadius,
|
|
3099
3269
|
snapshot,
|
|
3270
|
+
deepEqual,
|
|
3100
3271
|
changedOptions,
|
|
3101
3272
|
sourceKey,
|
|
3102
3273
|
floorPoint,
|
|
@@ -3109,9 +3280,10 @@ export {
|
|
|
3109
3280
|
Riffle,
|
|
3110
3281
|
bindKeyboard,
|
|
3111
3282
|
PageLoader,
|
|
3283
|
+
sharedResources,
|
|
3112
3284
|
PaperTextures,
|
|
3113
3285
|
SingleEngine,
|
|
3114
3286
|
SpreadEngine,
|
|
3115
3287
|
LeafThrough
|
|
3116
3288
|
};
|
|
3117
|
-
//# sourceMappingURL=chunk-
|
|
3289
|
+
//# sourceMappingURL=chunk-KCIOFDSW.js.map
|