Keep rotateZ on elements with a layout animation
The projection pipeline handled rotate, rotateX and rotateY but not rotateZ, so a layout or shared layout animation silently dropped it from the generated transform and never mixed it between lead and follow.
This commit is contained in:
1 parent
1ba1c99cc1
commit
2e01f31175
7 files changed
+83
No files matched your search
@@ -10,6 +10,10 @@ Undocumented APIs should be considered internal and may change without warning.
|
||||
|
||||
- `springValue`/`useSpring`: Improved performance when retargeting spring.
|
||||
|
||||
### Fixed
|
||||
|
||||
- `rotateZ` is no longer dropped from elements with a layout or shared layout animation.
|
||||
|
||||
## [13.2.0] 2026-09-03
|
||||
|
||||
### Added
|
||||
|
||||
@@ -97,4 +97,20 @@ describe("mixValues", () => {
|
||||
|
||||
expect(output).toEqual({ borderTopLeftRadius: "10px" })
|
||||
})
|
||||
|
||||
test("mixes rotate", () => {
|
||||
const output = {}
|
||||
|
||||
mixValues(output, { rotate: 0 }, { rotate: 90 }, 0.5, false, false)
|
||||
|
||||
expect(output).toEqual({ rotate: 45 })
|
||||
})
|
||||
|
||||
test("mixes rotateZ", () => {
|
||||
const output = {}
|
||||
|
||||
mixValues(output, { rotateZ: 0 }, { rotateZ: 90 }, 0.5, false, false)
|
||||
|
||||
expect(output).toEqual({ rotateZ: 45 })
|
||||
})
|
||||
})
|
||||
@@ -91,6 +91,15 @@ export function mixValues(
|
||||
progress
|
||||
)
|
||||
}
|
||||
|
||||
// `rotateZ` is a synonym of `rotate` but arrives as its own value.
|
||||
if (follow.rotateZ || lead.rotateZ) {
|
||||
target.rotateZ = mixNumber(
|
||||
(follow.rotateZ as number) || 0,
|
||||
(lead.rotateZ as number) || 0,
|
||||
progress
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function getRadius(values: ResolvedValues, radiusName: string) {
|
||||
|
||||
@@ -102,4 +102,35 @@ describe("buildProjectionTransform", () => {
|
||||
buildProjectionTransform(delta, { x: 1, y: 1 }, { rotate: 10 })
|
||||
).toEqual("translate3d(100px, 100px, 0px) rotate(10deg) scale(2, 4)")
|
||||
})
|
||||
|
||||
it("Applies rotateZ", () => {
|
||||
const delta = {
|
||||
x: {
|
||||
translate: 100,
|
||||
scale: 2,
|
||||
origin: 0.5,
|
||||
originPoint: 100,
|
||||
},
|
||||
y: {
|
||||
translate: 100,
|
||||
scale: 4,
|
||||
origin: 0.5,
|
||||
originPoint: 100,
|
||||
},
|
||||
}
|
||||
|
||||
expect(
|
||||
buildProjectionTransform(delta, { x: 1, y: 1 }, { rotateZ: 10 })
|
||||
).toEqual("translate3d(100px, 100px, 0px) rotateZ(10deg) scale(2, 4)")
|
||||
|
||||
expect(
|
||||
buildProjectionTransform(
|
||||
delta,
|
||||
{ x: 1, y: 1 },
|
||||
{ rotate: 45, rotateX: 20, rotateY: 30, rotateZ: 10 }
|
||||
)
|
||||
).toEqual(
|
||||
"translate3d(100px, 100px, 0px) rotate(45deg) rotateX(20deg) rotateY(30deg) rotateZ(10deg) scale(2, 4)"
|
||||
)
|
||||
})
|
||||
})
|
||||
@@ -36,6 +36,7 @@ export function buildProjectionTransform(
|
||||
pathRotation,
|
||||
rotateX,
|
||||
rotateY,
|
||||
rotateZ,
|
||||
skewX,
|
||||
skewY,
|
||||
} = latestTransform
|
||||
@@ -46,6 +47,7 @@ export function buildProjectionTransform(
|
||||
if (pathRotation) transform += `rotate(${pathRotation}deg) `
|
||||
if (rotateX) transform += `rotateX(${rotateX}deg) `
|
||||
if (rotateY) transform += `rotateY(${rotateY}deg) `
|
||||
if (rotateZ) transform += `rotateZ(${rotateZ}deg) `
|
||||
if (skewX) transform += `skewX(${skewX}deg) `
|
||||
if (skewY) transform += `skewY(${skewY}deg) `
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import { hasTransform } from "../has-transform"
|
||||
|
||||
describe("hasTransform", () => {
|
||||
test("returns false when no transform is set", () => {
|
||||
expect(hasTransform({})).toBeFalsy()
|
||||
expect(hasTransform({ scale: 1, scaleX: 1, scaleY: 1 })).toBeFalsy()
|
||||
})
|
||||
|
||||
test("detects every distorting transform", () => {
|
||||
expect(hasTransform({ scale: 2 })).toBeTruthy()
|
||||
expect(hasTransform({ x: 100 })).toBeTruthy()
|
||||
expect(hasTransform({ z: 100 })).toBeTruthy()
|
||||
expect(hasTransform({ rotate: 45 })).toBeTruthy()
|
||||
expect(hasTransform({ rotateX: 45 })).toBeTruthy()
|
||||
expect(hasTransform({ rotateY: 45 })).toBeTruthy()
|
||||
expect(hasTransform({ rotateZ: 45 })).toBeTruthy()
|
||||
expect(hasTransform({ skewX: 45 })).toBeTruthy()
|
||||
expect(hasTransform({ skewY: 45 })).toBeTruthy()
|
||||
})
|
||||
})
|
||||
@@ -21,6 +21,7 @@ export function hasTransform(values: ResolvedValues) {
|
||||
values.rotate ||
|
||||
values.rotateX ||
|
||||
values.rotateY ||
|
||||
values.rotateZ ||
|
||||
values.skewX ||
|
||||
values.skewY
|
||||
)
|
||||
|
||||
Reference in new issue
Block a user