export declare const toSingleRotation: (transforms: string[]) => string[]; export declare const toClosestRotations: (originTransforms: string[], targetTransforms: string[]) => void; /** * Adjust every rotateZ in `targetTransforms` to the equivalent angle closest to the origin's total * rotation, WITHOUT mutating `originTransforms`. * * Unlike {@link toClosestRotations}, the origin is treated as a fixed reference. This is required for * "to-only" keyframes (dropped items): there the animation's implicit "from" is the element's actual * inline transform (already normalized to [0, 2π) by {@link toSingleRotation}), so the target must * stay in that same convention. Re-baselining the target toward 0 (as toClosestRotations does) would * leave e.g. a 270° item with a -90° target, i.e. a 360° gap animated as a full spin. */ export declare const alignTargetRotationsToOrigin: (originTransforms: string[], targetTransforms: string[]) => void; export declare const removeRotations: (transforms: string[]) => string[]; /** * The same transforms, read in a frame that has been turned over by a rotateY(180deg): x and z change sign while * y does not, so a translateZ that lifts an item towards the player has to push it away instead, and a rotateZ * has to turn the other way round. * * Written this way rather than by wrapping the list in rotateY(-180deg) ... rotateY(180deg), which computes the * same thing but is 2 functions longer: a transition towards a longer list interpolates those 2 rotations from 0, * and everything between them is read in a half turned frame along the way, which swings the item sideways before * it settles. Mirroring each function in place keeps the list the length it was, so every step of a transition is * a step towards the answer. * * Undefined when the list holds something this cannot mirror, leaving the caller to fall back on wrapping. */ export declare const mirrorTransforms: (transforms: string[]) => string[] | undefined;