@inweb/viewer-three 26.10.3 → 26.10.5

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.
@@ -1126,12 +1126,14 @@ class MeasureSnapper {
1126
1126
  class MeasureOverlay {
1127
1127
  constructor(camera, canvas) {
1128
1128
  this.lines = [];
1129
- this.resizeContainer = (entries) => {
1130
- const { width, height } = entries[0].contentRect;
1131
- if (!width || !height)
1129
+ this.resizeContainer = () => {
1130
+ const { offsetLeft, offsetTop, offsetWidth, offsetHeight } = this.canvas;
1131
+ if (!offsetWidth || !offsetHeight)
1132
1132
  return;
1133
- this.container.style.width = `${width}px`;
1134
- this.container.style.height = `${height}px`;
1133
+ this.container.style.left = `${offsetLeft}px`;
1134
+ this.container.style.top = `${offsetTop}px`;
1135
+ this.container.style.width = `${offsetWidth}px`;
1136
+ this.container.style.height = `${offsetHeight}px`;
1135
1137
  };
1136
1138
  this.camera = camera;
1137
1139
  this.canvas = canvas;
@@ -1148,7 +1150,7 @@ class MeasureOverlay {
1148
1150
  if (!this.canvas.parentElement)
1149
1151
  return;
1150
1152
  this.canvas.parentElement.appendChild(this.container);
1151
- this.resizeObserver.observe(this.canvas.parentElement);
1153
+ this.resizeObserver.observe(this.canvas);
1152
1154
  }
1153
1155
  dispose() {
1154
1156
  this.clear();
@@ -1580,11 +1582,205 @@ class WalkControls extends Controls {
1580
1582
  }
1581
1583
  }
1582
1584
 
1585
+ class JoyStickControls extends Controls {
1586
+ constructor(camera, domElement, canvasElement, groundObjects) {
1587
+ super(camera, domElement);
1588
+ this.EYE_HEIGHT = 1.7;
1589
+ this.FAILING_DISTANCE = 2;
1590
+ this.GROUND_FOLLOWING_SPEED = 0.05;
1591
+ this.WALK_SPEED_DELIMITER = 4;
1592
+ this.movementSpeed = 0.1;
1593
+ this.multiplier = 3;
1594
+ this.isActive = false;
1595
+ this.MAX_JOYSTICK_DISTANCE = 100;
1596
+ this.INTERNAL_RADIUS = 35;
1597
+ this.MAX_MOVE_STICK = 40;
1598
+ this.EXTERNAL_RADIUS = 65;
1599
+ this.CANVAS_SIZE = 200;
1600
+ this.pressed = false;
1601
+ this.onPointerDown = (event) => {
1602
+ event.preventDefault();
1603
+ this.pressed = true;
1604
+ };
1605
+ this.onPointerMove = (event) => {
1606
+ event.preventDefault();
1607
+ if (!this.pressed)
1608
+ return;
1609
+ let movedX = event.pageX;
1610
+ let movedY = event.pageY;
1611
+ if (this.joyStickCanvas.offsetParent &&
1612
+ this.joyStickCanvas.offsetParent.tagName.toUpperCase() === "BODY") {
1613
+ movedX -= this.joyStickCanvas.offsetLeft;
1614
+ movedY -= this.joyStickCanvas.offsetTop;
1615
+ }
1616
+ else if (this.joyStickCanvas.offsetParent) {
1617
+ movedX -= this.joyStickCanvas.offsetParent.offsetLeft;
1618
+ movedY -= this.joyStickCanvas.offsetParent.offsetTop;
1619
+ }
1620
+ const x = 100 * ((movedX - this.centerX) / this.MAX_MOVE_STICK);
1621
+ const y = 100 * ((movedY - this.centerY) / this.MAX_MOVE_STICK) * -1;
1622
+ const distance = Math.sqrt(x * x + y * y);
1623
+ if (distance > 20) {
1624
+ this.joyStickPosition.set(x, y);
1625
+ this.isActive = true;
1626
+ }
1627
+ else {
1628
+ this.joyStickPosition.set(0, 0);
1629
+ this.isActive = false;
1630
+ }
1631
+ this.draw();
1632
+ this.moveClock.start();
1633
+ this.update();
1634
+ };
1635
+ this.onPointerUp = (event) => {
1636
+ event.preventDefault();
1637
+ this.pressed = false;
1638
+ this.joyStickPosition.set(0, 0);
1639
+ this.isActive = false;
1640
+ this.moveClock.stop();
1641
+ this.draw();
1642
+ };
1643
+ this.onResize = () => {
1644
+ this.updateVisibility();
1645
+ this.updatePosition();
1646
+ };
1647
+ this.camera = camera;
1648
+ this.canvas = canvasElement;
1649
+ this.moveClock = new Clock(false);
1650
+ this.joyStickPosition = new Vector2(0, 0);
1651
+ this.groundObjects = groundObjects;
1652
+ this.raycaster = new Raycaster();
1653
+ this.raycaster.near = 0;
1654
+ this.raycaster.far = this.EYE_HEIGHT + this.FAILING_DISTANCE;
1655
+ this.centerX = this.CANVAS_SIZE / 2;
1656
+ this.centerY = this.CANVAS_SIZE / 2;
1657
+ this.overlayElement = document.createElement("div");
1658
+ this.overlayElement.id = "joyStickDiv";
1659
+ this.overlayElement.style.background = "rgba(0,0,0,0)";
1660
+ this.overlayElement.style.position = "fixed";
1661
+ this.overlayElement.style.zIndex = "0";
1662
+ this.overlayElement.style.touchAction = "none";
1663
+ document.body.appendChild(this.overlayElement);
1664
+ this.joyStickCanvas = document.createElement("canvas");
1665
+ this.joyStickCanvas.id = "joyStickCanvas";
1666
+ this.joyStickCanvas.width = this.CANVAS_SIZE;
1667
+ this.joyStickCanvas.height = this.CANVAS_SIZE;
1668
+ this.overlayElement.appendChild(this.joyStickCanvas);
1669
+ this.context = this.joyStickCanvas.getContext("2d");
1670
+ this.joyStickCanvas.addEventListener("pointerdown", this.onPointerDown);
1671
+ document.addEventListener("pointermove", this.onPointerMove);
1672
+ document.addEventListener("pointerup", this.onPointerUp);
1673
+ window.addEventListener("resize", this.onResize);
1674
+ document.addEventListener("fullscreenchange", this.onResize);
1675
+ this.updateVisibility();
1676
+ this.updatePosition();
1677
+ this.draw();
1678
+ }
1679
+ dispose() {
1680
+ this.joyStickCanvas.removeEventListener("pointerdown", this.onPointerDown);
1681
+ document.removeEventListener("pointermove", this.onPointerMove);
1682
+ document.removeEventListener("pointerup", this.onPointerUp);
1683
+ window.removeEventListener("resize", this.onResize);
1684
+ document.removeEventListener("fullscreenchange", this.onResize);
1685
+ this.overlayElement.remove();
1686
+ super.dispose();
1687
+ }
1688
+ updateVisibility() {
1689
+ const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
1690
+ const isNarrowScreen = window.innerWidth < 1024;
1691
+ if (isMobile || isNarrowScreen) {
1692
+ this.overlayElement.style.display = "block";
1693
+ }
1694
+ else {
1695
+ this.overlayElement.style.display = "none";
1696
+ }
1697
+ }
1698
+ updatePosition() {
1699
+ const rect = this.canvas.getBoundingClientRect();
1700
+ this.overlayElement.style.top = `${rect.height - this.CANVAS_SIZE}px`;
1701
+ this.overlayElement.style.left = `${rect.left}px`;
1702
+ this.overlayElement.style.width = `${this.CANVAS_SIZE}px`;
1703
+ this.overlayElement.style.height = `${this.CANVAS_SIZE}px`;
1704
+ }
1705
+ draw() {
1706
+ this.context.clearRect(0, 0, this.CANVAS_SIZE, this.CANVAS_SIZE);
1707
+ this.context.beginPath();
1708
+ this.context.arc(this.centerX, this.centerY, this.EXTERNAL_RADIUS, 0, 2 * Math.PI, false);
1709
+ this.context.lineWidth = 2;
1710
+ this.context.strokeStyle = "#35436E";
1711
+ this.context.globalAlpha = 0.5;
1712
+ this.context.stroke();
1713
+ let movedX = this.centerX + (this.joyStickPosition.x * this.MAX_MOVE_STICK) / 100;
1714
+ let movedY = this.centerY - (this.joyStickPosition.y * this.MAX_MOVE_STICK) / 100;
1715
+ movedX = Math.max(this.MAX_MOVE_STICK, Math.min(this.CANVAS_SIZE - this.MAX_MOVE_STICK, movedX));
1716
+ movedY = Math.max(this.MAX_MOVE_STICK, Math.min(this.CANVAS_SIZE - this.MAX_MOVE_STICK, movedY));
1717
+ this.context.beginPath();
1718
+ this.context.arc(movedX, movedY, this.INTERNAL_RADIUS, 0, 2 * Math.PI, false);
1719
+ this.context.fillStyle = "#35436E";
1720
+ this.context.lineWidth = 2;
1721
+ this.context.strokeStyle = "#35436E";
1722
+ this.context.globalAlpha = 0.5;
1723
+ this.context.fill();
1724
+ this.context.stroke();
1725
+ }
1726
+ updateGroundFollowing() {
1727
+ const up = new Vector3().copy(this.camera.up);
1728
+ this.raycaster.set(this.camera.position, up.negate());
1729
+ this.raycaster.params = this.raycaster.params = {
1730
+ Mesh: {},
1731
+ Line: { threshold: 0 },
1732
+ Line2: { threshold: 0 },
1733
+ LOD: { threshold: 0 },
1734
+ Points: { threshold: 0 },
1735
+ Sprite: { threshold: 0 },
1736
+ };
1737
+ const intersects = this.raycaster.intersectObjects(this.groundObjects, false);
1738
+ if (intersects.length > 0) {
1739
+ const groundY = intersects[0].point.y;
1740
+ const targetY = groundY + this.EYE_HEIGHT;
1741
+ this.camera.position.y = MathUtils.lerp(this.camera.position.y, targetY, this.GROUND_FOLLOWING_SPEED);
1742
+ }
1743
+ }
1744
+ update() {
1745
+ if (!this.isActive)
1746
+ return;
1747
+ const forwardInput = this.joyStickPosition.y / this.MAX_JOYSTICK_DISTANCE;
1748
+ const rightInput = this.joyStickPosition.x / this.MAX_JOYSTICK_DISTANCE;
1749
+ const timeDelta = this.moveClock.getDelta();
1750
+ const moveDelta = (timeDelta * this.multiplier * this.movementSpeed) / this.WALK_SPEED_DELIMITER;
1751
+ const forward = new Vector3();
1752
+ const sideways = new Vector3();
1753
+ this.camera.getWorldDirection(forward);
1754
+ if (this.groundObjects.length > 0) {
1755
+ forward.y = 0;
1756
+ }
1757
+ forward.normalize();
1758
+ sideways.setFromMatrixColumn(this.camera.matrix, 0);
1759
+ if (this.groundObjects.length > 0) {
1760
+ sideways.y = 0;
1761
+ }
1762
+ sideways.normalize();
1763
+ if (forwardInput !== 0) {
1764
+ this.camera.position.addScaledVector(forward, moveDelta * forwardInput);
1765
+ }
1766
+ if (rightInput !== 0) {
1767
+ this.camera.position.addScaledVector(sideways, moveDelta * rightInput);
1768
+ }
1769
+ if (forwardInput !== 0 || rightInput !== 0) {
1770
+ if (this.groundObjects.length > 0)
1771
+ this.updateGroundFollowing();
1772
+ this.dispatchEvent({ type: "change" });
1773
+ }
1774
+ }
1775
+ }
1776
+
1583
1777
  class WalkDragger {
1584
1778
  constructor(viewer) {
1585
1779
  this.updateControls = () => {
1586
1780
  const size = this.viewer.extents.getSize(new Vector3());
1587
1781
  this.controls.movementSpeed = Math.min(size.x, size.y, size.z) / 2;
1782
+ this.joyStickControls.movementSpeed = this.controls.movementSpeed;
1783
+ this.joyStickControls.multiplier = this.controls.multiplier;
1588
1784
  };
1589
1785
  this.updateControlsCamera = () => {
1590
1786
  this.controls.object = this.viewer.camera;
@@ -1595,8 +1791,10 @@ class WalkDragger {
1595
1791
  };
1596
1792
  this.walkspeedChange = (event) => {
1597
1793
  this.viewer.emitEvent(event);
1794
+ this.joyStickControls.multiplier = this.controls.multiplier;
1598
1795
  };
1599
1796
  this.viewerRender = () => {
1797
+ this.joyStickControls.update();
1600
1798
  this.controls.update();
1601
1799
  };
1602
1800
  this.viewerZoom = () => {
@@ -1611,6 +1809,8 @@ class WalkDragger {
1611
1809
  this.controls = new WalkControls(viewer.camera, viewer.canvas, meshOnlyGround);
1612
1810
  this.controls.addEventListener("change", this.controlsChange);
1613
1811
  this.controls.addEventListener("walkspeedchange", this.walkspeedChange);
1812
+ this.joyStickControls = new JoyStickControls(viewer.camera, viewer.canvas, viewer.canvas, meshOnlyGround);
1813
+ this.joyStickControls.addEventListener("change", this.controlsChange);
1614
1814
  this.viewer = viewer;
1615
1815
  this.viewer.addEventListener("render", this.viewerRender);
1616
1816
  this.viewer.addEventListener("zoom", this.viewerZoom);
@@ -1624,6 +1824,8 @@ class WalkDragger {
1624
1824
  this.controls.removeEventListener("walkspeedchange", this.walkspeedChange);
1625
1825
  this.controls.removeEventListener("change", this.controlsChange);
1626
1826
  this.controls.dispose();
1827
+ this.joyStickControls.removeEventListener("change", this.controlsChange);
1828
+ this.joyStickControls.dispose();
1627
1829
  }
1628
1830
  }
1629
1831
 
@@ -1779,6 +1981,8 @@ class FlyDragger {
1779
1981
  this.updateControls = () => {
1780
1982
  const size = this.viewer.extents.getSize(new Vector3());
1781
1983
  this.controls.movementSpeed = Math.min(size.x, size.y, size.z) / 2;
1984
+ this.joyStickControls.movementSpeed = this.controls.movementSpeed;
1985
+ this.joyStickControls.multiplier = this.controls.multiplier;
1782
1986
  };
1783
1987
  this.updateControlsCamera = () => {
1784
1988
  this.controls.object = this.viewer.camera;
@@ -1789,8 +1993,10 @@ class FlyDragger {
1789
1993
  };
1790
1994
  this.flyspeedChange = (event) => {
1791
1995
  this.viewer.emitEvent(event);
1996
+ this.joyStickControls.multiplier = this.controls.multiplier;
1792
1997
  };
1793
1998
  this.viewerRender = () => {
1999
+ this.joyStickControls.update();
1794
2000
  this.controls.update();
1795
2001
  };
1796
2002
  this.viewerZoom = () => {
@@ -1799,6 +2005,8 @@ class FlyDragger {
1799
2005
  this.controls = new FlyControls(viewer.camera, viewer.canvas);
1800
2006
  this.controls.addEventListener("change", this.controlsChange);
1801
2007
  this.controls.addEventListener("flyspeedchange", this.flyspeedChange);
2008
+ this.joyStickControls = new JoyStickControls(viewer.camera, viewer.canvas, viewer.canvas, []);
2009
+ this.joyStickControls.addEventListener("change", this.controlsChange);
1802
2010
  this.viewer = viewer;
1803
2011
  this.viewer.addEventListener("render", this.viewerRender);
1804
2012
  this.viewer.addEventListener("zoom", this.viewerZoom);
@@ -1812,6 +2020,8 @@ class FlyDragger {
1812
2020
  this.controls.removeEventListener("flyspeedchange", this.flyspeedChange);
1813
2021
  this.controls.removeEventListener("change", this.controlsChange);
1814
2022
  this.controls.dispose();
2023
+ this.joyStickControls.removeEventListener("change", this.controlsChange);
2024
+ this.joyStickControls.dispose();
1815
2025
  }
1816
2026
  }
1817
2027