Skip to content

Commit 665fe01

Browse files
committed
improved masonry grid
1 parent 2a516a1 commit 665fe01

File tree

1 file changed

+47
-20
lines changed

1 file changed

+47
-20
lines changed

demos/hooks/masonry-grid/index.js

Lines changed: 47 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,67 @@
11
import React, { useState, useEffect } from 'react'
2-
import { useTransition, animated as a, config } from 'react-spring'
2+
import { useTransition, animated as a, config, interpolate } from 'react-spring'
33
import shuffle from 'lodash/shuffle'
44
import { useMeasure, useMedia } from './helpers'
55
import data from './data'
66
import './styles.css'
77

8+
const FAST_MODE = true
9+
810
export default function App() {
911
const columns = 6
1012
const [bind, { width }] = useMeasure()
1113
const [items, set] = useState(data)
1214

13-
let heights = new Array(columns).fill(0)
14-
let gridItems = items.map((child, i) => {
15-
const column = heights.indexOf(Math.min(...heights))
16-
const xy = [
17-
(width / columns) * column,
18-
(heights[column] += child.height / 2) - child.height / 2,
19-
]
20-
return { ...child, xy, width: width / columns, height: child.height / 2 }
21-
})
15+
const heights = new Array(columns).fill(0)
16+
const gridItems = width
17+
? items.map((child, i) => {
18+
const column = heights.indexOf(Math.min(...heights))
19+
const height = child.height / 2
20+
return {
21+
...child,
22+
xy: [
23+
(width / columns) * column,
24+
(heights[column] += height) - height,
25+
],
26+
width: width / columns,
27+
height,
28+
}
29+
})
30+
: []
2231

32+
const trail = FAST_MODE ? 25 : 80
2333
const transitions = useTransition(gridItems, item => item.css, {
24-
from: ({ xy, width, height }) => ({ xy, width, height, opacity: 0 }),
25-
enter: ({ xy, width, height }) => ({ xy, width, height, opacity: 1 }),
26-
update: ({ xy, width, height }) => ({ xy, width, height }),
27-
leave: { height: 0, opacity: 0 },
34+
from: ({ xy, width, height }) => ({
35+
xy,
36+
width,
37+
height,
38+
opacity: 0,
39+
scale: 0.8,
40+
}),
41+
enter: (_, i) => ({ scale: 1, opacity: 1, delay: i * trail }),
42+
update: ({ xy }) => ({ xy }),
43+
leave: { scale: 0.8, opacity: 0 },
2844
config: config.stiff,
29-
trail: 25,
3045
})
3146

32-
useEffect(() => void setInterval(() => set(shuffle), 2000), [])
47+
useEffect(() => every(FAST_MODE ? 1000 : 2500, () => set(shuffle)), [
48+
gridItems.length,
49+
])
3350

3451
return (
35-
<div className="mgrid">
52+
<div
53+
className="mgrid"
54+
onClick={() => {
55+
set(items.length ? [] : data)
56+
}}>
3657
<div {...bind} className="mgrid-list">
37-
{transitions.map(({ item, props: { xy, ...rest }, key }) => (
58+
{transitions.map(({ item, props: { xy, scale, ...rest }, key }) => (
3859
<a.div
3960
key={key}
4061
style={{
41-
transform: xy.interpolate(
42-
(x, y) => `translate3d(${x}px,${y}px,0)`
62+
transform: interpolate(
63+
[xy, scale],
64+
([x, y], s) => `translate3d(${x}px,${y}px,0) scale(${s})`
4365
),
4466
...rest,
4567
}}>
@@ -50,3 +72,8 @@ export default function App() {
5072
</div>
5173
)
5274
}
75+
76+
function every(ms, cb) {
77+
const id = setInterval(cb, ms)
78+
return () => clearInterval(id)
79+
}

0 commit comments

Comments
 (0)