@inweb/viewer-three 26.10.3 → 26.10.4

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