Skip to content

Commit 212b795

Browse files
committed
working on better staggering
1 parent 624d245 commit 212b795

File tree

18 files changed

+260
-923
lines changed

18 files changed

+260
-923
lines changed

README.md

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -163,13 +163,12 @@ The parent wrapper component that contains all the elements to be animated.
163163

164164
#### Props
165165

166-
| prop | default | type | details |
167-
| ----------------------- | :--------------------------------------------: | :------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
168-
| flipKey **(required)** | - | `string`, `number`, `bool` | Changing this tells `react-flip-toolkit` to transition child elements wrapped in `Flipped` components. |
169-
| children **(required)** | - | `node` | One or more element children |
170-
| spring | `{stiffness: 1000`, `damping: 500`, `mass: 3}` | `object` | **The default easing for all transitions uses springs.** You can customize the spring by changing the `stiffness`, `damping`, or `mass` values passed in the `spring` object prop. If you provide an `ease` prop (described below), that will be used instead of a spring. [Explore the spring setting options here.](https://codepen.io/aholachek/full/bKmZbV/) |
171-
| ease | `easeOutExpo` | `string` | If you'd rather use easing functions instead of springs, you can set the default easing for all FLIP transitions by providing a name of an easing function. [Explore the easing options here.](https://codepen.io/aholachek/full/bKmZbV/) |
172-
| duration | `250` | `number` | Default duration in `ms` for all FLIP transitions that use the `ease` prop instead of the default `spring` (which uses a physics simulation and therefore doesn't require a duration) |
166+
| prop | default | type | details |
167+
| ----------------------- | :--------------------------------------------: | :------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
168+
| flipKey **(required)** | - | `string`, `number`, `bool` | Changing this tells `react-flip-toolkit` to transition child elements wrapped in `Flipped` components. |
169+
| children **(required)** | - | `node` | One or more element children |
170+
| spring | `{stiffness: 1000`, `damping: 500`, `mass: 3}` | `object` | **The default easing for all transitions uses springs.** You can customize the spring by changing the `stiffness`, `damping`, or `mass` values passed in the `spring` object prop. If you provide an `ease` prop (described below), that will be used instead of a spring. [Explore the spring setting options here.](https://codepen.io/aholachek/full/bKmZbV/) |
171+
173172
| applyTransformOrigin | `true` | `bool` | Whether or not `react-flip-toolkit` should apply a transform-origin of "0 0" to animating children (this is generally, but not always, desirable for FLIP animations) |
174173
| element | `div` | `string` | If you'd like the wrapper element created by the `Flipped` container to be something other than a `div`, you can specify that here. |
175174
| className | - | `string` | A class applied to the wrapper element, helpful for styling. |
@@ -211,9 +210,7 @@ The `Flipped` component produces no markup, it simply passes some props down to
211210
| inverseFlipId | - | `string` | Refer to the id of the parent `Flipped` container whose transform you want to cancel out. [Read more about canceling out parent transforms here.](#scale-transitions-made-easier) |
212211
| transformOrigin | `"0 0"` | `string` | This is a convenience method to apply the proper CSS `transform-origin` to the element being FLIP-ped. This will override `react-flip-toolkit`'s default application of `transform-origin: 0 0;` if it is provided as a prop. |
213212
| spring | `{stiffness: 1000`, `damping: 500`, `mass: 3}` | `object` | **The default easing for all transitions uses springs.** You can customize the spring on a per-element basis by changing the `stiffness`, `damping`, or `mass` values passed in the `spring` object prop. If you provide an `ease` prop (described below), that will be used instead instead of a spring. [Explore the spring setting options here.](https://codepen.io/aholachek/full/bKmZbV/) |
214-
| ease | `easeOutExpo` | `string` | This string should refer to [one of the available easing options.](https://codepen.io/aholachek/full/bKmZbV/) This prop will override the easing specified in the parent `Flipped` component. |
215-
| duration | `250` | `number` | Timing for the individual FLIP transition. This is only meaningful if you've specified an `ease` prop, because springs don't take durations. This prop will override the one specified in the parent `Flipped` component if one exists. |
216-
| delay | `0` | `number` | Amount of time to wait before tweening the element position. You can use this to create staggered transitions. |
213+
217214

218215
#### Callback props
219216

demo/src/FlipMove/index.css

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77
margin-bottom: 2rem;
88
}
99

10-
.fm-example>* {
10+
.fm-example > * {
1111
max-width: 900px;
1212
margin: 0 auto;
1313
}
1414

15-
.fm-grid>ul {
15+
.fm-grid > ul {
1616
list-style-type: none;
1717
display: grid;
1818
grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
@@ -34,8 +34,8 @@
3434
margin-top: 2rem;
3535
}
3636

37-
.fm-list>ul,
38-
.fm-grid>ul {
37+
.fm-list > ul,
38+
.fm-grid > ul {
3939
width: 100%;
4040
list-style-type: none;
4141
margin: 0;
@@ -55,15 +55,15 @@
5555
border-radius: 4px;
5656
background-color: white;
5757
overflow: hidden;
58-
transform-origin: 0 0;
59-
box-shadow: 0 0 15px rgba(0, 0, 0, 0.08);
58+
59+
/* box-shadow: 0 0 15px rgba(0, 0, 0, 0.08); */
6060
}
6161

6262
.fm-item h3 {
6363
font-size: 1.1rem;
6464
}
6565

66-
.fm-item>div {
66+
.fm-item > div {
6767
padding: 0 1.5rem;
6868
display: flex;
6969
justify-content: space-between;

demo/src/FlipMove/index.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const data = [
1717
{ id: 7, title: "Fell to the floor but I hit the ground running" }
1818
]
1919

20-
const onElementAppear = type => (el, index) => {
20+
const onElementAppear = (el, index) => {
2121
anime({
2222
targets: el,
2323
opacity: [0, 1],
@@ -43,6 +43,9 @@ const onExit = type => (el, index, removeElement) => {
4343
}
4444
}
4545

46+
const onGridExit = onExit("grid")
47+
const onListExit = onExit("list")
48+
4649
class ListExample extends Component {
4750
state = { type: "list", sort: "ascending", filteredIds: [] }
4851

@@ -54,7 +57,6 @@ class ListExample extends Component {
5457
flipKey={`${this.state.type}-${this.state.sort}-${JSON.stringify(
5558
this.state.filteredIds
5659
)}`}
57-
spring={{ mass: 0.3 }}
5860
>
5961
<div className="fm-fieldsets">
6062
<fieldset>
@@ -150,14 +152,15 @@ class ListExample extends Component {
150152
})
151153
.map(({ title, id }, i) => {
152154
const flipId = `item-${id}`
153-
const delay = i * 45
154155
return (
155156
<Flipped
156157
flipId={flipId}
157-
onAppear={onElementAppear(this.state.type)}
158-
onExit={onExit(this.state.type)}
158+
onAppear={onElementAppear}
159+
onExit={
160+
this.state.type === "grid" ? onGridExit : onListExit
161+
}
159162
key={flipId}
160-
delay={delay}
163+
staggerKey="item"
161164
>
162165
<li className="fm-item">
163166
<Flipped inverseFlipId={flipId} scale>

index.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export interface FlipperProps {
4545
children: React.ReactNode
4646
duration?: number
4747
ease?: string
48-
spring?: Spring
48+
spring?: Spring | string
4949
applyTransformOrigin?: boolean
5050
debug?: boolean
5151
}

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@
2828
"bugs": "https://github.com/aholachek/react-flip-toolkit/issues",
2929
"dependencies": {
3030
"object-assign": "^4.1.1",
31+
"prop-types": "^15.6.2",
3132
"rematrix": "^0.2.2",
32-
"wobble": "^1.5.0",
33-
"prop-types": "^15.6.2"
33+
"wobble": "^1.5.0"
3434
},
3535
"peerDependencies": {
3636
"react": "16.x"
@@ -53,6 +53,8 @@
5353
"parcel": "^1.9.7",
5454
"react": "^16.4.0",
5555
"react-dom": "^16.4.0",
56+
"react-motion": "^0.5.2",
57+
"react-router": "^4.3.1",
5658
"react-test-renderer": "^16.4.1",
5759
"sinon": "^6.1.3"
5860
},

src/Flipped.js

Lines changed: 38 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { Children, cloneElement } from "react"
1+
import React, { Children, cloneElement, PureComponent } from "react"
22
import PropTypes from "prop-types"
33
import { FlipContext, PortalContext } from "./Flipper"
44
import getSpringInterface from "./getSpringInterface"
@@ -23,13 +23,11 @@ const propTypes = {
2323
children: PropTypes.node.isRequired,
2424
inverseFlipId: customPropCheck,
2525
flipId: customPropCheck,
26+
staggerKey: PropTypes.string,
2627
opacity: PropTypes.bool,
2728
translate: PropTypes.bool,
2829
scale: PropTypes.bool,
2930
transformOrigin: PropTypes.string,
30-
ease: PropTypes.string,
31-
duration: PropTypes.number,
32-
delay: PropTypes.number,
3331
spring: PropTypes.shape(getSpringInterface()),
3432
onStart: PropTypes.func,
3533
onComplete: PropTypes.func,
@@ -82,37 +80,42 @@ export function Flipped({
8280
return cloneElement(child, dataAttributes)
8381
}
8482

85-
const FlippedWithContext = ({
86-
children,
87-
flipId,
88-
onAppear,
89-
onDelayedAppear,
90-
onStart,
91-
onComplete,
92-
onExit,
93-
...rest
94-
}) => (
95-
<PortalContext.Consumer>
96-
{portalKey => (
97-
<FlipContext.Consumer>
98-
{data => {
99-
data[flipId] = {
100-
onAppear,
101-
onDelayedAppear,
102-
onStart,
103-
onComplete,
104-
onExit
105-
}
106-
return (
107-
<Flipped flipId={flipId} {...rest} portalKey={portalKey}>
108-
{children}
109-
</Flipped>
110-
)
111-
}}
112-
</FlipContext.Consumer>
113-
)}
114-
</PortalContext.Consumer>
115-
)
83+
class FlippedWithContext extends PureComponent {
84+
render() {
85+
const {
86+
children,
87+
flipId,
88+
onAppear,
89+
onDelayedAppear,
90+
onStart,
91+
onComplete,
92+
onExit,
93+
...rest
94+
} = this.props
95+
return (
96+
<PortalContext.Consumer>
97+
{portalKey => (
98+
<FlipContext.Consumer>
99+
{data => {
100+
data[flipId] = {
101+
onAppear,
102+
onDelayedAppear,
103+
onStart,
104+
onComplete,
105+
onExit
106+
}
107+
return (
108+
<Flipped flipId={flipId} {...rest} portalKey={portalKey}>
109+
{children}
110+
</Flipped>
111+
)
112+
}}
113+
</FlipContext.Consumer>
114+
)}
115+
</PortalContext.Consumer>
116+
)
117+
}
118+
}
116119

117120
FlippedWithContext.propTypes = propTypes
118121

src/Flipper.js

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,29 @@ import PropTypes from "prop-types"
33
import onFlipKeyUpdate from "./flip/index"
44
import { getFlippedElementPositionsBeforeUpdate } from "./flip/getFlippedElementPositions"
55
import getSpringInterface from "./getSpringInterface"
6+
import { isObject } from "./flip/utilities"
67

78
export const FlipContext = createContext("flip")
8-
99
export const PortalContext = createContext("portal")
1010

11+
// https://github.com/chenglou/react-motion/blob/9cb90eca20ecf56e77feb816d101a4a9110c7d70/src/presets.js
12+
const defaults = {
13+
noWobble: { stiffness: 170, damping: 26 },
14+
gentle: { stiffness: 120, damping: 14 },
15+
wobbly: { stiffness: 180, damping: 12 },
16+
stiff: { stiffness: 210, damping: 20 }
17+
}
18+
19+
const getSpringConfig = spring => {
20+
if (Object.keys(defaults).indexOf(spring) !== -1) {
21+
return defaults[spring]
22+
} else if (isObject(spring)) {
23+
return Object.assign(defaults[spring], spring)
24+
} else {
25+
return defaults.noWobble
26+
}
27+
}
28+
1129
class Flipper extends Component {
1230
static propTypes = {
1331
flipKey: PropTypes.oneOfType([
@@ -16,24 +34,17 @@ class Flipper extends Component {
1634
PropTypes.bool
1735
]).isRequired,
1836
children: PropTypes.node.isRequired,
19-
duration: PropTypes.number,
20-
ease: PropTypes.string,
2137
spring: PropTypes.shape(getSpringInterface()),
2238
applyTransformOrigin: PropTypes.bool,
2339
debug: PropTypes.bool,
2440
element: PropTypes.string,
2541
className: PropTypes.string,
26-
portalKey: PropTypes.string
42+
portalKey: PropTypes.string,
43+
// TODO: figure this out
44+
staggerConfig: PropTypes.object
2745
}
2846

2947
static defaultProps = {
30-
// by default, the easing function is a spring
31-
spring: {
32-
stiffness: 1000,
33-
damping: 500,
34-
mass: 3,
35-
overshootClamping: true
36-
},
3748
// but if a ease string is supplied this is the default duration
3849
duration: 250,
3950
applyTransformOrigin: true,
@@ -57,17 +68,16 @@ class Flipper extends Component {
5768
return null
5869
}
5970

60-
componentDidUpdate(prevProps, prevState, cachedFlipChildrenPositions) {
71+
componentDidUpdate(prevProps, prevState, cachedData) {
6172
if (this.props.flipKey !== prevProps.flipKey) {
6273
onFlipKeyUpdate({
63-
cachedFlipChildrenPositions,
74+
cachedFlipChildrenPositions: cachedData.flippedElementPositions,
75+
cachedOrderedFlipIds: cachedData.cachedOrderedFlipIds,
6476
containerEl: this.el,
65-
duration: this.props.duration,
66-
ease: this.props.ease,
6777
inProgressAnimations: this.inProgressAnimations,
6878
flipCallbacks: this.flipCallbacks,
6979
applyTransformOrigin: this.props.applyTransformOrigin,
70-
spring: this.props.spring,
80+
spring: getSpringConfig(this.props.spring),
7181
debug: this.props.debug,
7282
portalKey: this.props.portalKey
7383
})

0 commit comments

Comments
 (0)