Guides

动画

¥Animation

使用 CSS 关键帧或你选择的 JavaScript 动画库为 Radix Primitives 动画。

向 Radix Primitives 添加动画的感觉与其他组件类似,但这里需要注意一些关于使用 JS 动画库退出动画的注意事项。

¥Adding animation to Radix Primitives should feel similar to any other component, but there are some caveats noted here in regards to exiting animations with JS animation libraries.

使用 CSS 动画制作动画

¥Animating with CSS animation

为基元动画最简单的方法是使用 CSS。

¥The simplest way to animate Primitives is with CSS.

你可以使用 CSS 动画为挂载和卸载阶段设置动画。后者之所以能够实现,是因为 Radix Primitives 会在动画播放时暂停卸载。

¥You can use CSS animation to animate both mount and unmount phases. The latter is possible because the Radix Primitives will suspend unmount while your animation plays out.

@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
.DialogOverlay[data-state="open"], .DialogContent[data-state="open"] {
animation: fadeIn 300ms ease-out;
}
.DialogOverlay[data-state="closed"], .DialogContent[data-state="closed"] {
animation: fadeOut 300ms ease-in;
}

委托 JavaScript 动画卸载

¥Delegating unmounting for JavaScript Animation

当许多有状态的基元隐藏在视图之外时,它们实际上会从 React 树中移除,并且它们的元素也会从 DOM 中移除。JavaScript 动画库需要控制卸载阶段,因此我们在许多组件上提供了 forceMount prop,允许使用者根据这些库确定的动画状态委托子组件的挂载和卸载。

¥When many stateful Primitives are hidden from view, they are actually removed from the React Tree, and their elements removed from the DOM. JavaScript animation libraries need control of the unmounting phase, so we provide the forceMount prop on many components to allow consumers to delegate the mounting and unmounting of children based on the animation state determined by those libraries.

例如,如果你想使用 React Spring 为 Dialog 制作动画,你可以根据其某个钩子(例如 useTransition)的动画状态,有条件地渲染对话框的 OverlayContent 部分:

¥For example, if you want to use React Spring to animate a Dialog, you would do so by conditionally rendering the dialog Overlay and Content parts based on the animation state from one of its hooks like useTransition:

import { Dialog } from "radix-ui";
import { useTransition, animated, config } from "react-spring";
function Example() {
const [open, setOpen] = React.useState(false);
const transitions = useTransition(open, {
from: { opacity: 0, y: -10 },
enter: { opacity: 1, y: 0 },
leave: { opacity: 0, y: 10 },
config: config.stiff,
});
return (
<Dialog.Root open={open} onOpenChange={setOpen}>
<Dialog.Trigger>Open Dialog</Dialog.Trigger>
{transitions((styles, item) =>
item ? (
<>
<Dialog.Overlay forceMount asChild>
<animated.div style={{ opacity: styles.opacity, }} />
</Dialog.Overlay>
<Dialog.Content forceMount asChild>
<animated.div style={styles}>
<h1>Hello from inside the Dialog!</h1>
<Dialog.Close>close</Dialog.Close>
</animated.div>
</Dialog.Content>
</>
) : null,
)}
</Dialog.Root>
);
}
Previous样式
Next组合