1
1
import * as React from 'react';
2
- import { makeStyles, tokens, Button, Card, Title3, Body2, Caption1 } from '@fluentui/react-components';
2
+ import { makeStyles, tokens, Button, Card, Title3, Body2, Caption1, motionTokens } from '@fluentui/react-components';
3
3
import { Rotate } from '@fluentui/react-motion-components-preview';
4
4
import { RotateParams } from '../../../library/src/components/Rotate/rotate-types';
5
5
6
- type RotatePattern = {
7
- /** Unique identifier for the pattern */
8
- id: string;
9
- /** Display name of the pattern */
10
- name: string;
11
- /** Description of what the pattern does */
12
- description: string;
13
- /** Emoji icon for visual representation */
14
- icon: string;
15
- /** Background color for the demo card */
16
- color: string;
17
- /** The axis of rotation: 'x', 'y', or 'z' - matches Rotate component */
18
- axis: Required<RotateParams['axis']>;
19
- /** The starting rotation angle in degrees - matches Rotate component */
20
- angle: Required<RotateParams['angle']>;
21
- /** Time (ms) for the animation - matches Rotate component */
22
- duration: Required<RotateParams['duration']>;
23
- /** Easing curve for the animation - matches Rotate component */
24
- easing: Required<RotateParams['easing']>;
25
- };
26
-
27
6
const useClasses = makeStyles({
28
7
container: {
29
8
display: 'flex',
30
9
flexDirection: 'column',
31
10
gap: '20px',
32
11
padding: '20px',
33
12
maxWidth: '1000px',
13
+ perspective: '500px',
34
14
},
35
15
controls: {
36
16
display: 'flex',
@@ -81,17 +61,33 @@ const useClasses = makeStyles({
81
61
82
62
const curveSpringRelaxed = `linear(0.000 0.000%, 0.06073 1.000%, 0.1215 2.000%, 0.1822 3.000%, 0.2429 4.000%, 0.3036 5.000%, 0.3644 6.000%, 0.4251 7.000%, 0.4858 8.000%, 0.5465 9.000%, 0.6073 10.00%, 0.6680 11.00%, 0.7287 12.00%, 0.7895 13.00%, 0.8502 14.00%, 0.9109 15.00%, 0.9716 16.00%, 1.031 17.00%, 1.085 18.00%, 1.131 19.00%, 1.168 20.00%, 1.198 21.00%, 1.220 22.00%, 1.234 23.00%, 1.241 24.00%, 1.242 25.00%, 1.236 26.00%, 1.226 27.00%, 1.211 28.00%, 1.192 29.00%, 1.171 30.00%, 1.148 31.00%, 1.124 32.00%, 1.099 33.00%, 1.074 34.00%, 1.050 35.00%, 1.028 36.00%, 1.007 37.00%, 0.9880 38.00%, 0.9714 39.00%, 0.9572 40.00%, 0.9455 41.00%, 0.9364 42.00%, 0.9298 43.00%, 0.9255 44.00%, 0.9235 45.00%, 0.9236 46.00%, 0.9255 47.00%, 0.9291 48.00%, 0.9339 49.00%, 0.9399 50.00%, 0.9467 51.00%, 0.9541 52.00%, 0.9618 53.00%, 0.9697 54.00%, 0.9774 55.00%, 0.9849 56.00%, 0.9920 57.00%, 0.9986 58.00%, 1.004 59.00%, 1.010 60.00%, 1.014 61.00%, 1.018 62.00%, 1.020 63.00%, 1.022 64.00%, 1.024 65.00%, 1.024 66.00%, 1.024 67.00%, 1.023 68.00%, 1.022 69.00%, 1.021 70.00%, 1.019 71.00%, 1.017 72.00%, 1.014 73.00%, 1.012 74.00%, 1.009 75.00%, 1.007 76.00%, 1.004 77.00%, 1.002 78.00%, 1.000 79.00%, 0.9984 80.00%, 0.9968 81.00%, 0.9954 82.00%, 0.9943 83.00%, 0.9935 84.00%, 0.9929 85.00%, 0.9925 86.00%, 0.9923 87.00%, 0.9924 88.00%, 0.9926 89.00%, 0.9930 90.00%, 0.9935 91.00%, 0.9941 92.00%, 0.9948 93.00%, 0.9956 94.00%, 0.9964 95.00%, 0.9972 96.00%, 0.9979 97.00%, 0.9987 98.00%, 0.9994 99.00%, 1.000 100.0%)`;
83
63
64
+ type RotatePattern = {
65
+ id: string;
66
+ name: string;
67
+ description: string;
68
+ icon: string;
69
+ color: string;
70
+ axis: Required<RotateParams['axis']>;
71
+ angle: Required<RotateParams['angle']>;
72
+ duration: Required<RotateParams['duration']>;
73
+ easing: Required<RotateParams['easing']>;
74
+ exitEasing: Required<RotateParams['easing']>;
75
+ exitDuration: Required<RotateParams['duration']>;
76
+ };
77
+
84
78
const patterns: RotatePattern[] = [
85
79
{
86
80
id: 'flip-horizontal',
87
81
name: 'Horizontal Flip',
88
- description: 'Classic Y-axis rotation',
82
+ description: 'Y-axis rotation',
89
83
icon: '↔️',
90
84
color: tokens.colorPaletteBlueForeground2,
91
85
axis: 'y',
92
86
angle: 90,
93
87
easing: curveSpringRelaxed,
88
+ exitEasing: motionTokens.curveDecelerateMid,
94
89
duration: 2000,
90
+ exitDuration: motionTokens.durationUltraSlow,
95
91
},
96
92
{
97
93
id: 'flip-vertical',
@@ -102,7 +98,9 @@ const patterns: RotatePattern[] = [
102
98
axis: 'x',
103
99
angle: 90,
104
100
easing: curveSpringRelaxed,
101
+ exitEasing: motionTokens.curveDecelerateMid,
105
102
duration: 2000,
103
+ exitDuration: motionTokens.durationUltraSlow,
106
104
},
107
105
{
108
106
id: 'spin',
@@ -113,13 +111,15 @@ const patterns: RotatePattern[] = [
113
111
axis: 'z',
114
112
angle: 90,
115
113
easing: curveSpringRelaxed,
114
+ exitEasing: motionTokens.curveDecelerateMid,
116
115
duration: 2000,
116
+ exitDuration: motionTokens.durationUltraSlow,
117
117
},
118
118
];
119
119
120
120
export const CommonPatterns = () => {
121
121
const classes = useClasses();
122
- const [activePatterns, setActivePatterns] = React.useState<Set<string>>(new Set());
122
+ const [activePatterns, setActivePatterns] = React.useState<Set<string>>(new Set(patterns.map(p => p.id) ));
123
123
124
124
const togglePattern = (patternId: string) => {
125
125
setActivePatterns(prev => {
@@ -133,23 +133,6 @@ export const CommonPatterns = () => {
133
133
});
134
134
};
135
135
136
- const demonstrateAll = () => {
137
- setActivePatterns(new Set());
138
-
139
- patterns.forEach((pattern, index) => {
140
- setTimeout(() => {
141
- setActivePatterns(prev => new Set([...prev, pattern.id]));
142
- setTimeout(() => {
143
- setActivePatterns(prev => {
144
- const newSet = new Set(prev);
145
- newSet.delete(pattern.id);
146
- return newSet;
147
- });
148
- }, pattern.duration + 200);
149
- }, index * 300);
150
- });
151
- };
152
-
153
136
const toggleAllPatterns = () => {
154
137
if (activePatterns.size === patterns.length) {
155
138
// All are showing, so hide all
@@ -165,9 +148,6 @@ export const CommonPatterns = () => {
165
148
return (
166
149
<div className={classes.container}>
167
150
<div className={classes.controls}>
168
- <Button appearance="primary" onClick={demonstrateAll}>
169
- Demonstrate All Patterns
170
- </Button>
171
151
<Button onClick={toggleAllPatterns}>{allPatternsVisible ? 'Hide All' : 'Show All'}</Button>
172
152
</div>
173
153
@@ -180,6 +160,8 @@ export const CommonPatterns = () => {
180
160
angle={pattern.angle}
181
161
duration={pattern.duration}
182
162
easing={pattern.easing}
163
+ exitEasing={pattern.exitEasing}
164
+ exitDuration={pattern.exitDuration}
183
165
>
184
166
<Card className={classes.patternCard} onClick={() => togglePattern(pattern.id)}>
185
167
<div className={classes.demoIcon} style={{ backgroundColor: pattern.color }}>
0 commit comments