From ac3c7bbdd7a5afc11e9181d1cf78c3dc76a87c70 Mon Sep 17 00:00:00 2001 From: Breno Lira Date: Tue, 29 Oct 2024 23:26:27 -0300 Subject: [PATCH 1/6] feat: adds rotation property --- packages/svelte/src/animate/index.js | 5 +++-- packages/svelte/src/animate/public.d.ts | 1 + packages/svelte/types/index.d.ts | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/svelte/src/animate/index.js b/packages/svelte/src/animate/index.js index fbf2ac83e2a7..d102e04a19bd 100644 --- a/packages/svelte/src/animate/index.js +++ b/packages/svelte/src/animate/index.js @@ -21,7 +21,7 @@ export function flip(node, { from, to }, params = {}) { var dx = (from.left + dsx * ox - (to.left + ox)) / zoom; var dy = (from.top + dsy * oy - (to.top + oy)) / zoom; - var { delay = 0, duration = (d) => Math.sqrt(d) * 120, easing = cubicOut } = params; + var { delay = 0, duration = (d) => Math.sqrt(d) * 120, easing = cubicOut, rotation = 0 } = params; return { delay, @@ -30,9 +30,10 @@ export function flip(node, { from, to }, params = {}) { css: (t, u) => { var x = u * dx; var y = u * dy; + var r = u * rotation; var sx = t + u * dsx; var sy = t + u * dsy; - return `transform: ${transform} scale(${sx}, ${sy}) translate(${x}px, ${y}px);`; + return `transform: ${transform} scale(${sx}, ${sy}) translate(${x}px, ${y}px) rotate(${r}deg);`; } }; } diff --git a/packages/svelte/src/animate/public.d.ts b/packages/svelte/src/animate/public.d.ts index 8a6cf5ebf659..f0609756401f 100644 --- a/packages/svelte/src/animate/public.d.ts +++ b/packages/svelte/src/animate/public.d.ts @@ -11,6 +11,7 @@ export interface FlipParams { delay?: number; duration?: number | ((len: number) => number); easing?: (t: number) => number; + rotation?: number; } export * from './index.js'; diff --git a/packages/svelte/types/index.d.ts b/packages/svelte/types/index.d.ts index ebf17db6e2ff..bff1f61c19b8 100644 --- a/packages/svelte/types/index.d.ts +++ b/packages/svelte/types/index.d.ts @@ -581,6 +581,7 @@ declare module 'svelte/animate' { delay?: number; duration?: number | ((len: number) => number); easing?: (t: number) => number; + rotation?: number; } /** * The flip function calculates the start and end position of an element and animates between them, translating the x and y values. From 69b1972e540cd2bcecb2c26a9a72e9d8f2c40cdd Mon Sep 17 00:00:00 2001 From: Breno Lira Date: Fri, 1 Nov 2024 06:39:11 -0300 Subject: [PATCH 2/6] feat: gets rotation from transform matrix and from/to sizes --- packages/svelte/src/animate/index.js | 24 +++++++++++++++++++++--- packages/svelte/src/animate/public.d.ts | 1 - packages/svelte/types/index.d.ts | 1 - 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/packages/svelte/src/animate/index.js b/packages/svelte/src/animate/index.js index d102e04a19bd..0a3bfe2a1bea 100644 --- a/packages/svelte/src/animate/index.js +++ b/packages/svelte/src/animate/index.js @@ -16,12 +16,20 @@ export function flip(node, { from, to }, params = {}) { var transform = style.transform === 'none' ? '' : style.transform; var [ox, oy] = style.transformOrigin.split(' ').map(parseFloat); + + var m = new DOMMatrix(transform); + var dsx = from.width / to.width; var dsy = from.height / to.height; var dx = (from.left + dsx * ox - (to.left + ox)) / zoom; var dy = (from.top + dsy * oy - (to.top + oy)) / zoom; - var { delay = 0, duration = (d) => Math.sqrt(d) * 120, easing = cubicOut, rotation = 0 } = params; + var { delay = 0, duration = (d) => Math.sqrt(d) * 120, easing = cubicOut } = params; + + const rf = Math.atan2(m.m21, m.m11) + Math.atan2(from.bottom - from.top, from.right - from.left); + const rt = Math.atan2(to.bottom - to.top, to.right - to.left); + + const rn = normalize_angle(rf - rt); return { delay, @@ -30,14 +38,24 @@ export function flip(node, { from, to }, params = {}) { css: (t, u) => { var x = u * dx; var y = u * dy; - var r = u * rotation; var sx = t + u * dsx; var sy = t + u * dsy; - return `transform: ${transform} scale(${sx}, ${sy}) translate(${x}px, ${y}px) rotate(${r}deg);`; + var r = u * rn; + + return `transform: ${transform} scale(${sx}, ${sy}) translate(${x}px, ${y}px) rotate(${r}rad);`; } }; } +/** + * Prevent extra flips + * + * @param {number} angle + */ +function normalize_angle(angle) { + return Math.atan2(Math.sin(angle), Math.cos(angle)); +} + /** * @param {Element} element */ diff --git a/packages/svelte/src/animate/public.d.ts b/packages/svelte/src/animate/public.d.ts index f0609756401f..8a6cf5ebf659 100644 --- a/packages/svelte/src/animate/public.d.ts +++ b/packages/svelte/src/animate/public.d.ts @@ -11,7 +11,6 @@ export interface FlipParams { delay?: number; duration?: number | ((len: number) => number); easing?: (t: number) => number; - rotation?: number; } export * from './index.js'; diff --git a/packages/svelte/types/index.d.ts b/packages/svelte/types/index.d.ts index bff1f61c19b8..ebf17db6e2ff 100644 --- a/packages/svelte/types/index.d.ts +++ b/packages/svelte/types/index.d.ts @@ -581,7 +581,6 @@ declare module 'svelte/animate' { delay?: number; duration?: number | ((len: number) => number); easing?: (t: number) => number; - rotation?: number; } /** * The flip function calculates the start and end position of an element and animates between them, translating the x and y values. From a41e301390af9ee5507558062e050cdcfc7ec453 Mon Sep 17 00:00:00 2001 From: Breno Lira Date: Fri, 1 Nov 2024 06:56:09 -0300 Subject: [PATCH 3/6] fix: remove unused code --- packages/svelte/src/animate/index.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/svelte/src/animate/index.js b/packages/svelte/src/animate/index.js index 0a3bfe2a1bea..d6a40f2f6872 100644 --- a/packages/svelte/src/animate/index.js +++ b/packages/svelte/src/animate/index.js @@ -53,7 +53,17 @@ export function flip(node, { from, to }, params = {}) { * @param {number} angle */ function normalize_angle(angle) { - return Math.atan2(Math.sin(angle), Math.cos(angle)); + var n = angle % (2 * Math.PI); + + if (n > Math.PI) { + n -= 2 * Math.PI; + } + + if (n < -Math.PI) { + n += 2 * Math.PI; + } + + return n; } /** From 4c767c317e591b386ebc64565580796db14af589 Mon Sep 17 00:00:00 2001 From: Breno Lira Date: Mon, 4 Nov 2024 15:19:32 -0300 Subject: [PATCH 4/6] fix: format --- packages/svelte/src/animate/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/svelte/src/animate/index.js b/packages/svelte/src/animate/index.js index d6a40f2f6872..f3ad74986cf3 100644 --- a/packages/svelte/src/animate/index.js +++ b/packages/svelte/src/animate/index.js @@ -58,8 +58,8 @@ function normalize_angle(angle) { if (n > Math.PI) { n -= 2 * Math.PI; } - - if (n < -Math.PI) { + + if (n < -Math.PI) { n += 2 * Math.PI; } From d4bc59d61f877606ba7a13de468850e9eead8d1e Mon Sep 17 00:00:00 2001 From: Breno Lira Date: Tue, 5 Nov 2024 09:04:57 -0300 Subject: [PATCH 5/6] Update packages/svelte/src/animate/index.js Co-authored-by: Mathias Picker <48158184+MathiasWP@users.noreply.github.com> --- packages/svelte/src/animate/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/svelte/src/animate/index.js b/packages/svelte/src/animate/index.js index f3ad74986cf3..7faf4dede210 100644 --- a/packages/svelte/src/animate/index.js +++ b/packages/svelte/src/animate/index.js @@ -17,7 +17,7 @@ export function flip(node, { from, to }, params = {}) { var transform = style.transform === 'none' ? '' : style.transform; var [ox, oy] = style.transformOrigin.split(' ').map(parseFloat); - var m = new DOMMatrix(transform); + var m = new DOMMatrixReadOnly(transform); var dsx = from.width / to.width; var dsy = from.height / to.height; From 0619b76a4935c6e17ad8b910d36c2f68225ebc54 Mon Sep 17 00:00:00 2001 From: Breno Lira Date: Tue, 5 Nov 2024 09:29:37 -0300 Subject: [PATCH 6/6] fix: 'var' as default --- packages/svelte/src/animate/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/svelte/src/animate/index.js b/packages/svelte/src/animate/index.js index f3ad74986cf3..8f2e55e2cfbc 100644 --- a/packages/svelte/src/animate/index.js +++ b/packages/svelte/src/animate/index.js @@ -26,10 +26,10 @@ export function flip(node, { from, to }, params = {}) { var dy = (from.top + dsy * oy - (to.top + oy)) / zoom; var { delay = 0, duration = (d) => Math.sqrt(d) * 120, easing = cubicOut } = params; - const rf = Math.atan2(m.m21, m.m11) + Math.atan2(from.bottom - from.top, from.right - from.left); - const rt = Math.atan2(to.bottom - to.top, to.right - to.left); + var rf = Math.atan2(m.m21, m.m11) + Math.atan2(from.bottom - from.top, from.right - from.left); + var rt = Math.atan2(to.bottom - to.top, to.right - to.left); - const rn = normalize_angle(rf - rt); + var rn = normalize_angle(rf - rt); return { delay,