/
BulletRects.tsx
80 lines (75 loc) · 2.38 KB
/
BulletRects.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import React, { useMemo } from 'react'
import { useTransition, animated, to } from 'react-spring'
// @ts-ignore
import { useMotionConfig } from '@nivo/core'
import { computeRects } from './compute'
import { BulletRectsProps, BulletRectComputedRect, BulletRectAnimatedProps } from './types'
export const BulletRects = ({
animatedProps,
data,
layout,
y,
component,
reverse,
scale,
height,
onMouseEnter,
onMouseLeave,
onClick,
}: BulletRectsProps) => {
const rects = useMemo(
() =>
computeRects({
data,
layout,
reverse,
scale,
height,
}),
[data, layout, reverse, scale, height]
)
const getTransform = (value: number) =>
`translate(${layout === 'horizontal' ? 0 : value},${layout === 'horizontal' ? value : 0})`
const transform = animatedProps ? to(animatedProps.measuresY, getTransform) : getTransform(y)
const { animate, config: springConfig } = useMotionConfig()
const transition = useTransition<BulletRectComputedRect, BulletRectAnimatedProps>(rects, {
keys: rect => `${rect.data.index}`,
enter: rect => ({
x: rect.x,
y: rect.y,
width: rect.width,
height: rect.height,
color: rect.data.color,
}),
update: rect => ({
x: rect.x,
y: rect.y,
width: rect.width,
height: rect.height,
color: rect.data.color,
}),
config: springConfig,
immediate: !animate,
})
return (
<animated.g transform={transform}>
{transition((props, rect) =>
React.createElement(component, {
key: rect.data.index,
index: rect.data.index,
animatedProps: props,
data: rect.data,
x: props.x.get(),
y: props.y.get(),
width: to(props.width, value => Math.max(value, 0)).get(),
height: to(props.height, value => Math.max(value, 0)).get(),
color: props.color.get(),
onMouseEnter,
onMouseMove: onMouseEnter,
onMouseLeave,
onClick,
})
)}
</animated.g>
)
}