fix: get animation params before switching elements

animation-params
Simon Holthausen 6 months ago
parent 65234b80c0
commit e1439647ec

@ -73,6 +73,9 @@ export function animation(element, get_fn, get_params) {
/** @type {DOMRect} */ /** @type {DOMRect} */
var to; var to;
/** @type {P | undefined} */
var params;
/** @type {Animation | undefined} */ /** @type {Animation | undefined} */
var animation; var animation;
@ -83,6 +86,10 @@ export function animation(element, get_fn, get_params) {
element, element,
measure() { measure() {
from = this.element.getBoundingClientRect(); from = this.element.getBoundingClientRect();
// get params now, in case they depend on the list item's position. Example:
// If A and B switch position and the animation is like `animate:flip={{ delay: itemIdx * 50 }}`
// then we want `itemIdx` to be the index before the switch for both A and B
params = get_params?.();
}, },
apply() { apply() {
animation?.abort(); animation?.abort();
@ -95,7 +102,7 @@ export function animation(element, get_fn, get_params) {
from.top !== to.top || from.top !== to.top ||
from.bottom !== to.bottom from.bottom !== to.bottom
) { ) {
const options = get_fn()(this.element, { from, to }, get_params?.()); const options = get_fn()(this.element, { from, to }, params);
animation = animate( animation = animate(
this.element, this.element,
@ -422,6 +429,7 @@ function animate(element, options, counterpart, t2, on_finish, on_abort) {
} }
task = loop((now) => { task = loop((now) => {
console.log(now, start, end, delay);
if (now >= end) { if (now >= end) {
tick?.(t2, 1 - t2); tick?.(t2, 1 - t2);
on_finish?.(); on_finish?.();

@ -1,9 +1,6 @@
// @ts-nocheck import { test } from '../../test';
import { ok, test } from '../../test';
export default test({ export default test({
skip: true, // TODO: needs fixing
get props() { get props() {
return { return {
things: [ things: [
@ -25,7 +22,7 @@ export default test({
`, `,
test({ assert, component, window, raf }) { test({ assert, component, window, raf }) {
let divs = window.document.querySelectorAll('div'); let divs = /** @type {NodeListOf<any>} */ (window.document.querySelectorAll('div'));
divs.forEach((div) => { divs.forEach((div) => {
div.getBoundingClientRect = function () { div.getBoundingClientRect = function () {
const index = [...this.parentNode.children].indexOf(this); const index = [...this.parentNode.children].indexOf(this);
@ -52,6 +49,7 @@ export default test({
assert.equal(divs[0].dy, 120); assert.equal(divs[0].dy, 120);
assert.equal(divs[4].dy, -120); assert.equal(divs[4].dy, -120);
console.log('tick 50');
raf.tick(50); raf.tick(50);
assert.equal(divs[0].dy, 108); assert.equal(divs[0].dy, 108);
assert.equal(divs[4].dy, -60); assert.equal(divs[4].dy, -60);

Loading…
Cancel
Save