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
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 5m54s
This commit is contained in:
+18
-19
@@ -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"
|
||||||
|
|||||||
Reference in New Issue
Block a user