feat: Refine zoom functionality in GraphView by enforcing zoom limits and optimizing flag rendering for improved performance and visual consistency
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 5m54s

This commit is contained in:
2025-08-08 17:03:56 +07:00
parent 8ea6f9526e
commit 08cf7f806c
+18 -19
View File
@@ -97,17 +97,18 @@ function GraphView({ servers, connections }) {
const current = d3.zoomTransform(svgEl); const current = d3.zoomTransform(svgEl);
const cx = svgEl.clientWidth / 2; const cx = svgEl.clientWidth / 2;
const cy = svgEl.clientHeight / 2; const cy = svgEl.clientHeight / 2;
dbg('zoomBy click', { factor, current: { k: current.k, x: current.x, y: current.y }, center: { cx, cy } }); const minK = 0.3;
const next = d3.zoomIdentity const maxK = 3;
.translate(current.x, current.y) let nextK = current.k * factor;
.scale(current.k) if (nextK < minK) nextK = minK;
.translate(cx, cy) if (nextK > maxK) nextK = maxK;
.scale(factor) dbg('zoomBy click', { factor, current: { k: current.k, x: current.x, y: current.y }, nextK, center: { cx, cy } });
.translate(-cx, -cy); const svgSel = d3.select(svgEl);
d3.select(svgEl) svgSel.interrupt();
svgSel
.transition() .transition()
.duration(220) .duration(220)
.call(zoomRef.current.transform, next) .call(zoomRef.current.scaleTo, nextK, [cx, cy])
.on('end', () => { .on('end', () => {
const nt = d3.zoomTransform(svgEl); const nt = d3.zoomTransform(svgEl);
dbg('zoomBy end', { next: { k: nt.k, x: nt.x, y: nt.y } }); dbg('zoomBy end', { next: { k: nt.k, x: nt.x, y: nt.y } });
@@ -459,17 +460,15 @@ function GraphView({ servers, connections }) {
fill="#fff" fill="#fff"
stroke={countryColor} stroke={countryColor}
/> />
{/* Рендер флага через foreignObject как в HTML (надёжнее для Windows/Chrome) */}
<foreignObject x={badgeX + 4} y={badgeY + 3} width={16} height={14} style={{ pointerEvents: 'none' }}>
<div xmlns="http://www.w3.org/1999/xhtml"
style={{fontSize:'14px', lineHeight:'14px', fontFamily:'Segoe UI Emoji, Noto Color Emoji, Apple Color Emoji, "Twemoji Mozilla", "EmojiOne Color", sans-serif'}}>
{flag}
</div>
</foreignObject>
<text <text
x={badgeX + 10} x={badgeX + 30}
y={badgeY + 13}
fontSize="14"
dominantBaseline="middle"
style={{ fontFamily: 'Segoe UI Emoji, Noto Color Emoji, Apple Color Emoji, "Twemoji Mozilla", "EmojiOne Color", sans-serif' }}
>
{flag}
</text>
<text
x={badgeX + 28}
y={badgeY + 13} y={badgeY + 13}
fontSize="11" fontSize="11"
fill="#475569" fill="#475569"