@netless/app-slide 0.2.85 → 0.2.86

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/main.es.js CHANGED
@@ -37914,7 +37914,10 @@ const EmptyAttributes = {
37914
37914
  state: null,
37915
37915
  resourceList: [],
37916
37916
  previewList: [],
37917
- customLinks: []
37917
+ customLinks: [],
37918
+ slideScale: 1,
37919
+ translateX: 0.5,
37920
+ translateY: 0.5
37918
37921
  };
37919
37922
  const noop$1 = function noop2() {
37920
37923
  };
@@ -38147,7 +38150,7 @@ class SlideControllerBase {
38147
38150
  anchor,
38148
38151
  interactive: true,
38149
38152
  mode: "interactive",
38150
- controller: logger.enable,
38153
+ controller: false,
38151
38154
  enableGlobalClick: (_a = options.enableGlobalClick) != null ? _a : true,
38152
38155
  renderOptions: {
38153
38156
  minFPS: options.minFPS || 25,
@@ -39233,6 +39236,362 @@ class DocsViewer {
39233
39236
  return `${this.namespace}-${className}`;
39234
39237
  }
39235
39238
  }
39239
+ class ScrollBar {
39240
+ constructor(container, resizableContainer) {
39241
+ this.horizontalScrollBar = null;
39242
+ this.verticalScrollBar = null;
39243
+ this.isDraggingHorizontal = false;
39244
+ this.isDraggingVertical = false;
39245
+ this.eventListeners = [];
39246
+ this.container = container;
39247
+ this.resizableContainer = resizableContainer;
39248
+ }
39249
+ addTrackedListener(element, type, listener) {
39250
+ element.addEventListener(type, listener);
39251
+ this.eventListeners.push({ element, type, listener });
39252
+ }
39253
+ removeAllListeners() {
39254
+ this.eventListeners.forEach(({ element, type, listener }) => {
39255
+ element.removeEventListener(type, listener);
39256
+ });
39257
+ this.eventListeners = [];
39258
+ }
39259
+ render(containerWidth, containerHeight, contentWidth, contentHeight) {
39260
+ this.clearScrollBars();
39261
+ if (contentWidth > containerWidth) {
39262
+ this.createHorizontalScrollBar(containerWidth, contentWidth);
39263
+ }
39264
+ if (contentHeight > containerHeight) {
39265
+ this.createVerticalScrollBar(containerHeight, contentHeight);
39266
+ }
39267
+ }
39268
+ handleNormalizeTranslate(x, y) {
39269
+ const clampedX = Math.max(0, Math.min(1, x));
39270
+ const clampedY = Math.max(0, Math.min(1, y));
39271
+ if (this.horizontalScrollBar) {
39272
+ const thumb = this.horizontalScrollBar.querySelector(".horizontal-thumb");
39273
+ if (thumb) {
39274
+ const trackWidth = this.horizontalScrollBar.offsetWidth;
39275
+ const thumbWidth = thumb.offsetWidth;
39276
+ const maxPosition = trackWidth - thumbWidth - 2;
39277
+ if (maxPosition > 0) {
39278
+ const newPosition = 1 + clampedX * maxPosition;
39279
+ thumb.style.left = `${newPosition}px`;
39280
+ }
39281
+ }
39282
+ }
39283
+ if (this.verticalScrollBar) {
39284
+ const thumb = this.verticalScrollBar.querySelector(".vertical-thumb");
39285
+ if (thumb) {
39286
+ const trackHeight = this.verticalScrollBar.offsetHeight;
39287
+ const thumbHeight = thumb.offsetHeight;
39288
+ const maxPosition = trackHeight - thumbHeight - 2;
39289
+ if (maxPosition > 0) {
39290
+ const newPosition = 1 + clampedY * maxPosition;
39291
+ thumb.style.top = `${newPosition}px`;
39292
+ }
39293
+ }
39294
+ }
39295
+ }
39296
+ clearScrollBars() {
39297
+ this.removeAllListeners();
39298
+ if (this.horizontalScrollBar) {
39299
+ this.horizontalScrollBar.remove();
39300
+ this.horizontalScrollBar = null;
39301
+ }
39302
+ if (this.verticalScrollBar) {
39303
+ this.verticalScrollBar.remove();
39304
+ this.verticalScrollBar = null;
39305
+ }
39306
+ }
39307
+ createHorizontalScrollBar(containerWidth, contentWidth) {
39308
+ const scrollBar = document.createElement("div");
39309
+ scrollBar.className = "scroll-bar horizontal";
39310
+ const availableWidth = containerWidth;
39311
+ const trackWidth = availableWidth;
39312
+ const thumbWidth = Math.max(30, Math.min(trackWidth, trackWidth * availableWidth / contentWidth));
39313
+ scrollBar.style.cssText = `
39314
+ position: absolute;
39315
+ bottom: 0;
39316
+ left: 0;
39317
+ width: ${trackWidth}px;
39318
+ height: 6px;
39319
+ z-index: 1000;
39320
+ cursor: pointer;
39321
+ opacity: 1;
39322
+ transition: opacity 0.2s ease;
39323
+ `;
39324
+ const thumb = document.createElement("div");
39325
+ thumb.className = "scroll-bar-thumb horizontal-thumb";
39326
+ thumb.style.cssText = `
39327
+ position: absolute;
39328
+ bottom: 0px;
39329
+ left: 0px;
39330
+ width: ${thumbWidth}px;
39331
+ height: 6px;
39332
+ background: #9E9E9E;
39333
+ border-radius: 4px;
39334
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
39335
+ cursor: grab;
39336
+ `;
39337
+ this.addThumbDragListener(thumb, "horizontal", thumbWidth, trackWidth);
39338
+ scrollBar.appendChild(thumb);
39339
+ this.container.appendChild(scrollBar);
39340
+ this.horizontalScrollBar = scrollBar;
39341
+ }
39342
+ createVerticalScrollBar(containerHeight, contentHeight) {
39343
+ const scrollBar = document.createElement("div");
39344
+ scrollBar.className = "scroll-bar vertical";
39345
+ const availableHeight = containerHeight;
39346
+ const trackHeight = availableHeight;
39347
+ const thumbHeight = Math.max(30, Math.min(trackHeight, trackHeight * availableHeight / contentHeight));
39348
+ scrollBar.style.cssText = `
39349
+ position: absolute;
39350
+ top: 0;
39351
+ right: 0;
39352
+ width: 6px;
39353
+ height: ${trackHeight}px;
39354
+ z-index: 1000;
39355
+ cursor: pointer;
39356
+ opacity: 1;
39357
+ transition: opacity 0.2s ease;
39358
+ `;
39359
+ const thumb = document.createElement("div");
39360
+ thumb.className = "scroll-bar-thumb vertical-thumb";
39361
+ thumb.style.cssText = `
39362
+ position: absolute;
39363
+ top: 1px;
39364
+ left: 0px;
39365
+ width: 6px;
39366
+ height: ${thumbHeight}px;
39367
+ background: #9E9E9E;
39368
+ border-radius: 4px;
39369
+ box-shadow: 1px 0 2px rgba(0, 0, 0, 0.2);
39370
+ cursor: grab;
39371
+ `;
39372
+ this.addThumbDragListener(thumb, "vertical", thumbHeight, trackHeight);
39373
+ scrollBar.appendChild(thumb);
39374
+ this.container.appendChild(scrollBar);
39375
+ this.verticalScrollBar = scrollBar;
39376
+ }
39377
+ addThumbDragListener(thumb, orientation, thumbSize, trackSize) {
39378
+ let startPos = 0;
39379
+ let startThumbPos = 0;
39380
+ const handleStart = (clientX, clientY) => {
39381
+ if (orientation === "horizontal") {
39382
+ this.isDraggingHorizontal = true;
39383
+ } else {
39384
+ this.isDraggingVertical = true;
39385
+ }
39386
+ startPos = orientation === "horizontal" ? clientX : clientY;
39387
+ startThumbPos = orientation === "horizontal" ? parseFloat(thumb.style.left) || 0 : parseFloat(thumb.style.top) || 0;
39388
+ thumb.style.cursor = "grabbing";
39389
+ };
39390
+ const handleMove = (clientX, clientY) => {
39391
+ var _a, _b;
39392
+ const isDragging = orientation === "horizontal" ? this.isDraggingHorizontal : this.isDraggingVertical;
39393
+ if (!isDragging)
39394
+ return;
39395
+ const currentPos = orientation === "horizontal" ? clientX : clientY;
39396
+ const delta = currentPos - startPos;
39397
+ let newThumbPos = startThumbPos + delta;
39398
+ newThumbPos = Math.max(1, Math.min(trackSize - thumbSize - 1, newThumbPos));
39399
+ if (orientation === "horizontal") {
39400
+ thumb.style.left = `${newThumbPos}px`;
39401
+ } else {
39402
+ thumb.style.top = `${newThumbPos}px`;
39403
+ }
39404
+ const maxScroll = trackSize - thumbSize - 2;
39405
+ let scrollRatio = 0;
39406
+ if (maxScroll > 0) {
39407
+ scrollRatio = (newThumbPos - 1) / maxScroll;
39408
+ scrollRatio = Math.max(0, Math.min(1, scrollRatio));
39409
+ }
39410
+ if (orientation === "horizontal") {
39411
+ this.resizableContainer.handleNormalizeTranslate(scrollRatio, (_a = this.resizableContainer["translateY"]) != null ? _a : 0.5, {
39412
+ triggerScrollBar: false,
39413
+ triggerSync: true
39414
+ });
39415
+ } else {
39416
+ this.resizableContainer.handleNormalizeTranslate((_b = this.resizableContainer["translateX"]) != null ? _b : 0.5, scrollRatio, {
39417
+ triggerScrollBar: false,
39418
+ triggerSync: true
39419
+ });
39420
+ }
39421
+ };
39422
+ const handleEnd = () => {
39423
+ if (orientation === "horizontal") {
39424
+ this.isDraggingHorizontal = false;
39425
+ } else {
39426
+ this.isDraggingVertical = false;
39427
+ }
39428
+ thumb.style.cursor = "grab";
39429
+ };
39430
+ const handleMouseDown = (e) => {
39431
+ handleStart(e.clientX, e.clientY);
39432
+ e.preventDefault();
39433
+ };
39434
+ const handleMouseMove = (e) => {
39435
+ handleMove(e.clientX, e.clientY);
39436
+ };
39437
+ const handleMouseUp = () => {
39438
+ handleEnd();
39439
+ };
39440
+ this.addTrackedListener(thumb, "mousedown", handleMouseDown);
39441
+ this.addTrackedListener(document, "mousemove", handleMouseMove);
39442
+ this.addTrackedListener(document, "mouseup", handleMouseUp);
39443
+ }
39444
+ destroy() {
39445
+ this.clearScrollBars();
39446
+ }
39447
+ }
39448
+ class ResizableContainer {
39449
+ constructor(parent, context, enableResize) {
39450
+ this.onScaleChanged = null;
39451
+ this.whiteboardContainer = null;
39452
+ this.slide = null;
39453
+ this.scale = 1;
39454
+ this.resizeObserver = null;
39455
+ this.slideWidth = 1;
39456
+ this.slideHeight = 1;
39457
+ this.translateX = 0.5;
39458
+ this.translateY = 0.5;
39459
+ this.lastTriggerTime = 0;
39460
+ this.updateSlideSize = () => {
39461
+ if (this.slide) {
39462
+ let updateContainer = false;
39463
+ if (this.slideWidth !== this.slide.width || this.slideHeight !== this.slide.height) {
39464
+ this.slideWidth = this.slide.width;
39465
+ this.slideHeight = this.slide.height;
39466
+ updateContainer = true;
39467
+ }
39468
+ if (updateContainer) {
39469
+ this.updateResizableContainer();
39470
+ }
39471
+ }
39472
+ };
39473
+ this.enableResize = enableResize || true;
39474
+ this.parent = parent;
39475
+ this.context = context;
39476
+ this.root = document.createElement("div");
39477
+ this.root.style.width = "100%";
39478
+ this.root.style.height = "100%";
39479
+ this.root.style.overflow = "hidden";
39480
+ this.parent.appendChild(this.root);
39481
+ this.scrollContainer = document.createElement("div");
39482
+ this.scrollContainer.setAttribute("data-resizable-scroll", "true");
39483
+ this.scrollContainer.style.width = "100%";
39484
+ this.scrollContainer.style.height = "100%";
39485
+ this.scrollContainer.style.position = "relative";
39486
+ this.scrollContainer.style.overflow = "hidden";
39487
+ this.container = document.createElement("div");
39488
+ this.container.style.position = "relative";
39489
+ this.container.setAttribute("data-resizable-container", "true");
39490
+ this.scrollContainer.appendChild(this.container);
39491
+ this.root.appendChild(this.scrollContainer);
39492
+ this.scrollBar = new ScrollBar(this.root, this);
39493
+ this.resizeObserver = new ResizeObserver(() => {
39494
+ this.updateResizableContainer();
39495
+ });
39496
+ this.resizeObserver.observe(this.scrollContainer);
39497
+ }
39498
+ getTranslate() {
39499
+ return { x: this.translateX, y: this.translateY };
39500
+ }
39501
+ getScale() {
39502
+ return this.scale;
39503
+ }
39504
+ renderScrollBar(width, overflowWidth, height, overflowHeight) {
39505
+ if (this.scrollBar) {
39506
+ this.scrollBar.render(width, height, overflowWidth, overflowHeight);
39507
+ }
39508
+ }
39509
+ setSlideObject(slide) {
39510
+ this.slide = slide;
39511
+ this.slide.on("renderEnd", this.updateSlideSize);
39512
+ }
39513
+ updateResizableContainer() {
39514
+ if (Date.now() - this.lastTriggerTime < 50) {
39515
+ return;
39516
+ }
39517
+ this.lastTriggerTime = Date.now();
39518
+ const parentBounds = this.scrollContainer.getBoundingClientRect();
39519
+ this.container.style.width = `${parentBounds.width * this.scale}px`;
39520
+ this.container.style.height = `${parentBounds.height * this.scale}px`;
39521
+ if (this.whiteboardContainer) {
39522
+ const whiteboardBounds = this.whiteboardContainer.getBoundingClientRect();
39523
+ if (whiteboardBounds.width / whiteboardBounds.height > this.slideWidth / this.slideHeight) {
39524
+ const renderWidth = whiteboardBounds.height * this.slideWidth / this.slideHeight;
39525
+ const padding = (whiteboardBounds.width - renderWidth) / 2;
39526
+ this.whiteboardContainer.style.clipPath = `inset(0px ${padding}px 0px ${padding}px)`;
39527
+ } else if (whiteboardBounds.width / whiteboardBounds.height < this.slideWidth / this.slideHeight) {
39528
+ const renderHeight = whiteboardBounds.width * this.slideHeight / this.slideWidth;
39529
+ const padding = (whiteboardBounds.height - renderHeight) / 2;
39530
+ this.whiteboardContainer.style.clipPath = `inset(${padding}px 0px ${padding}px 0px)`;
39531
+ }
39532
+ }
39533
+ this.translateX = 0.5;
39534
+ this.translateY = 0.5;
39535
+ this.renderScrollBar(parentBounds.width, parentBounds.width * this.scale, parentBounds.height, parentBounds.height * this.scale);
39536
+ this.handleNormalizeTranslate(this.translateX, this.translateY, {
39537
+ triggerScrollBar: true,
39538
+ triggerSync: true
39539
+ });
39540
+ }
39541
+ handleNormalizeTranslate(x, y, options) {
39542
+ if (Math.abs(x - this.translateX) < 1e-3 && Math.abs(y - this.translateY) < 1e-3 && !options.triggerSync) {
39543
+ return;
39544
+ }
39545
+ const parentBounds = this.scrollContainer.getBoundingClientRect();
39546
+ const selfBounds = this.container.getBoundingClientRect();
39547
+ const translateX = -x * (selfBounds.width - parentBounds.width);
39548
+ const translateY = -y * (selfBounds.height - parentBounds.height);
39549
+ this.translateX = x;
39550
+ this.translateY = y;
39551
+ this.container.style.transform = `translate(${translateX}px, ${translateY}px)`;
39552
+ if (options.triggerScrollBar) {
39553
+ this.scrollBar.handleNormalizeTranslate(x, y);
39554
+ }
39555
+ if (options.triggerSync) {
39556
+ this.context.storage.setState({ translateX: this.translateX, translateY: this.translateY });
39557
+ }
39558
+ }
39559
+ scaleContainer(applyScale) {
39560
+ if (Math.abs(this.scale - applyScale) < 1e-3) {
39561
+ return;
39562
+ }
39563
+ if (applyScale > 1) {
39564
+ this.scrollContainer.style.width = "calc(100% - 6px)";
39565
+ this.scrollContainer.style.height = "calc(100% - 6px)";
39566
+ } else {
39567
+ this.scrollContainer.style.width = "100%";
39568
+ this.scrollContainer.style.height = "100%";
39569
+ }
39570
+ applyScale = this.enableResize ? applyScale : 1;
39571
+ if (this.onScaleChanged && this.enableResize) {
39572
+ this.onScaleChanged(applyScale);
39573
+ }
39574
+ this.scale = applyScale;
39575
+ setTimeout(() => {
39576
+ this.updateResizableContainer();
39577
+ });
39578
+ }
39579
+ addSlideContainer(slideContainer) {
39580
+ this.container.appendChild(slideContainer);
39581
+ }
39582
+ addWhiteboardContainer(whiteboardContainer) {
39583
+ this.container.appendChild(whiteboardContainer);
39584
+ this.whiteboardContainer = whiteboardContainer;
39585
+ }
39586
+ getCurrentScale() {
39587
+ return this.scale;
39588
+ }
39589
+ destroy() {
39590
+ var _a, _b;
39591
+ (_a = this.resizeObserver) == null ? void 0 : _a.disconnect();
39592
+ (_b = this.scrollBar) == null ? void 0 : _b.destroy();
39593
+ }
39594
+ }
39236
39595
  const ClickThroughAppliances = /* @__PURE__ */ new Set(["clicker"]);
39237
39596
  const noop = function noop22() {
39238
39597
  };
@@ -39246,6 +39605,7 @@ class SlideDocsViewer {
39246
39605
  baseScenePath,
39247
39606
  appId,
39248
39607
  urlInterrupter,
39608
+ enableScale,
39249
39609
  onPagesReady,
39250
39610
  onNavigate
39251
39611
  }) {
@@ -39410,6 +39770,7 @@ class SlideDocsViewer {
39410
39770
  this.mountWhiteboard = mountWhiteboard;
39411
39771
  this.onNavigate = onNavigate || noop;
39412
39772
  this.baseScenePath = baseScenePath;
39773
+ this.enableScale = enableScale != null ? enableScale : false;
39413
39774
  this.appId = appId;
39414
39775
  this.viewer = new DocsViewer({
39415
39776
  readonly: box.readonly,
@@ -39437,6 +39798,45 @@ class SlideDocsViewer {
39437
39798
  };
39438
39799
  });
39439
39800
  this.render();
39801
+ this.sideEffect.add(() => {
39802
+ const applyScale = (scale) => {
39803
+ if (this.resizableContainer) {
39804
+ this.resizableContainer.scaleContainer(scale);
39805
+ }
39806
+ };
39807
+ console.log("[SlideDocsViewer] Initial storage state:", this.context.storage.state);
39808
+ console.log("[SlideDocsViewer] Initial slideScale:", this.context.storage.state.slideScale);
39809
+ if (this.context.storage.state.slideScale !== void 0) {
39810
+ console.log("[SlideDocsViewer] Applying initial slideScale:", this.context.storage.state.slideScale);
39811
+ applyScale(this.context.storage.state.slideScale);
39812
+ } else {
39813
+ console.log("[SlideDocsViewer] No initial slideScale found");
39814
+ }
39815
+ const handler = (diff) => {
39816
+ var _a, _b;
39817
+ if (diff.slideScale !== void 0) {
39818
+ const newScale = diff.slideScale.newValue;
39819
+ applyScale(newScale != null ? newScale : 1);
39820
+ }
39821
+ if (diff.translateX !== void 0 || diff.translateY !== void 0) {
39822
+ const currentTranslate = this.resizableContainer.getTranslate();
39823
+ const translateX = diff.translateX ? (_a = diff.translateX.newValue) != null ? _a : 0.5 : currentTranslate.x;
39824
+ const translateY = diff.translateY ? (_b = diff.translateY.newValue) != null ? _b : 0.5 : currentTranslate.y;
39825
+ if (this.resizableContainer) {
39826
+ this.resizableContainer.handleNormalizeTranslate(translateX, translateY, {
39827
+ triggerScrollBar: true,
39828
+ triggerSync: false
39829
+ });
39830
+ }
39831
+ }
39832
+ };
39833
+ console.log("[SlideDocsViewer] Adding storage state listener");
39834
+ this.context.storage.onStateChanged.addListener(handler);
39835
+ return () => {
39836
+ console.log("[SlideDocsViewer] Removing storage state listener");
39837
+ this.context.storage.onStateChanged.removeListener(handler);
39838
+ };
39839
+ });
39440
39840
  }
39441
39841
  setJustSildeReadonly(justSildeReadonly) {
39442
39842
  var _a;
@@ -39444,9 +39844,15 @@ class SlideDocsViewer {
39444
39844
  (_a = this.slideController) == null ? void 0 : _a.slide.setInteractive(!this.justSildeReadonly);
39445
39845
  }
39446
39846
  render() {
39447
- this.viewer.$content.appendChild(this.renderSlideContainer());
39448
- this.viewer.$content.appendChild(this.renderWhiteboardView());
39449
- this.viewer.$content.appendChild(this.renderOverlay());
39847
+ if (!this.resizableContainer) {
39848
+ this.resizableContainer = new ResizableContainer(this.viewer.$content, this.context, this.enableScale);
39849
+ }
39850
+ this.renderSlideContainer();
39851
+ this.renderWhiteboardView();
39852
+ this.renderOverlay();
39853
+ this.resizableContainer.addSlideContainer(this.$slide);
39854
+ this.resizableContainer.addWhiteboardContainer(this.$whiteboardView);
39855
+ this.viewer.$content.appendChild(this.$overlay);
39450
39856
  this.sideEffect.addEventListener(window, "keydown", (ev) => {
39451
39857
  if (this.justSildeReadonly) {
39452
39858
  return;
@@ -39506,6 +39912,7 @@ class SlideDocsViewer {
39506
39912
  onNavigate: this.onNavigate,
39507
39913
  onError: this.onError
39508
39914
  });
39915
+ this.resizableContainer.setSlideObject(this.slideController.slide);
39509
39916
  this.scaleDocsToFit();
39510
39917
  this.sideEffect.add(() => {
39511
39918
  this.whiteboardView.callbacks.on("onSizeUpdated", this.scaleDocsToFit);
@@ -39522,6 +39929,7 @@ class SlideDocsViewer {
39522
39929
  this.slideController = null;
39523
39930
  }
39524
39931
  this.viewer.unmount();
39932
+ this.resizableContainer.destroy();
39525
39933
  return this;
39526
39934
  }
39527
39935
  setReadonly(readonly) {
@@ -39819,11 +40227,11 @@ class SlidePreviewer {
39819
40227
  }
39820
40228
  }
39821
40229
  const usePlugin = /* @__PURE__ */ Slide.Slide.usePlugin.bind(Slide.Slide);
39822
- const version = "0.2.85";
40230
+ const version = "0.2.86";
39823
40231
  const SlideApp = {
39824
40232
  kind: "Slide",
39825
40233
  setup(context) {
39826
- var _a, _b;
40234
+ var _a, _b, _c, _d;
39827
40235
  console.log("[Slide] setup @ " + version);
39828
40236
  if (context.getIsWritable()) {
39829
40237
  context.storage.ensureState(EmptyAttributes);
@@ -39898,6 +40306,7 @@ const SlideApp = {
39898
40306
  baseScenePath,
39899
40307
  appId: context.appId,
39900
40308
  urlInterrupter: (_a = context.getAppOptions()) == null ? void 0 : _a.urlInterrupter,
40309
+ enableScale: (_c = (_b = context.getAppOptions()) == null ? void 0 : _b.enableScale) != null ? _c : false,
39901
40310
  onPagesReady: ({ length }) => {
39902
40311
  const index = (docsViewer == null ? void 0 : docsViewer.viewer.pageIndex) || 0;
39903
40312
  context.dispatchAppEvent("pageStateChange", { index, length });
@@ -39906,7 +40315,7 @@ const SlideApp = {
39906
40315
  log("[Slide] user navigate to", page, origin ? `(${origin})` : "");
39907
40316
  }
39908
40317
  });
39909
- if ((_b = context.getAppOptions()) == null ? void 0 : _b.justSildeReadonly) {
40318
+ if ((_d = context.getAppOptions()) == null ? void 0 : _d.justSildeReadonly) {
39910
40319
  docsViewer == null ? void 0 : docsViewer.setJustSildeReadonly(true);
39911
40320
  }
39912
40321
  const room = context.getRoom();
@@ -39942,6 +40351,53 @@ const SlideApp = {
39942
40351
  });
39943
40352
  docsViewer.mount();
39944
40353
  return {
40354
+ onScaleChanged: (cb) => {
40355
+ if (!docsViewer) {
40356
+ return;
40357
+ }
40358
+ docsViewer.resizableContainer.onScaleChanged = cb;
40359
+ },
40360
+ scaleView: (to) => {
40361
+ let applyScale = Number(to);
40362
+ if (Number.isNaN(applyScale)) {
40363
+ applyScale = 1;
40364
+ }
40365
+ if (applyScale < 1) {
40366
+ applyScale = 1;
40367
+ }
40368
+ if (applyScale > 4) {
40369
+ applyScale = 4;
40370
+ }
40371
+ context.storage.setState({ slideScale: applyScale });
40372
+ context.storage.setState({ translateX: 0.5, translateY: 0.5 });
40373
+ docsViewer == null ? void 0 : docsViewer.resizableContainer.scaleContainer(applyScale);
40374
+ },
40375
+ getViewScale: () => {
40376
+ return docsViewer == null ? void 0 : docsViewer.resizableContainer.getScale();
40377
+ },
40378
+ translateView: (offsetX, offsetY) => {
40379
+ var _a2, _b2;
40380
+ if (docsViewer == null ? void 0 : docsViewer.resizableContainer) {
40381
+ const container = docsViewer.resizableContainer;
40382
+ const parentBounds = context.getBox().$content.getBoundingClientRect();
40383
+ const containerBounds = container.container.getBoundingClientRect();
40384
+ const maxScrollX = containerBounds.width - parentBounds.width;
40385
+ const maxScrollY = containerBounds.height - parentBounds.height;
40386
+ if (maxScrollX > 0 || maxScrollY > 0) {
40387
+ const currentX = (_a2 = container["translateX"]) != null ? _a2 : 0.5;
40388
+ const currentY = (_b2 = container["translateY"]) != null ? _b2 : 0.5;
40389
+ const normalizedDeltaX = maxScrollX > 0 ? offsetX / maxScrollX : 0;
40390
+ const normalizedDeltaY = maxScrollY > 0 ? offsetY / maxScrollY : 0;
40391
+ const newX = Math.max(0, Math.min(1, currentX + normalizedDeltaX));
40392
+ const newY = Math.max(0, Math.min(1, currentY + normalizedDeltaY));
40393
+ context.storage.setState({ translateX: newX, translateY: newY });
40394
+ container.handleNormalizeTranslate(newX, newY, {
40395
+ triggerScrollBar: true,
40396
+ triggerSync: false
40397
+ });
40398
+ }
40399
+ }
40400
+ },
39945
40401
  setSildeReadonly: (bol) => {
39946
40402
  docsViewer == null ? void 0 : docsViewer.setJustSildeReadonly(bol);
39947
40403
  },