@sienci/gviewer 0.1.21 → 0.1.23

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.
@@ -2974,10 +2974,10 @@ function Fi(r) {
2974
2974
  }
2975
2975
  };
2976
2976
  }
2977
- const Gi = 25.4;
2978
- class Ii {
2977
+ const Gi = 25.4, fi = 500, bi = 300;
2978
+ class Yi {
2979
2979
  constructor(Q) {
2980
- this.viewCube = null, this.resizeObserver = null, this.onWindowResize = null, this.animationFrameId = null, this.gridGroup = null, this.axesGroup = null, this.gridLabelsGroup = null, this.boundingBoxGroup = null, this.machineBedGroup = null, this.bitMarker = null, this.preLaserBitType = "drill", this.toolpathStreams = [], this.toolpathCutBucketCount = 1, this.toolpathRotationA = 0, this.lastBitPosition = { x: 0, y: 0, z: 0, a: 0 }, this.sim3dHandle = null, this.currentLines = [], this.linePositions = null, this.renderSequence = 0, this.currentBounds = null, this.cameraFocusTransition = null, this.id = Q.id, this.container = Q.container, this.callbacks = Q.callbacks ?? {}, this.options = Et(GP, Q.options), this.canvas = document.createElement("canvas"), this.canvas.style.width = "100%", this.canvas.style.height = "100%", this.canvas.style.display = "block", this.container.appendChild(this.canvas), KP(this.container), this.renderer = new a.WebGLRenderer({
2980
+ this.viewCube = null, this.resizeObserver = null, this.onWindowResize = null, this.animationFrameId = null, this.gridGroup = null, this.axesGroup = null, this.gridLabelsGroup = null, this.boundingBoxGroup = null, this.machineBedGroup = null, this.bitMarker = null, this.preLaserBitType = "drill", this.toolpathStreams = [], this.toolpathCutBucketCount = 1, this.toolpathRotationA = 0, this.lastBitPosition = { x: 0, y: 0, z: 0, a: 0 }, this.sim3dHandle = null, this.currentLines = [], this.linePositions = null, this.renderSequence = 0, this.currentBounds = null, this.cameraFocusTransition = null, this.cameraFollowRequested = !1, this.cameraFollowInterrupted = !1, this.cameraFollowOffset = null, this.id = Q.id, this.container = Q.container, this.callbacks = Q.callbacks ?? {}, this.options = Et(GP, Q.options), this.canvas = document.createElement("canvas"), this.canvas.style.width = "100%", this.canvas.style.height = "100%", this.canvas.style.display = "block", this.container.appendChild(this.canvas), KP(this.container), this.renderer = new a.WebGLRenderer({
2981
2981
  canvas: this.canvas,
2982
2982
  antialias: this.options.render.antialias
2983
2983
  }), this.renderer.setPixelRatio(window.devicePixelRatio), this.renderer.setClearColor(this.options.render.theme.background, 1), this.scene = new a.Scene(), this.scene.add(new a.AmbientLight(16777215, 0.8));
@@ -2988,7 +2988,9 @@ class Ii {
2988
2988
  this.options.camera.initialPosition.x,
2989
2989
  this.options.camera.initialPosition.y,
2990
2990
  this.options.camera.initialPosition.z
2991
- ), this.controls = new lP(this.camera, this.renderer.domElement), this.controls.enableDamping = this.options.camera.orbit.enableDamping, this.controls.update(), this.viewCubeCorrection = new a.Matrix4().makeRotationX(a.MathUtils.degToRad(90)), this.viewCube = new xP({
2991
+ ), this.controls = new lP(this.camera, this.renderer.domElement), this.controls.enableDamping = this.options.camera.orbit.enableDamping, this.controls.addEventListener("start", () => {
2992
+ this.cameraFollowRequested && (this.cameraFollowInterrupted = !0);
2993
+ }), this.controls.update(), this.viewCubeCorrection = new a.Matrix4().makeRotationX(a.MathUtils.degToRad(90)), this.viewCube = new xP({
2992
2994
  container: this.container,
2993
2995
  onSelectView: (t) => {
2994
2996
  const P = new a.Vector3();
@@ -3007,7 +3009,29 @@ class Ii {
3007
3009
  }
3008
3010
  setBitPosition(Q, B) {
3009
3011
  var A;
3010
- this.ensureBitMarker(), this.lastBitPosition = { ...this.lastBitPosition, ...Q }, (A = this.bitMarker) == null || A.setTarget(Q, B);
3012
+ if (this.ensureBitMarker(), this.lastBitPosition = { ...this.lastBitPosition, ...Q }, (A = this.bitMarker) == null || A.setTarget(Q, B), this.cameraFollowRequested && !this.cameraFollowInterrupted && this.cameraFollowOffset) {
3013
+ const t = new a.Vector3(this.lastBitPosition.x, this.lastBitPosition.y, this.controls.target.z), P = t.clone().add(this.cameraFollowOffset);
3014
+ this.startCameraLerp(t, P, bi, "linear");
3015
+ }
3016
+ }
3017
+ /**
3018
+ * Enable or disable "follow tool" camera tracking. While enabled, every
3019
+ * subsequent setBitPosition() call pans the camera+target in X/Y to keep
3020
+ * the tool centered, holding the camera→target offset captured at engage
3021
+ * time constant — which is what preserves viewing angle and height. A
3022
+ * user-initiated camera drag (OrbitControls "start") interrupts an active
3023
+ * session; it only re-arms on the next disabled→enabled edge.
3024
+ */
3025
+ setCameraFollowEnabled(Q) {
3026
+ if (Q === this.cameraFollowRequested)
3027
+ return;
3028
+ if (this.cameraFollowRequested = Q, this.cameraFollowInterrupted = !1, !Q) {
3029
+ this.cameraFollowOffset = null;
3030
+ return;
3031
+ }
3032
+ this.cameraFollowOffset = this.camera.position.clone().sub(this.controls.target);
3033
+ const B = new a.Vector3(this.lastBitPosition.x, this.lastBitPosition.y, this.controls.target.z), A = B.clone().add(this.cameraFollowOffset);
3034
+ this.startCameraLerp(B, A, fi);
3011
3035
  }
3012
3036
  setBitVisible(Q) {
3013
3037
  var B;
@@ -3104,14 +3128,21 @@ class Ii {
3104
3128
  }
3105
3129
  startSnapToView(Q, B, A, t) {
3106
3130
  const P = JA(Q), e = B.clone().add(P.multiplyScalar(A)), i = Math.max(1, A);
3107
- this.camera.near = i / 1e3, this.camera.far = i * 50, this.camera.updateProjectionMatrix(), this.cameraFocusTransition && (this.controls.enableDamping = this.cameraFocusTransition.dampingEnabled), this.cameraFocusTransition = {
3131
+ this.camera.near = i / 1e3, this.camera.far = i * 50, this.camera.updateProjectionMatrix(), this.startCameraLerp(B, e, t);
3132
+ }
3133
+ // Shared tween kickoff for any camera position+target move (view snapping,
3134
+ // model focus, tool-follow engage/track): saves/restores damping around the
3135
+ // transition and hands off to updateCameraFocusTransition() each frame.
3136
+ startCameraLerp(Q, B, A, t = "easeInOutCubic") {
3137
+ this.cameraFocusTransition && (this.controls.enableDamping = this.cameraFocusTransition.dampingEnabled), this.cameraFocusTransition = {
3108
3138
  startedAt: performance.now(),
3109
- duration: t,
3139
+ duration: A,
3110
3140
  fromPosition: this.camera.position.clone(),
3111
- toPosition: e,
3141
+ toPosition: B,
3112
3142
  fromTarget: this.controls.target.clone(),
3113
- toTarget: B,
3114
- dampingEnabled: this.controls.enableDamping
3143
+ toTarget: Q,
3144
+ dampingEnabled: this.controls.enableDamping,
3145
+ easing: t
3115
3146
  }, this.controls.enableDamping = !1;
3116
3147
  }
3117
3148
  async loadFromUrl(Q, B = {}) {
@@ -3460,20 +3491,12 @@ class Ii {
3460
3491
  const A = new a.Vector3();
3461
3492
  Q.getSize(A);
3462
3493
  const t = Math.max(A.x, A.y, 1) / 2, P = a.MathUtils.degToRad(this.camera.fov), e = t / Math.tan(P / 2) * 1.25 + A.z, i = JA("front-top-left"), s = B.clone().add(i.multiplyScalar(e)), v = Math.max(A.x, A.y, A.z, 1);
3463
- this.camera.near = v / 1e3, this.camera.far = v * 50, this.camera.updateProjectionMatrix(), this.cameraFocusTransition && (this.controls.enableDamping = this.cameraFocusTransition.dampingEnabled), this.cameraFocusTransition = {
3464
- startedAt: performance.now(),
3465
- duration: this.options.camera.focusDurationMs,
3466
- fromPosition: this.camera.position.clone(),
3467
- toPosition: s,
3468
- fromTarget: this.controls.target.clone(),
3469
- toTarget: B,
3470
- dampingEnabled: this.controls.enableDamping
3471
- }, this.controls.enableDamping = !1;
3494
+ this.camera.near = v / 1e3, this.camera.far = v * 50, this.camera.updateProjectionMatrix(), this.startCameraLerp(B, s, this.options.camera.focusDurationMs);
3472
3495
  }
3473
3496
  updateCameraFocusTransition() {
3474
3497
  if (!this.cameraFocusTransition)
3475
3498
  return;
3476
- const B = performance.now() - this.cameraFocusTransition.startedAt, A = Math.min(1, Math.max(0, B / this.cameraFocusTransition.duration)), t = ZP(A);
3499
+ const B = performance.now() - this.cameraFocusTransition.startedAt, A = Math.min(1, Math.max(0, B / this.cameraFocusTransition.duration)), t = this.cameraFocusTransition.easing === "linear" ? A : ZP(A);
3477
3500
  if (this.camera.position.lerpVectors(this.cameraFocusTransition.fromPosition, this.cameraFocusTransition.toPosition, t), this.controls.target.lerpVectors(this.cameraFocusTransition.fromTarget, this.cameraFocusTransition.toTarget, t), A >= 1) {
3478
3501
  const P = this.cameraFocusTransition.dampingEnabled;
3479
3502
  this.camera.position.copy(this.cameraFocusTransition.toPosition), this.controls.target.copy(this.cameraFocusTransition.toTarget), this.cameraFocusTransition = null, this.controls.enableDamping = !1, this.controls.update(), this.controls.enableDamping = P;
@@ -3497,7 +3520,7 @@ function Et(r, Q) {
3497
3520
  var A, t, P, e;
3498
3521
  if (!Q)
3499
3522
  return { ...r };
3500
- const B = fi(r.render.theme, (A = Q.render) == null ? void 0 : A.theme);
3523
+ const B = gi(r.render.theme, (A = Q.render) == null ? void 0 : A.theme);
3501
3524
  return {
3502
3525
  ...r,
3503
3526
  ...Q,
@@ -3526,7 +3549,7 @@ function Et(r, Q) {
3526
3549
  }
3527
3550
  };
3528
3551
  }
3529
- function fi(r, Q) {
3552
+ function gi(r, Q) {
3530
3553
  var B, A;
3531
3554
  return Q ? {
3532
3555
  ...r,
@@ -3539,7 +3562,7 @@ function fi(r, Q) {
3539
3562
  }
3540
3563
  } : r;
3541
3564
  }
3542
- const bi = {
3565
+ const pi = {
3543
3566
  rapidColor: "#0ef6ae",
3544
3567
  cutColor: "#3e85c7",
3545
3568
  boundingBoxColor: "#d0d0d0",
@@ -3551,7 +3574,7 @@ const bi = {
3551
3574
  originColor: "#ffffff",
3552
3575
  crosshairColor: "#ffffff"
3553
3576
  }, eB = 0, iB = 0;
3554
- class Si {
3577
+ class Vi {
3555
3578
  constructor(Q, B) {
3556
3579
  this.crosshairPos = null, this.crosshairVisible = !1, this.pathEls = [], this.segmentGroups = [], this.workerMode = !1, this.viewBox = { x: 0, y: 0, w: 100, h: 100 }, this.rotX = eB, this.rotY = iB, this.centerX = 0, this.centerY = 0, this.centerZ = 0, this.focalLength = 500, this.cosRotX = 1, this.sinRotX = 0, this.cosRotY = 1, this.sinRotY = 0, this.dragMode = "none", this.activePointers = /* @__PURE__ */ new Map(), this.pinchLastDist = 0, this.pinchLastMid = { x: 0, y: 0 }, this.rafPending = !1, this.rapidVerts = new Float32Array(0), this.cutVerts = new Float32Array(0), this.bounds = { minX: 0, minY: 0, maxX: 0, maxY: 0, minZ: 0, maxZ: 0, empty: !0 }, this.project = (A, t, P) => {
3557
3580
  const e = A - this.centerX, i = t - this.centerY, s = P - this.centerZ, v = e * this.cosRotY + s * this.sinRotY, c = i, n = -e * this.sinRotY + s * this.cosRotY, T = v, z = c * this.cosRotX - n * this.sinRotX, w = c * this.sinRotX + n * this.cosRotX;
@@ -3619,7 +3642,7 @@ class Si {
3619
3642
  } else this.activePointers.size === 0 && (this.dragMode = "none", this.svg.style.cursor = "grab");
3620
3643
  }, this.onContextMenu = (A) => {
3621
3644
  A.preventDefault();
3622
- }, this.options = { ...bi, ...B }, this.svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"), this.svg.style.cssText = "width:100%;height:100%;display:block;cursor:grab;user-select:none;touch-action:none;", this.svg.setAttribute("preserveAspectRatio", "xMidYMid meet"), this.svg.setAttribute("xmlns", "http://www.w3.org/2000/svg"), this.bboxPath = qB(), this.pathLayer = document.createElementNS("http://www.w3.org/2000/svg", "g"), this.bboxLabelX = _B("middle", "hanging"), this.bboxLabelY = _B("start", "middle"), this.bboxLabelZ = _B("middle", "auto"), this.originMarker = document.createElementNS("http://www.w3.org/2000/svg", "circle"), this.originMarker.setAttribute("stroke-opacity", "0.4"), this.originMarker.setAttribute("visibility", "hidden"), this.crosshairEl = qB(), this.crosshairEl.setAttribute("fill", "none"), this.crosshairEl.setAttribute("visibility", "hidden"), this.svg.appendChild(this.bboxPath), this.svg.appendChild(this.pathLayer), this.svg.appendChild(this.bboxLabelX), this.svg.appendChild(this.bboxLabelY), this.svg.appendChild(this.bboxLabelZ), this.svg.appendChild(this.originMarker), this.svg.appendChild(this.crosshairEl), Q.appendChild(this.svg), this.applyOptions(), this.bindEvents();
3645
+ }, this.options = { ...pi, ...B }, this.svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"), this.svg.style.cssText = "width:100%;height:100%;display:block;cursor:grab;user-select:none;touch-action:none;", this.svg.setAttribute("preserveAspectRatio", "xMidYMid meet"), this.svg.setAttribute("xmlns", "http://www.w3.org/2000/svg"), this.bboxPath = qB(), this.pathLayer = document.createElementNS("http://www.w3.org/2000/svg", "g"), this.bboxLabelX = _B("middle", "hanging"), this.bboxLabelY = _B("start", "middle"), this.bboxLabelZ = _B("middle", "auto"), this.originMarker = document.createElementNS("http://www.w3.org/2000/svg", "circle"), this.originMarker.setAttribute("stroke-opacity", "0.4"), this.originMarker.setAttribute("visibility", "hidden"), this.crosshairEl = qB(), this.crosshairEl.setAttribute("fill", "none"), this.crosshairEl.setAttribute("visibility", "hidden"), this.svg.appendChild(this.bboxPath), this.svg.appendChild(this.pathLayer), this.svg.appendChild(this.bboxLabelX), this.svg.appendChild(this.bboxLabelY), this.svg.appendChild(this.bboxLabelZ), this.svg.appendChild(this.originMarker), this.svg.appendChild(this.crosshairEl), Q.appendChild(this.svg), this.applyOptions(), this.bindEvents();
3623
3646
  }
3624
3647
  // ── Public API ────────────────────────────────────────────────────────────
3625
3648
  loadFromLines(Q) {
@@ -3723,7 +3746,7 @@ class Si {
3723
3746
  }
3724
3747
  // ── Rendering ─────────────────────────────────────────────────────────────
3725
3748
  rebuildAndRender(Q = !1) {
3726
- const B = Q ? gi : L, A = String(this.options.strokeWidth);
3749
+ const B = Q ? mi : L, A = String(this.options.strokeWidth);
3727
3750
  for (; this.pathEls.length < this.segmentGroups.length; ) {
3728
3751
  const t = qB();
3729
3752
  this.pathLayer.appendChild(t), this.pathEls.push(t);
@@ -3732,7 +3755,7 @@ class Si {
3732
3755
  this.pathLayer.removeChild(this.pathEls.pop());
3733
3756
  for (let t = 0; t < this.segmentGroups.length; t++) {
3734
3757
  const { color: P, opacity: e, verts: i } = this.segmentGroups[t], s = this.pathEls[t];
3735
- s.setAttribute("stroke", P), s.setAttribute("stroke-opacity", String(e)), s.setAttribute("stroke-width", A), s.setAttribute("stroke-linecap", "round"), s.setAttribute("stroke-linejoin", "round"), s.setAttribute("d", pi(i, this.project, B));
3758
+ s.setAttribute("stroke", P), s.setAttribute("stroke-opacity", String(e)), s.setAttribute("stroke-width", A), s.setAttribute("stroke-linecap", "round"), s.setAttribute("stroke-linejoin", "round"), s.setAttribute("d", xi(i, this.project, B));
3736
3759
  }
3737
3760
  this.renderBbox(), this.renderOriginMarker(), this.renderCrosshairMarker(), this.applyViewBox();
3738
3761
  }
@@ -3843,13 +3866,13 @@ function at(r, Q, B) {
3843
3866
  function L(r) {
3844
3867
  return r.toFixed(2);
3845
3868
  }
3846
- function gi(r) {
3869
+ function mi(r) {
3847
3870
  return Math.round(r) + "";
3848
3871
  }
3849
3872
  function QA(r) {
3850
3873
  return r.toFixed(2);
3851
3874
  }
3852
- function pi(r, Q, B) {
3875
+ function xi(r, Q, B) {
3853
3876
  if (r.length === 0) return "";
3854
3877
  const A = [], t = 1e-6;
3855
3878
  let P = NaN, e = NaN;
@@ -3869,9 +3892,9 @@ function BA(...r) {
3869
3892
  return { minX: Q, minY: B, maxX: t, maxY: P, minZ: A, maxZ: e, empty: i };
3870
3893
  }
3871
3894
  export {
3872
- Si as G,
3895
+ Vi as G,
3873
3896
  xP as V,
3874
- Ii as a,
3897
+ Yi as a,
3875
3898
  YA as b,
3876
3899
  GP as d
3877
3900
  };