@cocorof/graphier 1.2.0 → 1.3.0

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/index.js CHANGED
@@ -34,8 +34,8 @@ function hexToRgb(hex) {
34
34
  return [(n >> 16) / 255, (n >> 8 & 255) / 255, (n & 255) / 255];
35
35
  }
36
36
  function rgbToHex(r, g, b) {
37
- const clamp2 = (v) => Math.round(Math.max(0, Math.min(1, v)) * 255);
38
- const hex = clamp2(r) << 16 | clamp2(g) << 8 | clamp2(b);
37
+ const clamp = (v) => Math.round(Math.max(0, Math.min(1, v)) * 255);
38
+ const hex = clamp(r) << 16 | clamp(g) << 8 | clamp(b);
39
39
  return "#" + hex.toString(16).padStart(6, "0");
40
40
  }
41
41
  function brighten(hex, factor) {
@@ -1954,61 +1954,45 @@ function disposeLabelSystem(state) {
1954
1954
  }
1955
1955
  state.textureCache.clear();
1956
1956
  }
1957
- const ORBIT_ACCEL = 12e-4;
1958
- const ORBIT_MAX_SPEED = 0.06;
1959
- const ORBIT_DAMPING = 0.88;
1957
+ const ORBIT_ROTATE_SPEED = 0.02;
1960
1958
  const ORBIT_ZOOM_FACTOR = 0.015;
1961
- const ORBIT_DEAD_ZONE = 1e-4;
1962
- const FLY_ACCEL = 6e-3;
1963
- const FLY_FRICTION = 0.92;
1964
- const FLY_MAX_THRUST = 0.18;
1959
+ const FLY_THRUST_SPEED = 0.08;
1965
1960
  const FLY_TURN_RATE = 8e-3;
1966
- const FLY_DEAD_ZONE = 2e-4;
1967
1961
  const _offset = new THREE.Vector3();
1968
1962
  const _right = new THREE.Vector3();
1969
1963
  const _q = new THREE.Quaternion();
1970
1964
  const _dir = new THREE.Vector3();
1971
1965
  const _worldUp = new THREE.Vector3(0, 1, 0);
