@andespindola/brainlink 0.1.0-beta.70 → 0.1.0-beta.72
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.
|
@@ -8,6 +8,8 @@ const renderEdgeBudget = 2400
|
|
|
8
8
|
const clusterActivationNodeThreshold = 600
|
|
9
9
|
const clusterZoomThreshold = 0.18
|
|
10
10
|
const macroGalaxyZoomThreshold = 0.012
|
|
11
|
+
const macroGalaxyEnterHysteresis = 0.86
|
|
12
|
+
const macroGalaxyExitHysteresis = 1.24
|
|
11
13
|
const massiveAutoFitMacroScale = 0.006
|
|
12
14
|
const defaultMacroScale = 0.006
|
|
13
15
|
const clusterCellPixelSize = 64
|
|
@@ -25,6 +27,9 @@ const meshEdgeMaxBudget = 1400
|
|
|
25
27
|
const layeredCoreScaleThreshold = 0.55
|
|
26
28
|
const dragNeighborhoodMaxAffected = 180
|
|
27
29
|
const dragSettleRounds = 3
|
|
30
|
+
const wheelZoomExponent = 0.0018
|
|
31
|
+
const wheelZoomExponentCap = 0.09
|
|
32
|
+
const wheelZoomModifierBoost = 1.22
|
|
28
33
|
const state = {
|
|
29
34
|
graph: { nodes: [], edges: [] },
|
|
30
35
|
nodes: [],
|
|
@@ -65,7 +70,8 @@ const state = {
|
|
|
65
70
|
filterReady: false,
|
|
66
71
|
lastHoverHitAt: 0,
|
|
67
72
|
lastManualZoomAt: 0,
|
|
68
|
-
lastZoomFocus: { x: 0, y: 0, at: 0 }
|
|
73
|
+
lastZoomFocus: { x: 0, y: 0, at: 0 },
|
|
74
|
+
macroViewActive: false
|
|
69
75
|
}
|
|
70
76
|
|
|
71
77
|
const byId = id => document.getElementById(id)
|
|
@@ -662,6 +668,29 @@ const viewportCenterWorldPoint = () => {
|
|
|
662
668
|
}
|
|
663
669
|
}
|
|
664
670
|
|
|
671
|
+
const visibilityScaleBucket = (scale) => {
|
|
672
|
+
const safeScale = Math.max(zoomRange.min, scale)
|
|
673
|
+
if (safeScale < 0.01) return Math.round(safeScale * 300_000)
|
|
674
|
+
if (safeScale < 0.05) return Math.round(safeScale * 120_000)
|
|
675
|
+
if (safeScale < 0.2) return Math.round(safeScale * 40_000)
|
|
676
|
+
return Math.round(safeScale * 8_000)
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
const shouldRenderMacroGalaxyView = () => {
|
|
680
|
+
if (state.visibleNodes.length <= 1) {
|
|
681
|
+
state.macroViewActive = false
|
|
682
|
+
return false
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
const enterThreshold = macroGalaxyZoomThreshold * macroGalaxyEnterHysteresis
|
|
686
|
+
const exitThreshold = macroGalaxyZoomThreshold * macroGalaxyExitHysteresis
|
|
687
|
+
const shouldRender = state.macroViewActive
|
|
688
|
+
? state.transform.scale <= exitThreshold
|
|
689
|
+
: state.transform.scale <= enterThreshold
|
|
690
|
+
state.macroViewActive = shouldRender
|
|
691
|
+
return shouldRender
|
|
692
|
+
}
|
|
693
|
+
|
|
665
694
|
const mergeUniqueNodes = (leftNodes, rightNodes, limit) => {
|
|
666
695
|
const merged = []
|
|
667
696
|
const ids = new Set()
|
|
@@ -1733,7 +1762,7 @@ const computeRenderVisibility = () => {
|
|
|
1733
1762
|
Math.round(viewport.maxX * 10) + ':' +
|
|
1734
1763
|
Math.round(viewport.minY * 10) + ':' +
|
|
1735
1764
|
Math.round(viewport.maxY * 10) + ':' +
|
|
1736
|
-
|
|
1765
|
+
visibilityScaleBucket(state.transform.scale)
|
|
1737
1766
|
|
|
1738
1767
|
if (!state.renderVisibilityDirty && viewportKey === state.lastViewportKey) {
|
|
1739
1768
|
return
|
|
@@ -1741,8 +1770,7 @@ const computeRenderVisibility = () => {
|
|
|
1741
1770
|
state.lastViewportKey = viewportKey
|
|
1742
1771
|
state.renderVisibilityDirty = false
|
|
1743
1772
|
|
|
1744
|
-
const shouldRenderMacroGalaxy =
|
|
1745
|
-
state.transform.scale <= macroGalaxyZoomThreshold && state.visibleNodes.length > 1
|
|
1773
|
+
const shouldRenderMacroGalaxy = shouldRenderMacroGalaxyView()
|
|
1746
1774
|
|
|
1747
1775
|
if (shouldRenderMacroGalaxy) {
|
|
1748
1776
|
const viewportNodes = viewportNodesFromSpatialIndex(viewport)
|
|
@@ -1797,10 +1825,19 @@ const computeRenderVisibility = () => {
|
|
|
1797
1825
|
selectAccessBridgeNodes(sourceWithCarry, bridgeLimit),
|
|
1798
1826
|
Math.min(renderNodeBudget, sampleLimit + bridgeLimit)
|
|
1799
1827
|
)
|
|
1800
|
-
const
|
|
1828
|
+
const sampledRaw = selectStableSampleNodes(
|
|
1801
1829
|
bridgedNodes,
|
|
1802
1830
|
Math.min(sampleLimit, renderNodeBudget)
|
|
1803
1831
|
)
|
|
1832
|
+
const continuityBudget = Math.max(24, Math.min(sampleLimit - 8, Math.floor(sampleLimit * 0.42)))
|
|
1833
|
+
const previousVisibleNodes = (state.renderNodes ?? [])
|
|
1834
|
+
.filter((node) => sourceWithCarry.some((candidate) => candidate.id === node.id))
|
|
1835
|
+
const continuityNodes = selectStableSampleNodes(previousVisibleNodes, continuityBudget)
|
|
1836
|
+
const sampled = mergeUniqueNodes(
|
|
1837
|
+
continuityNodes,
|
|
1838
|
+
sampledRaw,
|
|
1839
|
+
Math.min(sampleLimit, renderNodeBudget)
|
|
1840
|
+
)
|
|
1804
1841
|
const sampledIds = new Set(sampled.map((node) => node.id))
|
|
1805
1842
|
let sampledEdges = state.transform.scale >= 0.035 ? collectVisibleEdgesForNodes(sampledIds) : []
|
|
1806
1843
|
let sampledNodes = ensureHubNodesInRenderedSet(sampled)
|
|
@@ -2184,16 +2221,18 @@ const zoomAtPoint = (screenX, screenY, factor, source = 'generic') => {
|
|
|
2184
2221
|
const wheelZoomFactor = event => {
|
|
2185
2222
|
const isModifierZoom = event.metaKey || event.ctrlKey
|
|
2186
2223
|
const deltaModeFactor = event.deltaMode === 1 ? 16 : event.deltaMode === 2 ? 120 : 1
|
|
2187
|
-
const
|
|
2224
|
+
const normalizedDelta = event.deltaY * deltaModeFactor
|
|
2188
2225
|
|
|
2189
|
-
if (
|
|
2226
|
+
if (!Number.isFinite(normalizedDelta) || Math.abs(normalizedDelta) <= 0.0001) {
|
|
2190
2227
|
return 1
|
|
2191
2228
|
}
|
|
2192
2229
|
|
|
2193
|
-
const
|
|
2194
|
-
const
|
|
2195
|
-
|
|
2196
|
-
|
|
2230
|
+
const sensitivity = wheelZoomExponent * (isModifierZoom ? wheelZoomModifierBoost : 1)
|
|
2231
|
+
const exponent = Math.max(
|
|
2232
|
+
-wheelZoomExponentCap,
|
|
2233
|
+
Math.min(wheelZoomExponentCap, -normalizedDelta * sensitivity)
|
|
2234
|
+
)
|
|
2235
|
+
return Math.exp(exponent)
|
|
2197
2236
|
}
|
|
2198
2237
|
|
|
2199
2238
|
const handleWheelZoom = event => {
|
package/package.json
CHANGED