@@ -179,11 +179,16 @@ function observePosition(el: Element) {
179179/**
180180 * Update the exact position of a given element.
181181 * @param el - An element to update the position of.
182+ * @param debounce - Whether or not to debounce the update. After an animation is finished, it should update as soon as possible to prevent flickering on quick toggles.
182183 */
183- function updatePos ( el : Element ) {
184+ function updatePos ( el : Element , debounce = true ) {
184185 clearTimeout ( debounces . get ( el ) )
185186 const optionsOrPlugin = getOptions ( el )
186- const delay = isPlugin ( optionsOrPlugin ) ? 500 : optionsOrPlugin . duration
187+ const delay = debounce
188+ ? isPlugin ( optionsOrPlugin )
189+ ? 500
190+ : optionsOrPlugin . duration
191+ : 0
187192 debounces . set (
188193 el ,
189194 setTimeout ( async ( ) => {
@@ -357,7 +362,8 @@ function animate(el: Element) {
357362 const isMounted = el . isConnected
358363 const preExisting = coords . has ( el )
359364 if ( isMounted && siblings . has ( el ) ) siblings . delete ( el )
360- if ( animations . has ( el ) ) {
365+
366+ if ( animations . get ( el ) ?. playState !== "finished" ) {
361367 animations . get ( el ) ?. cancel ( )
362368 }
363369 if ( NEW in el ) {
@@ -540,15 +546,24 @@ function remain(el: Element) {
540546 if ( ! oldCoords ) return
541547 const pluginOrOptions = getOptions ( el )
542548 if ( typeof pluginOrOptions !== "function" ) {
543- const deltaX = oldCoords . left - newCoords . left
544- const deltaY = oldCoords . top - newCoords . top
549+ let deltaLeft = oldCoords . left - newCoords . left
550+ let deltaTop = oldCoords . top - newCoords . top
551+ const deltaRight =
552+ oldCoords . left + oldCoords . width - ( newCoords . left + newCoords . width )
553+ const deltaBottom =
554+ oldCoords . top + oldCoords . height - ( newCoords . top + newCoords . height )
555+
556+ // element is probably anchored and doesn't need to be offset
557+ if ( deltaBottom == 0 ) deltaTop = 0
558+ if ( deltaRight == 0 ) deltaLeft = 0
559+
545560 const [ widthFrom , widthTo , heightFrom , heightTo ] = getTransitionSizes (
546561 el ,
547562 oldCoords ,
548563 newCoords ,
549564 )
550565 const start : Record < string , any > = {
551- transform : `translate(${ deltaX } px, ${ deltaY } px)` ,
566+ transform : `translate(${ deltaLeft } px, ${ deltaTop } px)` ,
552567 }
553568 const end : Record < string , any > = {
554569 transform : `translate(0, 0)` ,
@@ -574,7 +589,9 @@ function remain(el: Element) {
574589 }
575590 animations . set ( el , animation )
576591 coords . set ( el , newCoords )
577- animation . addEventListener ( "finish" , ( ) => updatePos ( el ) , { once : true } )
592+ animation . addEventListener ( "finish" , updatePos . bind ( null , el , false ) , {
593+ once : true ,
594+ } )
578595}
579596
580597/**
@@ -611,7 +628,9 @@ function add(el: Element) {
611628 animation . play ( )
612629 }
613630 animations . set ( el , animation )
614- animation . addEventListener ( "finish" , ( ) => updatePos ( el ) , { once : true } )
631+ animation . addEventListener ( "finish" , updatePos . bind ( null , el , false ) , {
632+ once : true ,
633+ } )
615634}
616635
617636/**
@@ -801,7 +820,11 @@ function deletePosition(
801820 }
802821 if ( ! offsetParent ) offsetParent = document . body
803822 const parentStyles = getComputedStyle ( offsetParent )
804- const parentCoords = coords . get ( offsetParent ) || getCoords ( offsetParent )
823+ const parentCoords =
824+ ! animations . has ( el ) || animations . get ( el ) ?. playState === "finished"
825+ ? getCoords ( offsetParent )
826+ : coords . get ( offsetParent ) !
827+
805828 const top =
806829 Math . round ( oldCoords . top - parentCoords . top ) -
807830 raw ( parentStyles . borderTopWidth )
0 commit comments