@@ -309,26 +309,39 @@ class _DraggableThumbnailState extends State<DraggableThumbnail> {
309309 child: GestureDetector (
310310 onTap: widget.onTap,
311311 onPanStart: (details) {
312+ // Sync state with actual render position before starting the drag
313+ final startRect = _findCallCardRect ();
312314 setState (() {
315+ _offset = startRect.topLeft;
313316 _callCardPanning = true ;
314317 });
315318 },
316319 onPanUpdate: (details) {
317- final callCardRect = _findCallCardRect (details.delta);
318- final translateX = _boundTranslateX (_activeRect, callCardRect);
319- final translateY = _boundTranslateY (_activeRect, callCardRect);
320- final offset = callCardRect.translate (translateX, translateY).topLeft;
320+ if (_offset == null ) return ;
321321
322- widget.onOffsetUpdate? .call (offset);
322+ // Calculate new position based on state + delta (ignoring render lag)
323+ final currentSize = _callCardKey.currentContext? .size ?? Size .zero;
324+ final tentativeOffset = _offset! + details.delta;
325+ final tentativeRect = tentativeOffset & currentSize;
326+
327+ final translateX = _boundTranslateX (_activeRect, tentativeRect);
328+ final translateY = _boundTranslateY (_activeRect, tentativeRect);
329+
330+ final finalOffset = tentativeRect.translate (translateX, translateY).topLeft;
331+
332+ widget.onOffsetUpdate? .call (finalOffset);
323333 setState (() {
324- _offset = offset ;
334+ _offset = finalOffset ;
325335 });
326336 },
327337 onPanEnd: (details) {
328- final callCardRect = _findCallCardRect ();
329- final translateX = _stickTranslateX (_stickyRect, callCardRect);
330- final translateY = _boundTranslateY (_stickyRect, callCardRect);
331- final offset = callCardRect.translate (translateX, translateY).topLeft;
338+ // Calculate snapping based on the final dragged position
339+ final currentSize = _callCardKey.currentContext? .size ?? Size .zero;
340+ final currentRect = (_offset ?? Offset .zero) & currentSize;
341+
342+ final translateX = _stickTranslateX (_stickyRect, currentRect);
343+ final translateY = _boundTranslateY (_stickyRect, currentRect);
344+ final offset = currentRect.translate (translateX, translateY).topLeft;
332345
333346 widget.onOffsetUpdate? .call (offset);
334347 setState (() {
@@ -341,11 +354,15 @@ class _DraggableThumbnailState extends State<DraggableThumbnail> {
341354 );
342355 }
343356
344- Rect _findCallCardRect ([Offset delta = Offset .zero]) {
345- final callCardRenderBox = _callCardKey.currentContext? .findRenderObject ()! as RenderBox ;
346- final offset = callCardRenderBox.localToGlobal (Offset .zero) + delta;
357+ Rect _findCallCardRect () {
358+ final callCardContext = _callCardKey.currentContext;
359+ if (callCardContext == null ) return Rect .zero;
360+
361+ final callCardRenderBox = callCardContext.findRenderObject () as RenderBox ? ;
362+ if (callCardRenderBox == null || ! callCardRenderBox.hasSize) return Rect .zero;
363+
364+ final offset = callCardRenderBox.localToGlobal (Offset .zero);
347365 final size = callCardRenderBox.size;
348- if (! callCardRenderBox.hasSize) return Rect .zero;
349366
350367 return Rect .fromLTWH (offset.dx, offset.dy, size.width, size.height);
351368 }
0 commit comments