@ifc-lite/viewer-core 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"viewer-html.d.ts","sourceRoot":"","sources":["../src/viewer-html.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;GAgBG;AAEH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CA0xCvD"}
1
+ {"version":3,"file":"viewer-html.d.ts","sourceRoot":"","sources":["../src/viewer-html.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;GAgBG;AAEH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CA+yCvD"}
@@ -583,6 +583,10 @@ let camTheta = Math.PI * 0.25;
583
583
  let camPhi = Math.PI * 0.3;
584
584
  let camDist = 50;
585
585
  let camTarget = [0, 0, 0];
586
+ // Smooth orbit targets — mouse input writes here, render loop lerps toward them
587
+ let camThetaTarget = camTheta;
588
+ let camPhiTarget = camPhi;
589
+ const ORBIT_SMOOTHING = 0.35; // lerp factor per frame (higher = snappier)
586
590
  // Inertia
587
591
  let camVelTheta = 0, camVelPhi = 0;
588
592
  let camVelPanX = 0, camVelPanY = 0, camVelPanZ = 0;
@@ -611,8 +615,8 @@ function fitCamera() {
611
615
  const maxDim = Math.max(dx, dy, dz, 0.1);
612
616
  camTarget = [cx, cy, cz];
613
617
  camDist = maxDim * 1.5;
614
- camTheta = Math.PI * 0.25;
615
- camPhi = Math.PI * 0.3;
618
+ camTheta = camThetaTarget = Math.PI * 0.25;
619
+ camPhi = camPhiTarget = Math.PI * 0.3;
616
620
  camVelTheta = camVelPhi = camVelPanX = camVelPanY = camVelPanZ = 0;
617
621
  }
618
622
 
@@ -633,10 +637,14 @@ function updateCamAnimation() {
633
637
  camDist = camAnimFrom.dist + (camAnimTo.dist - camAnimFrom.dist) * ease;
634
638
  if (t >= 1) camAnimating = false;
635
639
  }
640
+ // Smooth orbit: lerp actual angles toward targets every frame
641
+ camTheta += (camThetaTarget - camTheta) * ORBIT_SMOOTHING;
642
+ camPhi += (camPhiTarget - camPhi) * ORBIT_SMOOTHING;
643
+
636
644
  // Inertia (only when not dragging)
637
645
  if (!isDragging) {
638
- camTheta += camVelTheta;
639
- camPhi = Math.max(0.05, Math.min(Math.PI - 0.05, camPhi + camVelPhi));
646
+ camThetaTarget += camVelTheta;
647
+ camPhiTarget = Math.max(0.05, Math.min(Math.PI - 0.05, camPhiTarget + camVelPhi));
640
648
  camTarget[0] += camVelPanX;
641
649
  camTarget[1] += camVelPanY;
642
650
  camTarget[2] += camVelPanZ;
@@ -651,11 +659,16 @@ function updateCamAnimation() {
651
659
  let isDragging = false;
652
660
  let isPanning = false;
653
661
  let lastMouse = [0, 0];
662
+ let mouseDownPos = [0, 0];
663
+ let didDrag = false;
664
+ const DRAG_THRESHOLD = 3; // px – movement beyond this suppresses click
654
665
 
655
666
  canvas.addEventListener('mousedown', (e) => {
656
667
  isDragging = true;
668
+ didDrag = false;
657
669
  isPanning = e.button === 1 || e.button === 2 || e.shiftKey;
658
670
  lastMouse = [e.clientX, e.clientY];
671
+ mouseDownPos = [e.clientX, e.clientY];
659
672
  camVelTheta = camVelPhi = camVelPanX = camVelPanY = camVelPanZ = 0;
660
673
  e.preventDefault();
661
674
  });
@@ -664,6 +677,13 @@ window.addEventListener('mouseup', () => { isDragging = false; isPanning = false
664
677
 
665
678
  window.addEventListener('mousemove', (e) => {
666
679
  if (!isDragging) return;
680
+ if (!didDrag) {
681
+ const totalDx = e.clientX - mouseDownPos[0];
682
+ const totalDy = e.clientY - mouseDownPos[1];
683
+ if (totalDx * totalDx + totalDy * totalDy > DRAG_THRESHOLD * DRAG_THRESHOLD) {
684
+ didDrag = true;
685
+ }
686
+ }
667
687
  const dx = e.clientX - lastMouse[0];
668
688
  const dy = e.clientY - lastMouse[1];
669
689
  lastMouse = [e.clientX, e.clientY];
@@ -682,8 +702,8 @@ window.addEventListener('mousemove', (e) => {
682
702
  } else {
683
703
  camVelTheta = dx * 0.004;
684
704
  camVelPhi = -dy * 0.004;
685
- camTheta += camVelTheta;
686
- camPhi = Math.max(0.05, Math.min(Math.PI - 0.05, camPhi + camVelPhi));
705
+ camThetaTarget += camVelTheta;
706
+ camPhiTarget = Math.max(0.05, Math.min(Math.PI - 0.05, camPhiTarget + camVelPhi));
687
707
  }
688
708
  });
689
709
 
@@ -705,8 +725,8 @@ canvas.addEventListener('touchmove', (e) => {
705
725
  if (touches.length === 1 && lastTouches.length >= 1) {
706
726
  const dx = touches[0][0] - lastTouches[0][0];
707
727
  const dy = touches[0][1] - lastTouches[0][1];
708
- camTheta -= dx * 0.005;
709
- camPhi = Math.max(0.05, Math.min(Math.PI - 0.05, camPhi - dy * 0.005));
728
+ camThetaTarget -= dx * 0.005;
729
+ camPhiTarget = Math.max(0.05, Math.min(Math.PI - 0.05, camPhiTarget - dy * 0.005));
710
730
  } else if (touches.length === 2 && lastTouches.length >= 2) {
711
731
  const d1 = Math.hypot(lastTouches[1][0]-lastTouches[0][0], lastTouches[1][1]-lastTouches[0][1]);
712
732
  const d2 = Math.hypot(touches[1][0]-touches[0][0], touches[1][1]-touches[0][1]);
@@ -740,6 +760,7 @@ function ensurePickFbo() {
740
760
  }
741
761
 
742
762
  canvas.addEventListener('click', (e) => {
763
+ if (didDrag) return; // Was a drag, not a click
743
764
  if (!pickVao || drawCount === 0) return;
744
765
  ensurePickFbo();
745
766
  const mvp = getMVP();
@@ -1101,8 +1122,8 @@ function handleCommand(cmd) {
1101
1122
  camAnimFrom = { target: [...camTarget], dist: camDist };
1102
1123
  camAnimTo = { target: [...camTarget], dist: camDist };
1103
1124
  // Animate theta/phi by setting target directly after animation
1104
- camTheta = preset.theta;
1105
- camPhi = preset.phi;
1125
+ camTheta = camThetaTarget = preset.theta;
1126
+ camPhi = camPhiTarget = preset.phi;
1106
1127
  camVelTheta = camVelPhi = 0;
1107
1128
  }
1108
1129
  break;
@@ -1 +1 @@
1
- {"version":3,"file":"viewer-html.js","sourceRoot":"","sources":["../src/viewer-html.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,UAAU,aAAa,CAAC,SAAiB;IAC7C,4EAA4E;IAC5E,MAAM,IAAI,GAAG,SAAS;SACnB,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC1B,OAAO;;;;;SAKA,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;gBA2BG,IAAI;;;;;uBAKG,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA4uCnB,CAAC;AACT,CAAC"}
1
+ {"version":3,"file":"viewer-html.js","sourceRoot":"","sources":["../src/viewer-html.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,UAAU,aAAa,CAAC,SAAiB;IAC7C,4EAA4E;IAC5E,MAAM,IAAI,GAAG,SAAS;SACnB,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC1B,OAAO;;;;;SAKA,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;gBA2BG,IAAI;;;;;uBAKG,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAiwCnB,CAAC;AACT,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ifc-lite/viewer-core",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Interactive 3D viewer for IFC models — WebGL 2 browser viewer with REST API",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -18,7 +18,7 @@
18
18
  "dependencies": {
19
19
  "@ifc-lite/sdk": "^1.14.5",
20
20
  "@ifc-lite/create": "^1.14.4",
21
- "@ifc-lite/wasm": "^1.14.4"
21
+ "@ifc-lite/wasm": "^1.14.5"
22
22
  },
23
23
  "devDependencies": {
24
24
  "@types/node": "^20.0.0",