@expofp/renderer 2.2.1 → 2.3.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/dist/index.d.ts +10 -0
- package/dist/index.js +161 -70
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -691,6 +691,16 @@ export declare interface ViewportAPI {
|
|
|
691
691
|
* @param dynamicTransformMatrix dynamic transform matrix (changes every frame)
|
|
692
692
|
*/
|
|
693
693
|
setDynamicTransform: (dynamicTransformMatrix: number[]) => void;
|
|
694
|
+
/**
|
|
695
|
+
* Set the maximum zoom factor. Default is 35.
|
|
696
|
+
* @param maxZoom Maximum zoom factor
|
|
697
|
+
*/
|
|
698
|
+
setMaxZoom: (maxZoom: number) => void;
|
|
699
|
+
/**
|
|
700
|
+
* Set the minimum zoom factor. Default is 0.1.
|
|
701
|
+
* @param minZoom Minimum zoom factor
|
|
702
|
+
*/
|
|
703
|
+
setMinZoom: (minZoom: number) => void;
|
|
694
704
|
}
|
|
695
705
|
|
|
696
706
|
/** Options for the {@link ControlsAPI.zoomTo} method. */
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ var __defProp = Object.defineProperty;
|
|
|
2
2
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
4
|
var _a;
|
|
5
|
-
import { DataTexture, FloatType, UnsignedIntType, IntType, RGBAFormat, RGBAIntegerFormat, RGFormat, RGIntegerFormat, RedFormat, RedIntegerFormat, BatchedMesh as BatchedMesh$1, BufferAttribute, StreamDrawUsage, Color, Matrix4, Vector3, Vector4, AlwaysDepth, DoubleSide, MeshBasicMaterial, Texture, Group, PlaneGeometry, SRGBColorSpace, Vector2, Quaternion, BufferGeometry, Mesh, LessEqualDepth, LinearSRGBColorSpace, Plane, Raycaster,
|
|
5
|
+
import { DataTexture, FloatType, UnsignedIntType, IntType, RGBAFormat, RGBAIntegerFormat, RGFormat, RGIntegerFormat, RedFormat, RedIntegerFormat, BatchedMesh as BatchedMesh$1, BufferAttribute, StreamDrawUsage, Color, Matrix4, Vector3, Frustum, Sphere, Box3, Vector4, AlwaysDepth, DoubleSide, MeshBasicMaterial, Texture, Group, PlaneGeometry, SRGBColorSpace, Vector2, Quaternion, BufferGeometry, Mesh, LessEqualDepth, LinearSRGBColorSpace, Plane, Raycaster, Spherical, PerspectiveCamera, Camera, Scene, MathUtils, Clock, WebGLRenderer } from "three";
|
|
6
6
|
import { traverseAncestorsGenerator } from "three/examples/jsm/utils/SceneUtils.js";
|
|
7
7
|
import createLog from "debug";
|
|
8
8
|
import { BatchedText as BatchedText$1, Text as Text$1 } from "troika-three-text";
|
|
@@ -551,9 +551,12 @@ class BatchedText extends BatchedText$1 {
|
|
|
551
551
|
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
552
552
|
constructor() {
|
|
553
553
|
super();
|
|
554
|
-
__publicField(this, "mapInstanceIdToText", /* @__PURE__ */ new Map());
|
|
555
554
|
__publicField(this, "textArray", []);
|
|
556
555
|
__publicField(this, "textureNeedsUpdate", false);
|
|
556
|
+
__publicField(this, "boundsNeedsUpdate", false);
|
|
557
|
+
this.addEventListener("synccomplete", () => {
|
|
558
|
+
this.boundsNeedsUpdate = true;
|
|
559
|
+
});
|
|
557
560
|
}
|
|
558
561
|
/** Number of texts in the batch */
|
|
559
562
|
get size() {
|
|
@@ -569,7 +572,13 @@ class BatchedText extends BatchedText$1 {
|
|
|
569
572
|
* @returns Text object
|
|
570
573
|
*/
|
|
571
574
|
getText(instanceId) {
|
|
572
|
-
return this.
|
|
575
|
+
return this.textArray[instanceId];
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* Mark this BatchedText as needing bounds update. This should be called when changing text transforms.
|
|
579
|
+
*/
|
|
580
|
+
invalidateBounds() {
|
|
581
|
+
this.boundsNeedsUpdate = true;
|
|
573
582
|
}
|
|
574
583
|
/**
|
|
575
584
|
* Set the visibility of the {@link Text} object by instance id.
|
|
@@ -583,17 +592,39 @@ class BatchedText extends BatchedText$1 {
|
|
|
583
592
|
}
|
|
584
593
|
addText(text, instanceId) {
|
|
585
594
|
super.addText(text);
|
|
586
|
-
if (instanceId !== void 0)
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
595
|
+
if (instanceId !== void 0) this.textArray[instanceId] = text;
|
|
596
|
+
this.boundsNeedsUpdate = true;
|
|
597
|
+
}
|
|
598
|
+
removeText(text) {
|
|
599
|
+
super.removeText(text);
|
|
600
|
+
this.textArray.splice(this.textArray.indexOf(text), 1);
|
|
601
|
+
this.boundsNeedsUpdate = true;
|
|
590
602
|
}
|
|
591
603
|
dispose() {
|
|
592
604
|
super.dispose();
|
|
605
|
+
this.textArray.length = 0;
|
|
593
606
|
this.dispatchEvent({ type: "dispose" });
|
|
594
607
|
}
|
|
595
|
-
|
|
596
|
-
|
|
608
|
+
updateBounds() {
|
|
609
|
+
if (this.boundsNeedsUpdate) {
|
|
610
|
+
const bbox = this.geometry.boundingBox.makeEmpty();
|
|
611
|
+
for (const text of this.textArray) {
|
|
612
|
+
if (!text.visible) continue;
|
|
613
|
+
if (text.matrixAutoUpdate) text.updateMatrix();
|
|
614
|
+
_box$1.copy(text.geometry.boundingBox).applyMatrix4(text.matrix);
|
|
615
|
+
bbox.union(_box$1);
|
|
616
|
+
}
|
|
617
|
+
bbox.getBoundingSphere(this.geometry.boundingSphere);
|
|
618
|
+
this.boundsNeedsUpdate = false;
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
onBeforeRender(renderer, scene, camera, geometry, material) {
|
|
622
|
+
this.sync();
|
|
623
|
+
if ("isTroikaTextMaterial" in material && material.isTroikaTextMaterial) {
|
|
624
|
+
this.prepareForRender(material, scene, camera);
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
prepareForRender(material, scene, camera) {
|
|
597
628
|
var _a2;
|
|
598
629
|
const isOutline = material.isTextOutlineMaterial;
|
|
599
630
|
material.uniforms.uTroikaIsOutline.value = isOutline;
|
|
@@ -612,12 +643,15 @@ class BatchedText extends BatchedText$1 {
|
|
|
612
643
|
}
|
|
613
644
|
const texData = texture.image.data;
|
|
614
645
|
this.textureNeedsUpdate = false;
|
|
646
|
+
_matrix$1.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse).multiply(scene.matrixWorld);
|
|
647
|
+
_frustum$1.setFromProjectionMatrix(_matrix$1, camera.coordinateSystem);
|
|
615
648
|
for (const text of this.textArray) {
|
|
616
649
|
const index = ((_a2 = this._members.get(text)) == null ? void 0 : _a2.index) ?? -1;
|
|
617
650
|
const textRenderInfo = text.textRenderInfo;
|
|
618
651
|
if (index < 0 || !textRenderInfo) continue;
|
|
619
652
|
const startIndex = index * floatsPerMember;
|
|
620
|
-
|
|
653
|
+
const isHidden = !text.visible || !_frustum$1.intersectsSphere(_sphere$1.copy(text.geometry.boundingSphere).applyMatrix4(text.matrix));
|
|
654
|
+
if (isHidden) {
|
|
621
655
|
for (let i = 0; i < 16; i++) {
|
|
622
656
|
this.setTexData(startIndex + i, 0, texData);
|
|
623
657
|
}
|
|
@@ -732,7 +766,6 @@ class Text extends Text$1 {
|
|
|
732
766
|
blockBounds[3] + pad
|
|
733
767
|
);
|
|
734
768
|
}
|
|
735
|
-
this.geometry.applyClipRect(uniforms.uTroikaClipRect.value);
|
|
736
769
|
}
|
|
737
770
|
uniforms.uTroikaSDFDebug.value = !!this.debugSDF;
|
|
738
771
|
material.polygonOffset = !!this.depthOffset;
|
|
@@ -764,6 +797,10 @@ class Text extends Text$1 {
|
|
|
764
797
|
}
|
|
765
798
|
}
|
|
766
799
|
}
|
|
800
|
+
const _matrix$1 = new Matrix4();
|
|
801
|
+
const _frustum$1 = new Frustum();
|
|
802
|
+
const _sphere$1 = new Sphere();
|
|
803
|
+
const _box$1 = new Box3();
|
|
767
804
|
function setDimming(root, dim) {
|
|
768
805
|
root.userData["uDim"] = dim === void 0 ? void 0 : +dim;
|
|
769
806
|
}
|
|
@@ -2001,19 +2038,30 @@ class TextSystem extends RenderableSystem {
|
|
|
2001
2038
|
group.add(newBatchedText);
|
|
2002
2039
|
}
|
|
2003
2040
|
updateDefImpl(textDef, mesh, instanceIds) {
|
|
2004
|
-
|
|
2041
|
+
const lines = [];
|
|
2042
|
+
for (let i = 0; i < textDef.lines.length; i++) {
|
|
2043
|
+
const line = textDef.lines[i];
|
|
2005
2044
|
const text = mesh.getText(instanceIds[i]);
|
|
2006
|
-
if (
|
|
2007
|
-
text.
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2045
|
+
if (line.fontSize === 0) {
|
|
2046
|
+
text.visible = false;
|
|
2047
|
+
continue;
|
|
2048
|
+
}
|
|
2049
|
+
text.visible = true;
|
|
2050
|
+
text.text = line.text;
|
|
2051
|
+
text.color = this.textColor.set(line.color).getHex(LinearSRGBColorSpace);
|
|
2052
|
+
text.font = line.fontUrl;
|
|
2053
|
+
if (line.stroke) {
|
|
2054
|
+
text.outlineColor = line.stroke.color;
|
|
2055
|
+
text.outlineWidth = line.fontSize == 0 ? 0 : line.stroke.width / line.fontSize;
|
|
2014
2056
|
}
|
|
2057
|
+
const fontSize = line.fontSize;
|
|
2058
|
+
const height = line.text.split("\n").length * text.lineHeight * fontSize;
|
|
2059
|
+
lines.push({ text, fontSize, height });
|
|
2060
|
+
}
|
|
2061
|
+
if (lines.length > 0) {
|
|
2062
|
+
if (textDef.alignment.vertical === "bottom") lines.reverse();
|
|
2063
|
+
this.updateScale(textDef, mesh, lines);
|
|
2015
2064
|
}
|
|
2016
|
-
this.updateScale(textDef);
|
|
2017
2065
|
}
|
|
2018
2066
|
buildBatchedText(layer) {
|
|
2019
2067
|
const textDefs = layer.children;
|
|
@@ -2028,6 +2076,7 @@ class TextSystem extends RenderableSystem {
|
|
|
2028
2076
|
text.fontSize = 1;
|
|
2029
2077
|
text.lineHeight = 1.1;
|
|
2030
2078
|
text.whiteSpace = "nowrap";
|
|
2079
|
+
text.clipRect = [0, 0, 0, 0];
|
|
2031
2080
|
batchedText.addText(text, instanceId);
|
|
2032
2081
|
instanceIds.push(instanceId);
|
|
2033
2082
|
instanceId++;
|
|
@@ -2047,9 +2096,8 @@ class TextSystem extends RenderableSystem {
|
|
|
2047
2096
|
return batchedText;
|
|
2048
2097
|
}
|
|
2049
2098
|
// TODO: Simplify
|
|
2050
|
-
updateScale(textDef) {
|
|
2099
|
+
updateScale(textDef, mesh, lines) {
|
|
2051
2100
|
const dpr = this.renderer.context.getPixelRatio();
|
|
2052
|
-
const lines = this.getTextLines(textDef);
|
|
2053
2101
|
this.calculateStartInBoundsPosition(
|
|
2054
2102
|
textDef,
|
|
2055
2103
|
lines,
|
|
@@ -2057,41 +2105,18 @@ class TextSystem extends RenderableSystem {
|
|
|
2057
2105
|
this.alignmentOffset,
|
|
2058
2106
|
this.localPosition
|
|
2059
2107
|
);
|
|
2060
|
-
for (const { text, fontSize, height
|
|
2061
|
-
|
|
2062
|
-
text.visible = false;
|
|
2063
|
-
continue;
|
|
2064
|
-
}
|
|
2065
|
-
text.visible = true;
|
|
2066
|
-
setAnchorsAndAlignment(text, alignment);
|
|
2108
|
+
for (const { text, fontSize, height } of lines) {
|
|
2109
|
+
setAnchorsAndAlignment(text, textDef.alignment);
|
|
2067
2110
|
this.worldPosition.copy(this.localPosition).rotateAround({ x: 0, y: 0 }, textDef.bounds.rotation).add(textDef.bounds.center);
|
|
2068
2111
|
this.textScale.copy(this.initialTextScale).multiplyScalar(fontSize * dpr);
|
|
2069
2112
|
text.scale.set(this.textScale.x, this.textScale.y, 1);
|
|
2070
2113
|
text.position.set(this.worldPosition.x, this.worldPosition.y, 0);
|
|
2071
2114
|
text.rotation.set(0, 0, textDef.bounds.rotation);
|
|
2072
|
-
text.
|
|
2073
|
-
textDef,
|
|
2074
|
-
this.localPosition,
|
|
2075
|
-
this.textScale,
|
|
2076
|
-
this.localToMin,
|
|
2077
|
-
this.localToMax
|
|
2078
|
-
);
|
|
2115
|
+
this.calculateClipRect(text, textDef, this.localPosition, this.textScale, this.localToMin, this.localToMax);
|
|
2079
2116
|
this.localPosition.y += height * dpr;
|
|
2117
|
+
mesh.invalidateBounds();
|
|
2080
2118
|
}
|
|
2081
2119
|
}
|
|
2082
|
-
getTextLines(textDef) {
|
|
2083
|
-
const { object: mesh, instanceIds } = this.getObjectInstanceByDef(textDef);
|
|
2084
|
-
const alignment = textDef.alignment;
|
|
2085
|
-
const lines = instanceIds.map((instanceId, i) => {
|
|
2086
|
-
const text = mesh.getText(instanceId);
|
|
2087
|
-
const line = textDef.lines[i];
|
|
2088
|
-
const fontSize = line.fontSize;
|
|
2089
|
-
const height = fontSize ? text.text.split("\n").length * text.lineHeight * fontSize : 0;
|
|
2090
|
-
return { text, fontSize, height, alignment };
|
|
2091
|
-
});
|
|
2092
|
-
if (alignment.vertical === "bottom") lines.reverse();
|
|
2093
|
-
return lines;
|
|
2094
|
-
}
|
|
2095
2120
|
calculateStartInBoundsPosition(textDef, lines, alignmentDirection, alignmentOffset, inBoundsPosition) {
|
|
2096
2121
|
const padding = textDef.padding;
|
|
2097
2122
|
const alignment = textDef.alignment;
|
|
@@ -2106,10 +2131,13 @@ class TextSystem extends RenderableSystem {
|
|
|
2106
2131
|
}
|
|
2107
2132
|
inBoundsPosition.multiply(alignmentDirection);
|
|
2108
2133
|
}
|
|
2109
|
-
calculateClipRect(textDef, inBoundsPosition, textScale, toMin, toMax) {
|
|
2134
|
+
calculateClipRect(text, textDef, inBoundsPosition, textScale, toMin, toMax) {
|
|
2110
2135
|
toMin.subVectors(textDef.bounds.min, textDef.bounds.center).multiply(this.initialTextScale).sub(inBoundsPosition).divide(textScale);
|
|
2111
2136
|
toMax.subVectors(textDef.bounds.max, textDef.bounds.center).multiply(this.initialTextScale).sub(inBoundsPosition).divide(textScale);
|
|
2112
|
-
|
|
2137
|
+
text.clipRect[0] = toMin.x;
|
|
2138
|
+
text.clipRect[1] = toMin.y;
|
|
2139
|
+
text.clipRect[2] = toMax.x;
|
|
2140
|
+
text.clipRect[3] = toMax.y;
|
|
2113
2141
|
}
|
|
2114
2142
|
}
|
|
2115
2143
|
function getAlignmentDirection(alignment) {
|
|
@@ -2147,7 +2175,8 @@ class LayerSystem {
|
|
|
2147
2175
|
__publicField(this, "mapLayerDefToParent", /* @__PURE__ */ new Map());
|
|
2148
2176
|
__publicField(this, "layerDefRenderOrder", []);
|
|
2149
2177
|
__publicField(this, "pendingDefs", /* @__PURE__ */ new Set());
|
|
2150
|
-
__publicField(this, "
|
|
2178
|
+
__publicField(this, "culledDefs", /* @__PURE__ */ new Set());
|
|
2179
|
+
__publicField(this, "useUpdateBuffering", true);
|
|
2151
2180
|
this.renderer = renderer;
|
|
2152
2181
|
this.materialSystem = new MaterialSystem();
|
|
2153
2182
|
this.meshSystem = new MeshSystem(this.materialSystem, this.renderer);
|
|
@@ -2181,30 +2210,57 @@ class LayerSystem {
|
|
|
2181
2210
|
*/
|
|
2182
2211
|
updateDefs(defs) {
|
|
2183
2212
|
for (const def of defs) {
|
|
2184
|
-
if (this.useUpdateBuffering)
|
|
2185
|
-
|
|
2213
|
+
if (this.useUpdateBuffering) {
|
|
2214
|
+
this.pendingDefs.add(def);
|
|
2215
|
+
this.culledDefs.delete(def);
|
|
2216
|
+
} else this.updateDef(def);
|
|
2186
2217
|
}
|
|
2187
2218
|
}
|
|
2188
2219
|
/**
|
|
2189
2220
|
* Drain the queued updates within a time budget.
|
|
2190
2221
|
* Returns true if any def was updated during this call.
|
|
2222
|
+
* @param scene {@link Scene} instance to get the world matrix from
|
|
2223
|
+
* @param camera {@link Camera} instance to do frustum culling against
|
|
2191
2224
|
* @param timeBudgetMs frame time budget to perform updates in milliseconds
|
|
2192
2225
|
* @returns true if any def was updated during this call
|
|
2193
2226
|
*/
|
|
2194
|
-
processPendingUpdates(timeBudgetMs =
|
|
2227
|
+
processPendingUpdates(scene, camera, timeBudgetMs = -1) {
|
|
2195
2228
|
if (!this.useUpdateBuffering) return false;
|
|
2196
|
-
if (this.pendingDefs.size === 0) return false;
|
|
2229
|
+
if (this.pendingDefs.size === 0 && this.culledDefs.size === 0) return false;
|
|
2197
2230
|
const startTime = performance.now();
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2231
|
+
_matrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse).multiply(scene.matrixWorld);
|
|
2232
|
+
_frustum.setFromProjectionMatrix(_matrix, camera.coordinateSystem);
|
|
2233
|
+
let processedCount = 0;
|
|
2234
|
+
const overBudget = () => timeBudgetMs > 0 && performance.now() - startTime >= timeBudgetMs;
|
|
2235
|
+
for (const def of this.pendingDefs) {
|
|
2236
|
+
if (overBudget()) break;
|
|
2237
|
+
let culled = false;
|
|
2201
2238
|
this.pendingDefs.delete(def);
|
|
2239
|
+
if (isTextDef(def) || isImageDef(def)) {
|
|
2240
|
+
const bounds = def.bounds;
|
|
2241
|
+
_box.min.set(bounds.min.x, bounds.min.y, 0);
|
|
2242
|
+
_box.max.set(bounds.max.x, bounds.max.y, 0);
|
|
2243
|
+
culled = !_frustum.intersectsBox(_box);
|
|
2244
|
+
}
|
|
2245
|
+
if (culled) this.culledDefs.add(def);
|
|
2246
|
+
else {
|
|
2247
|
+
this.updateDef(def);
|
|
2248
|
+
processedCount++;
|
|
2249
|
+
}
|
|
2250
|
+
}
|
|
2251
|
+
for (const def of this.culledDefs) {
|
|
2252
|
+
if (overBudget()) break;
|
|
2253
|
+
this.culledDefs.delete(def);
|
|
2202
2254
|
this.updateDef(def);
|
|
2203
|
-
|
|
2255
|
+
processedCount++;
|
|
2204
2256
|
}
|
|
2205
2257
|
const took = (performance.now() - startTime).toFixed(2);
|
|
2206
|
-
if (
|
|
2207
|
-
|
|
2258
|
+
if (processedCount > 0) {
|
|
2259
|
+
const culled = this.culledDefs.size;
|
|
2260
|
+
const remaining = this.pendingDefs.size;
|
|
2261
|
+
logger$5.debug(`processed ${processedCount} defs (${culled} culled, ${remaining} remaining) in ${took}ms`);
|
|
2262
|
+
}
|
|
2263
|
+
return processedCount > 0;
|
|
2208
2264
|
}
|
|
2209
2265
|
/**
|
|
2210
2266
|
* Build the scene graph from the given scene definition.
|
|
@@ -2337,6 +2393,9 @@ class LayerSystem {
|
|
|
2337
2393
|
return fullName;
|
|
2338
2394
|
}
|
|
2339
2395
|
}
|
|
2396
|
+
const _matrix = new Matrix4();
|
|
2397
|
+
const _frustum = new Frustum();
|
|
2398
|
+
const _box = new Box3();
|
|
2340
2399
|
/*!
|
|
2341
2400
|
* camera-controls
|
|
2342
2401
|
* https://github.com/yomotsu/camera-controls
|
|
@@ -4947,6 +5006,17 @@ class CameraSystem {
|
|
|
4947
5006
|
if (zoomFactor <= 0) return this.zoomIdentityDistance;
|
|
4948
5007
|
return this.zoomIdentityDistance / zoomFactor;
|
|
4949
5008
|
}
|
|
5009
|
+
/**
|
|
5010
|
+
* Set the zoom factor bounds.
|
|
5011
|
+
* @param minZoom Minimum zoom factor. Default is 0.1.
|
|
5012
|
+
* @param maxZoom Maximum zoom factor. Default is 35.
|
|
5013
|
+
*/
|
|
5014
|
+
setZoomBounds(minZoom, maxZoom) {
|
|
5015
|
+
if (!this.zoomBounds) return;
|
|
5016
|
+
if (minZoom) this.zoomBounds[0] = minZoom;
|
|
5017
|
+
if (maxZoom) this.zoomBounds[1] = maxZoom;
|
|
5018
|
+
this.updateCamera();
|
|
5019
|
+
}
|
|
4950
5020
|
/**
|
|
4951
5021
|
* Initializes the camera with the given zoom bounds.
|
|
4952
5022
|
* @param zoomBounds [minZoom, maxZoom]
|
|
@@ -5292,7 +5362,7 @@ class ViewportSystem {
|
|
|
5292
5362
|
*/
|
|
5293
5363
|
initViewport(sceneDef) {
|
|
5294
5364
|
if (!this.renderer.isExternalMode) this.sceneSystem.initScene(sceneDef.viewbox);
|
|
5295
|
-
this.cameraSystem.initCamera([0.1, sceneDef.viewbox.size.x >
|
|
5365
|
+
this.cameraSystem.initCamera([0.1, sceneDef.viewbox.size.x > 1e4 ? 100 : 35]);
|
|
5296
5366
|
}
|
|
5297
5367
|
/** Updates the viewport when the renderer size changes. */
|
|
5298
5368
|
updateViewport() {
|
|
@@ -5397,12 +5467,28 @@ class ViewportSystem {
|
|
|
5397
5467
|
zoomFactorToDistance(zoomFactor) {
|
|
5398
5468
|
return this.cameraSystem.zoomFactorToDistance(zoomFactor);
|
|
5399
5469
|
}
|
|
5470
|
+
/**
|
|
5471
|
+
* Set the maximum zoom factor. Default is 35.
|
|
5472
|
+
* @param maxZoom Maximum zoom factor
|
|
5473
|
+
*/
|
|
5474
|
+
setMaxZoom(maxZoom) {
|
|
5475
|
+
this.cameraSystem.setZoomBounds(void 0, maxZoom);
|
|
5476
|
+
}
|
|
5477
|
+
/**
|
|
5478
|
+
* Set the minimum zoom factor. Default is 0.1.
|
|
5479
|
+
* @param minZoom Minimum zoom factor
|
|
5480
|
+
*/
|
|
5481
|
+
setMinZoom(minZoom) {
|
|
5482
|
+
this.cameraSystem.setZoomBounds(minZoom, void 0);
|
|
5483
|
+
}
|
|
5400
5484
|
}
|
|
5401
5485
|
function asViewportAPI(viewportSystem) {
|
|
5402
5486
|
return {
|
|
5403
5487
|
canvasToSvg: viewportSystem.canvasToSvg.bind(viewportSystem),
|
|
5404
5488
|
setStaticTransform: viewportSystem.setStaticTransform.bind(viewportSystem),
|
|
5405
|
-
setDynamicTransform: viewportSystem.setDynamicTransform.bind(viewportSystem)
|
|
5489
|
+
setDynamicTransform: viewportSystem.setDynamicTransform.bind(viewportSystem),
|
|
5490
|
+
setMaxZoom: viewportSystem.setMaxZoom.bind(viewportSystem),
|
|
5491
|
+
setMinZoom: viewportSystem.setMinZoom.bind(viewportSystem)
|
|
5406
5492
|
};
|
|
5407
5493
|
}
|
|
5408
5494
|
function eventToCanvas(event) {
|
|
@@ -6418,10 +6504,13 @@ class Renderer {
|
|
|
6418
6504
|
const api = asViewportAPI(this.viewportSystem);
|
|
6419
6505
|
const guard = (name) => this.assertInitialized(`viewport.${name}`) && this.assertNotDisposed(`viewport.${name}`);
|
|
6420
6506
|
const guardExternal = (name) => guard(name) && this.assertExternalMode(`viewport.${name}`);
|
|
6507
|
+
const guardNotExternal = (name) => guard(name) && this.assertNotExternalMode(`viewport.${name}`);
|
|
6421
6508
|
this.viewportAPI = {
|
|
6422
6509
|
canvasToSvg: guardFn(guard, api.canvasToSvg, { x: 0, y: 0 }),
|
|
6423
6510
|
setStaticTransform: guardFn(guardExternal, api.setStaticTransform),
|
|
6424
|
-
setDynamicTransform: guardFn(guardExternal, api.setDynamicTransform)
|
|
6511
|
+
setDynamicTransform: guardFn(guardExternal, api.setDynamicTransform),
|
|
6512
|
+
setMaxZoom: guardFn(guardNotExternal, api.setMaxZoom),
|
|
6513
|
+
setMinZoom: guardFn(guardNotExternal, api.setMinZoom)
|
|
6425
6514
|
};
|
|
6426
6515
|
return this.viewportAPI;
|
|
6427
6516
|
}
|
|
@@ -6521,12 +6610,13 @@ class Renderer {
|
|
|
6521
6610
|
(_b = (_a2 = this.ui) == null ? void 0 : _a2.stats) == null ? void 0 : _b.begin();
|
|
6522
6611
|
if (this.isExternalMode) this.renderer.resetState();
|
|
6523
6612
|
else this.resizeCanvasToDisplaySize();
|
|
6524
|
-
this.viewportSystem
|
|
6525
|
-
const hasDefsUpdated = this.layerSystem.processPendingUpdates();
|
|
6613
|
+
const { scene, camera } = this.viewportSystem;
|
|
6526
6614
|
const hasControlsUpdated = this.interactionsSystem.updateControls(this.clock.getDelta());
|
|
6615
|
+
this.viewportSystem.updatePtScale();
|
|
6616
|
+
const hasDefsUpdated = this.layerSystem.processPendingUpdates(scene, camera, 3);
|
|
6527
6617
|
const needsRedraw = this.needsRedraw || hasControlsUpdated || hasDefsUpdated || this.isExternalMode || this.ui;
|
|
6528
6618
|
if (needsRedraw) {
|
|
6529
|
-
this.renderer.render(
|
|
6619
|
+
this.renderer.render(scene, camera);
|
|
6530
6620
|
this.needsRedraw = false;
|
|
6531
6621
|
}
|
|
6532
6622
|
(_d = (_c = this.ui) == null ? void 0 : _c.stats) == null ? void 0 : _d.end();
|
|
@@ -6562,7 +6652,8 @@ class Renderer {
|
|
|
6562
6652
|
// https://webgl2fundamentals.org/webgl/lessons/webgl-resizing-the-canvas.html
|
|
6563
6653
|
resizeCanvasToDisplaySize() {
|
|
6564
6654
|
const dpr = window.devicePixelRatio;
|
|
6565
|
-
const
|
|
6655
|
+
const width = this.canvas.clientWidth;
|
|
6656
|
+
const height = this.canvas.clientHeight;
|
|
6566
6657
|
const displayWidth = Math.floor(width * dpr);
|
|
6567
6658
|
const displayHeight = Math.floor(height * dpr);
|
|
6568
6659
|
if (this.canvas.width !== displayWidth || this.canvas.height !== displayHeight || this.renderer.getPixelRatio() !== dpr) {
|