1972
- function clamp(v, min, max) {
1973
- return v < min ? min : v > max ? max : v;
1974
- }
1975
1966
  function createOrbitUpdate(camera, controls, keys) {
1976
- const vel = { zoom: 0, azimuth: 0, polar: 0 };
1977
1967
  return function update() {
1978
- if (keys["z"] || keys["Z"]) vel.zoom -= ORBIT_ACCEL;
1979
- if (keys["x"] || keys["X"]) vel.zoom += ORBIT_ACCEL;
1980
- if (keys["ArrowLeft"]) vel.azimuth -= ORBIT_ACCEL;
1981
- if (keys["ArrowRight"]) vel.azimuth += ORBIT_ACCEL;
1982
- if (keys["ArrowUp"]) vel.polar -= ORBIT_ACCEL;
1983
- if (keys["ArrowDown"]) vel.polar += ORBIT_ACCEL;
1984
- vel.zoom = clamp(vel.zoom, -ORBIT_MAX_SPEED, ORBIT_MAX_SPEED);
1985
- vel.azimuth = clamp(vel.azimuth, -ORBIT_MAX_SPEED, ORBIT_MAX_SPEED);
1986
- vel.polar = clamp(vel.polar, -ORBIT_MAX_SPEED, ORBIT_MAX_SPEED);
1987
- vel.zoom *= ORBIT_DAMPING;
1988
- vel.azimuth *= ORBIT_DAMPING;
1989
- vel.polar *= ORBIT_DAMPING;
1990
- if (Math.abs(vel.zoom) < ORBIT_DEAD_ZONE) vel.zoom = 0;
1991
- if (Math.abs(vel.azimuth) < ORBIT_DEAD_ZONE) vel.azimuth = 0;
1992
- if (Math.abs(vel.polar) < ORBIT_DEAD_ZONE) vel.polar = 0;
1993
- const hasMotion = vel.zoom !== 0 || vel.azimuth !== 0 || vel.polar !== 0;
1968
+ let zoom = 0;
1969
+ let azimuth = 0;
1970
+ let polar = 0;
1971
+ if (keys["z"] || keys["Z"]) zoom -= ORBIT_ROTATE_SPEED;
1972
+ if (keys["x"] || keys["X"]) zoom += ORBIT_ROTATE_SPEED;
1973
+ if (keys["ArrowLeft"]) azimuth -= ORBIT_ROTATE_SPEED;
1974
+ if (keys["ArrowRight"]) azimuth += ORBIT_ROTATE_SPEED;
1975
+ if (keys["ArrowUp"]) polar -= ORBIT_ROTATE_SPEED;
1976
+ if (keys["ArrowDown"]) polar += ORBIT_ROTATE_SPEED;
1977
+ const hasMotion = zoom !== 0 || azimuth !== 0 || polar !== 0;
1994
1978
  if (!hasMotion) return false;
1995
1979
  const target = controls.target;
1996
1980
  _offset.copy(camera.position).sub(target);
1997
1981
  let radius = _offset.length();
1998
- if (vel.zoom !== 0) {
1999
- radius *= 1 + vel.zoom * ORBIT_ZOOM_FACTOR * radius * 0.01;
1982
+ if (zoom !== 0) {
1983
+ radius *= 1 + zoom * ORBIT_ZOOM_FACTOR * radius * 0.01;
2000
1984
  radius = Math.max(controls.minDistance, Math.min(controls.maxDistance, radius));
2001
1985
  }
2002
- if (vel.azimuth !== 0) {
2003
- _q.setFromAxisAngle(camera.up, -vel.azimuth);
1986
+ if (azimuth !== 0) {
1987
+ _q.setFromAxisAngle(camera.up, -azimuth);
2004
1988
  _offset.applyQuaternion(_q);
2005
1989
  }
2006
- if (vel.polar !== 0) {
1990
+ if (polar !== 0) {
2007
1991
  _right.copy(_offset).normalize().cross(camera.up).normalize();
2008
1992
  if (_right.lengthSq() < 1e-3) {
2009
1993
  _right.setFromMatrixColumn(camera.matrixWorld, 0);
2010
1994
  }
2011
- _q.setFromAxisAngle(_right, vel.polar);
1995
+ _q.setFromAxisAngle(_right, polar);
2012
1996
  _offset.applyQuaternion(_q);
2013
1997
  camera.up.applyQuaternion(_q).normalize();
2014
1998
  }
@@ -2020,44 +2004,37 @@ function createOrbitUpdate(camera, controls, keys) {
2020
2004
  };
2021
2005
  }
2022
2006
  function createFlyUpdate(camera, controls, keys, state) {
2023
- const vel = { thrust: 0, yaw: 0, pitch: 0 };
2024
2007
  return function update() {
2025
2008
  const speedMul = state.flySpeed;
2026
- if (keys["z"] || keys["Z"]) vel.thrust += FLY_ACCEL * speedMul;
2027
- if (keys["x"] || keys["X"]) vel.thrust -= FLY_ACCEL * speedMul;
2028
- if (keys["a"] || keys["A"] || keys["ArrowLeft"]) vel.yaw += FLY_TURN_RATE;
2029
- if (keys["d"] || keys["D"] || keys["ArrowRight"]) vel.yaw -= FLY_TURN_RATE;
2030
- if (keys["w"] || keys["W"] || keys["ArrowUp"]) vel.pitch += FLY_TURN_RATE;
2031
- if (keys["s"] || keys["S"] || keys["ArrowDown"]) vel.pitch -= FLY_TURN_RATE;
2032
- const lookDist = camera.position.distanceTo(controls.target);
2033
- const distScale = Math.max(0.3, lookDist * 3e-3);
2034
- vel.thrust = clamp(vel.thrust, -FLY_MAX_THRUST * distScale * speedMul, FLY_MAX_THRUST * distScale * speedMul);
2035
- vel.yaw = clamp(vel.yaw, -FLY_TURN_RATE * 2, FLY_TURN_RATE * 2);
2036
- vel.pitch = clamp(vel.pitch, -FLY_TURN_RATE * 2, FLY_TURN_RATE * 2);
2037
- vel.thrust *= FLY_FRICTION;
2038
- vel.yaw *= FLY_FRICTION;
2039
- vel.pitch *= FLY_FRICTION;
2040
- if (Math.abs(vel.thrust) < FLY_DEAD_ZONE) vel.thrust = 0;
2041
- if (Math.abs(vel.yaw) < FLY_DEAD_ZONE) vel.yaw = 0;
2042
- if (Math.abs(vel.pitch) < FLY_DEAD_ZONE) vel.pitch = 0;
2043
- const hasMotion = vel.thrust !== 0 || vel.yaw !== 0 || vel.pitch !== 0;
2009
+ let thrust = 0;
2010
+ let yaw = 0;
2011
+ let pitch = 0;
2012
+ if (keys["z"] || keys["Z"]) thrust += FLY_THRUST_SPEED * speedMul;
2013
+ if (keys["x"] || keys["X"]) thrust -= FLY_THRUST_SPEED * speedMul;
2014
+ if (keys["a"] || keys["A"] || keys["ArrowLeft"]) yaw += FLY_TURN_RATE;
2015
+ if (keys["d"] || keys["D"] || keys["ArrowRight"]) yaw -= FLY_TURN_RATE;
2016
+ if (keys["w"] || keys["W"] || keys["ArrowUp"]) pitch += FLY_TURN_RATE;
2017
+ if (keys["s"] || keys["S"] || keys["ArrowDown"]) pitch -= FLY_TURN_RATE;
2018
+ const hasMotion = thrust !== 0 || yaw !== 0 || pitch !== 0;
2044
2019
  if (!hasMotion) return false;
2045
- if (vel.yaw !== 0) {
2020
+ if (yaw !== 0) {
2046
2021
  const upDot = camera.up.dot(_worldUp);
2047
2022
  const yawSign = upDot < 0 ? -1 : 1;
2048
- _q.setFromAxisAngle(_worldUp, vel.yaw * yawSign);
2023
+ _q.setFromAxisAngle(_worldUp, yaw * yawSign);
2049
2024
  camera.quaternion.premultiply(_q);
2050
2025
  camera.up.applyQuaternion(_q).normalize();
2051
2026
  }
2052
- if (vel.pitch !== 0) {
2027
+ if (pitch !== 0) {
2053
2028
  _right.setFromMatrixColumn(camera.matrixWorld, 0).normalize();
2054
- _q.setFromAxisAngle(_right, vel.pitch);
2029
+ _q.setFromAxisAngle(_right, pitch);
2055
2030
  camera.quaternion.premultiply(_q);
2056
2031
  camera.up.applyQuaternion(_q).normalize();
2057
2032
  }
2058
- if (vel.thrust !== 0) {
2033
+ if (thrust !== 0) {
2034
+ const lookDist = camera.position.distanceTo(controls.target);
2035
+ const distScale = Math.max(0.3, lookDist * 3e-3);
2059
2036
  camera.getWorldDirection(_dir);
2060
- _dir.multiplyScalar(vel.thrust * distScale * 100);
2037
+ _dir.multiplyScalar(thrust * distScale * 100);
2061
2038
  camera.position.add(_dir);
2062
2039
  controls.target.add(_dir);
2063
2040
  }
@@ -2130,6 +2107,21 @@ function createScene(container, backgroundColor, style, rendererConfig) {
2130
2107
  scene.add(labels.group);
2131
2108
  const cameraMode = (rendererConfig == null ? void 0 : rendererConfig.cameraMode) ?? "fly";
2132
2109
  const keyboard = setupKeyboardControls(camera, controls, container, cameraMode, style.flySpeed ?? 1);
2110
+ controls.enableZoom = false;
2111
+ const _wheelDir = new THREE.Vector3();
2112
+ const onWheel = (e) => {
2113
+ e.preventDefault();
2114
+ let delta = -e.deltaY;
2115
+ if (e.deltaMode === 1) delta *= 40;
2116
+ if (e.deltaMode === 2) delta *= 800;
2117
+ camera.getWorldDirection(_wheelDir);
2118
+ const dist = camera.position.distanceTo(controls.target);
2119
+ const moveAmount = delta * 2e-3 * Math.max(dist * 0.1, 1);
2120
+ camera.position.addScaledVector(_wheelDir, moveAmount);
2121
+ controls.target.addScaledVector(_wheelDir, moveAmount);
2122
+ };
2123
+ canvas.addEventListener("wheel", onWheel, { passive: false });
2124
+ const scrollCleanup = () => canvas.removeEventListener("wheel", onWheel);
2133
2125
  return {
2134
2126
  scene,
2135
2127
  camera,
@@ -2140,7 +2132,8 @@ function createScene(container, backgroundColor, style, rendererConfig) {
2140
2132
  labels,
2141
2133
  composer: null,
2142
2134
  bloomPass: null,
2143
- keyboard
2135
+ keyboard,
2136
+ scrollCleanup
2144
2137
  };
2145
2138
  }
2146
2139
  function initBloom(state, nodeCount, style) {
@@ -2167,9 +2160,21 @@ function initBloom(state, nodeCount, style) {
2167
2160
  }
2168
2161
  function startAnimationLoop(state, onTick) {
2169
2162
  let animFrame;
2163
+ let wasKeyboardActive = false;
2164
+ const _syncDir = new THREE.Vector3();
2170
2165
  function animate() {
2171
2166
  animFrame = requestAnimationFrame(animate);
2172
2167
  const keyboardActive = state.keyboard.update();
2168
+ if (wasKeyboardActive && !keyboardActive) {
2169
+ const dist = state.camera.position.distanceTo(
2170
+ state.controls.target
2171
+ );
2172
+ state.camera.getWorldDirection(_syncDir);
2173
+ state.controls.target.copy(state.camera.position).add(_syncDir.multiplyScalar(dist));
2174
+ state.camera.up.set(0, 1, 0);
2175
+ state.camera.lookAt(state.controls.target);
2176
+ }
2177
+ wasKeyboardActive = keyboardActive;
2173
2178
  if (!keyboardActive) state.controls.update();
2174
2179
  if (state.selectionRing.visible) {
2175
2180
  state.selectionRing.quaternion.copy(state.camera.quaternion);
@@ -2970,6 +2975,7 @@ function NetworkGraph3DInner(props, ref) {
2970
2975
  resizeObserver.disconnect();
2971
2976
  interaction.cleanup();
2972
2977
  state.keyboard.cleanup();
2978
+ state.scrollCleanup();
2973
2979
  state.controls.dispose();
2974
2980
  disposeObject(state.stars);
2975
2981
  disposeObject(state.selectionRing);