feat(tasarim): şehir haritası yüklenince ile doğru yakınlaşır

- viewBox 0,7 s gecikmeyle 1,1 s güçlü ease-out ile ilin çevresindeki kutuya
  kayar (en çok 2,4 kat; ülke haritasında şehir işaretine 1,8 kat); kutu SVG
  oranında ve harita dışına taşmaz. Hareketi azalt: doğrudan odak.
- usePixelHeat viewBox'ı her taramada canlı okur; yakınlaşmış haritada da
  imleç doğru kareyi ısıtır (hero davranışı değişmez).
- DESIGN.md §4.17 yakınlaşma notu.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
bilalgursen
2026-09-24 15:02:28 +03:00
parent eefac56659
commit 6e057aa0f5
3 changed files with 110 additions and 19 deletions

View File

@@ -36,7 +36,6 @@ type HeatTarget = {
type HeatInstance = {
svg: SVGSVGElement;
viewW: number;
radius: number;
baseColor: string;
pixels: HeatTarget[];
@@ -65,7 +64,12 @@ function tara() {
for (const inst of instances) {
const rect = inst.svg.getBoundingClientRect();
if (rect.width === 0) continue;
const scale = rect.width / inst.viewW;
// viewBox her taramada okunur: şehir haritası (sehir-piksel-haritasi.tsx)
// yüklendikten sonra ile doğru yakınlaşır; kutunun oranı SVG'ninkiyle
// aynı tutulduğu için ölçek = genişlik oranı, orijin = viewBox.x/y.
const vb = inst.svg.viewBox.baseVal;
if (!vb.width) continue;
const scale = rect.width / vb.width;
const pad = inst.radius * scale;
// İmleç fırça menzilinin tamamen dışındaysa ve sıcak piksel yoksa
// bu örnek için hiç hesap yapma
@@ -78,8 +82,8 @@ function tara() {
) {
continue;
}
const x = (e.clientX - rect.left) / scale;
const y = (e.clientY - rect.top) / scale;
const x = vb.x + (e.clientX - rect.left) / scale;
const y = vb.y + (e.clientY - rect.top) / scale;
for (const p of inst.pixels) {
const d2 = (p.cx - x) ** 2 + (p.cy - y) ** 2;
const isHot = d2 <= inst.radius * inst.radius;
@@ -140,8 +144,7 @@ export function usePixelHeat(
// Dokunmatik cihazlarda hover yanlış tetiklenir; efekti imleçli cihazlara sakla
if (!window.matchMedia(FINE_POINTER_QUERY).matches) return;
const viewW = svg.viewBox.baseVal.width;
if (!viewW) return;
if (!svg.viewBox.baseVal.width) return;
const pixels: HeatTarget[] = Array.from(
svg.querySelectorAll<SVGRectElement>("[data-px]"),
@@ -155,7 +158,6 @@ export function usePixelHeat(
const inst: HeatInstance = {
svg,
viewW,
radius,
baseColor: getComputedStyle(svg).color,
pixels,