# ImajViewer — Pan Sınırlama & Zoom Merkezi Sorunu ✅ ÇÖZÜLDÜ > **Tarih:** 2026-07-23 > **Dosya:** `lib/widgets/image_canvas.dart` > **Durum:** ✅ Çözüldü --- ## Nihai Çözüm ### 1. Zoom — `Matrix4.copy(m)..translate..scale..translate` Cursor merkezli zoomAroundPoint. Hem fill hem fit modunda çalışır çünkü `localPosition` her zaman Listener'a göre doğru koordinat verir. `_currentScale` listener'da güncellenir. ### 2. `_clampAfterZoom` — Image offset + sadece boundary clamp **Kritik:** Fit modunda (BoxFit.contain) Image, Center widget içinde **ortalanır**. Offset hesaplanarak image'ın viewport'taki gerçek sınırları bulunur: ```dart imgOffsetX = (viewportW - imageW) / 2 // fill modunda 0, fit modunda >0 imgLeft = tx + imgOffsetX * scale imgRight = tx + (imgOffsetX + imageW) * scale ``` **SADECE** image viewport'tan büyükse clamp yapılır. Küçükse **dokunulmaz** — zoom-around-point merkezi korunur. Kullanıcı double-tap ile istediği zaman ortalamayı sıfırlayabilir (`Matrix4.identity()`). ### 3. `translate` — asla `setTranslationRaw` kullanma `setTranslationRaw` matrisin translation sütununu ezer → zoom merkezini bozar. `translate(dx,dy)` ekleme yapar → zoom merkezi korunur. ### 4. Listener'da clamp YOK Sadece `_currentScale` takip edilir. Pan → `boundaryMargin: EdgeInsets.zero`, Zoom → `_handleScroll` içinde `_clampAfterZoom`. --- ## Akış ``` Scroll → _handleScroll → zoomAroundPoint → _controller.value ↓ _clampAfterZoom() ├─ image > viewport → translate ile clamp └─ image ≤ viewport → dokunma Pan → InteractiveViewer → _controller.value (boundaryMargin sınırlar) ↓ _onTransformChanged → sadece _currentScale ```