@aphrody/m3-运动
反应组件和钩用于材料 3 运动模式(容器变换,共享轴,淡出,倒塌, 开始 动议,带有M3弹簧,放松和持续符.
bun add @aphrody/m3-motion motion react
import { M3Fade, M3FadeThrough } from "@aphrody/m3-motion";
<M3Fade in={open}>Details</M3Fade>;
<M3FadeThrough stateKey={tab}>{panel}</M3FadeThrough>;
许可证: Apache-2.0(LICENSE) (中文(简体) ). 安装指南 : 文件/材料/立方米/INSTALL.md。 。 。 .
1. 集装箱转换M3ContainerTransform(中文(简体) )
容器将一个UI元素转换为另一个元素(例如将一个小卡片组件变形为一整页详细视图).
关键特性
- 光谱比保全: 使用布局-位置校正在容器形态时自动地防止儿童的布局扭曲(skewing/stritching).
- Spec-compliant 交叉淡出: 提前显示起始内容(0%到30%的过渡),并延迟目标内容的淡出(20%到100%的过渡)来避免混乱的中间状态.
- 指针事件管理:防止不活动,隐藏内容被拦截指针交互.
- 灵活性: 支持两个 单容器切换 方法(在同一集装箱内重新提交)和 双容器共享布局 方法(通过
layoutId) (中文(简体) ).
子组件
M3ContainerTransform: 家长形态容器.M3ContainerTransformStart: srapper 用于起始内容(例如倒卡细节).M3ContainerTransformEnd: 收尾内容的收尾(如扩充的页面细节).
代码示例
单一集装箱切换方法
使用状态对单个组件实例进行形态化的最佳方式 .
import React, { useState } from "react";
import {
M3ContainerTransform,
M3ContainerTransformStart,
M3ContainerTransformEnd,
} from "@aphrody/m3-motion";
export const MorphingCard = () => {
const [isExpanded, setIsExpanded] = useState(false);
return (
<M3ContainerTransform
isExpanded={isExpanded}
speed="default"
style={{
width: isExpanded ? 500 : 250,
height: isExpanded ? 400 : 150,
borderRadius: isExpanded ? 28 : 16,
backgroundColor: "var(--md-sys-color-surface-container)",
cursor: "pointer",
}}
onClick={() => setIsExpanded(!isExpanded)}
>
{/* Start state (collapsed content) */}
<M3ContainerTransformStart>
<div style={{ padding: 16 }}>
<h3>Collapsed Card</h3>
<p>Click me to expand...</p>
</div>
</M3ContainerTransformStart>
{/* End state (expanded detail content) */}
<M3ContainerTransformEnd>
<div style={{ padding: 24 }}>
<h2>Detailed View</h2>
<p>This is the expanded content showing the full detail surface.</p>
<button
onClick={e => {
e.stopPropagation();
setIsExpanded(false);
}}
>
Close
</button>
</div>
</M3ContainerTransformEnd>
</M3ContainerTransform>
);
};
双集装箱共享版式办法(通过 layoutId(中文(简体) )
最适合页面/路由转换或单独的 DOM 元素 。 环绕条件渲染到 <AnimatePresence> 以启用退出淡出过渡.
import React, { useState } from "react";
import { AnimatePresence } from "motion/react";
import {
M3ContainerTransform,
M3ContainerTransformStart,
M3ContainerTransformEnd,
} from "@aphrody/m3-motion";
export const ListView = () => {
const [selectedId, setSelectedId] = useState<string | null>(null);
return (
<div>
{/* List of items */}
{!selectedId && (
<div className="grid">
<M3ContainerTransform
layoutId="card-item-1"
onClick={() => setSelectedId("1")}
style={{
borderRadius: 16,
background: "#eee",
width: 200,
height: 120,
}}
>
<M3ContainerTransformStart>
<div style={{ padding: 12 }}>Card Content 1</div>
</M3ContainerTransformStart>
</M3ContainerTransform>
</div>
)}
{/* Expanded detail page */}
<AnimatePresence>
{selectedId === "1" && (
<div className="backdrop">
<M3ContainerTransform
layoutId="card-item-1"
style={{
borderRadius: 24,
background: "#fff",
width: 600,
height: 450,
}}
>
<M3ContainerTransformEnd>
<div style={{ padding: 24 }}>
<h2>Expanded Title 1</h2>
<p>Long detail text...</p>
<button onClick={() => setSelectedId(null)}>
Back to List
</button>
</div>
</M3ContainerTransformEnd>
</M3ContainerTransform>
</div>
)}
</AnimatePresence>
</div>
);
};
2. 共有轴心国(M3SharedAxis(中文(简体) )
用于具有空间或导航关系的UI元素之间的过渡(例如:页面分步器,分页切换,或对话框覆盖等). 支助 x, (中文(简体) ), y,以及 z 斧头.
- 默认输入时间 : 300ms (英语) (单位:千美元)
medium2与emphasizedDecelerate放松点. - 默认退出时间 : 200米长 (单位:千美元)
short4与emphasizedAccelerate放松点.
代码示例
import React, { useState } from "react";
import { M3SharedAxis } from "@aphrody/m3-motion";
export const StepWizard = () => {
const [step, setStep] = useState(0);
return (
<div>
<M3SharedAxis
stateKey={step}
axis="x"
forward={step > 0}
style={{ padding: 20 }}
>
{step === 0 && <div>Step 1: Enter details</div>}
{step === 1 && <div>Step 2: Review options</div>}
{step === 2 && <div>Step 3: Confirm purchase</div>}
</M3SharedAxis>
<button onClick={() => setStep(prev => Math.max(0, prev - 1))}>
Back
</button>
<button onClick={() => setStep(prev => Math.min(2, prev + 1))}>
Next
</button>
</div>
);
};
3. 通过(M3FadeThrough(中文(简体) )
用于没有很强空间关系的主视图之间的过渡(如底层导航切换,设置屏幕等).
- 默认退出时间( 取消) : 90分钟 与
emphasizedAccelerate放松点. - 默认输入持续时间( 从92% 中取消) : 210毫米口径 与
emphasizedDecelerate放松点.
代码示例
import React, { useState } from "react";
import { M3FadeThrough } from "@aphrody/m3-motion";
export const AppNavigation = () => {
const [currentTab, setCurrentTab] = useState("home");
return (
<div>
<M3FadeThrough stateKey={currentTab} style={{ height: 400 }}>
{currentTab === "home" && <div>Home View Content</div>}
{currentTab === "search" && <div>Search Page Content</div>}
{currentTab === "profile" && <div>User Profile Settings</div>}
</M3FadeThrough>
<nav>
<button onClick={() => setCurrentTab("home")}>Home</button>
<button onClick={() => setCurrentTab("search")}>Search</button>
<button onClick={() => setCurrentTab("profile")}>Profile</button>
</nav>
</div>
);
};
4. 期限和缓解预设
开发者可直接访问官方"材料设计"3分计时和曲线:
import { m3Easings, m3Durations, m3Springs } from "@aphrody/m3-motion";
// Custom animation example using M3 tokens
const myCustomTransition = {
ease: m3Easings.emphasizedDecelerate,
duration: m3Durations.medium4, // 400ms
};
动议预设摘要
m3Easings: Bezier 曲线用于emphasized(约),emphasizedDecelerate(进入),emphasizedAccelerate(出狱),standard, (中文(简体) ),standardDecelerate,以及standardAccelerate。 。 。 .m3Durations: 计时表short1(50毫秒)至extraLong4(1000ms) (英语).m3Springs: 手调取出春常数fast, (中文(简体) ),default, (中文(简体) ),slow拆分为spatial(义务)和effects(严重被挡住).
许可证
阿帕奇 - 2.0