Skip to content

Commit

Permalink
feat(bullet): switch from react-motion to react-spring
Browse files Browse the repository at this point in the history
  • Loading branch information
wyze authored and plouc committed Nov 9, 2020
1 parent 8dd28fe commit 04f0709
Show file tree
Hide file tree
Showing 15 changed files with 240 additions and 288 deletions.
5 changes: 2 additions & 3 deletions packages/bullet/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,11 @@
"@nivo/legends": "0.64.0",
"@nivo/tooltip": "0.64.0",
"d3-scale": "^3.0.0",
"react-motion": "^0.5.2"
"react-spring": "^8.0.27"
},
"devDependencies": {
"@nivo/core": "*",
"@types/d3-scale": "^3.2.1",
"@types/react-motion": "^0.0.29"
"@types/d3-scale": "^3.2.1"
},
"peerDependencies": {
"@nivo/core": "^0.64.0",
Expand Down
9 changes: 2 additions & 7 deletions packages/bullet/src/Bullet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ export const Bullet = (props: BulletSvgProps) => {
theme: _theme,

animate,
motionStiffness,
motionDamping,
motionConfig,

isInteractive,
onRangeClick,
Expand Down Expand Up @@ -89,8 +88,7 @@ export const Bullet = (props: BulletSvgProps) => {
isInteractive={isInteractive}
theme={theme}
animate={animate}
motionStiffness={motionStiffness}
motionDamping={motionDamping}
motionConfig={motionConfig}
>
{({ showTooltip, hideTooltip }: TooltipHandlers<unknown>) => (
<SvgWrapper
Expand Down Expand Up @@ -125,9 +123,6 @@ export const Bullet = (props: BulletSvgProps) => {
markerColors={markerColors}
theme={theme}
axisPosition={axisPosition}
animate={animate}
motionStiffness={motionStiffness}
motionDamping={motionDamping}
showTooltip={showTooltip}
hideTooltip={hideTooltip}
onRangeClick={onRangeClick}
Expand Down
142 changes: 44 additions & 98 deletions packages/bullet/src/BulletItem.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import React from 'react'
import { Motion, spring } from 'react-motion'
import { AnimatedValue, useSpring, animated } from 'react-spring'
import { Axis } from '@nivo/axes'
// @ts-ignore
import { getColorScale, defaultTheme, extendDefaultTheme } from '@nivo/core'
import { getColorScale, defaultTheme, extendDefaultTheme, useMotionConfig } from '@nivo/core'
import { BasicTooltip } from '@nivo/tooltip'
import { stackValues } from './compute'
import { defaultProps } from './props'
import { BulletMarkers } from './BulletMarkers'
import { BulletRects } from './BulletRects'
import { BulletItemProps } from './types'
Expand Down Expand Up @@ -51,10 +50,6 @@ export const BulletItem = ({

showTooltip,
hideTooltip,

animate = defaultProps.animate,
motionStiffness = defaultProps.motionStiffness,
motionDamping = defaultProps.motionDamping,
}: BulletItemProps) => {
const theme = extendDefaultTheme(defaultTheme, _theme)

Expand All @@ -71,12 +66,6 @@ export const BulletItem = ({
color: markerColorScale(markerColorScale.type === 'sequential' ? marker : index) as string,
}))

const motionProps = {
animate,
motionStiffness,
motionDamping,
}

const rangeNodes = (
<BulletRects
data={computedRanges}
Expand Down Expand Up @@ -106,7 +95,6 @@ export const BulletItem = ({
onClick={(range, event) => {
onRangeClick?.({ id, ...range }, event)
}}
{...motionProps}
/>
)

Expand All @@ -133,7 +121,6 @@ export const BulletItem = ({
onClick={(marker, event) => {
onMarkerClick?.({ id, ...marker }, event)
}}
{...motionProps}
/>
)

Expand Down Expand Up @@ -186,90 +173,49 @@ export const BulletItem = ({
</g>
)

if (animate !== true) {
return (
<g transform={`translate(${x},${y})`}>
{rangeNodes}
<BulletRects
data={computedMeasures}
scale={scale}
layout={layout}
reverse={reverse}
x={0}
y={(height - measureHeight) / 2}
width={width}
height={measureHeight}
component={measureComponent}
onMouseEnter={(measure, event) => {
showTooltip(
<BasicTooltip
id={<strong>{measure.v1}</strong>}
enableChip={true}
color={measure.color}
/>,
event
)
}}
onMouseLeave={hideTooltip}
onClick={(measure, event) => {
onMeasureClick?.({ id, ...measure }, event)
}}
{...motionProps}
/>
{axis}
{markerNodes}
{titleNode}
</g>
)
}

const springConfig = {
damping: motionDamping,
stiffness: motionStiffness,
}
const { animate, config: springConfig } = useMotionConfig()
const animatedProps = useSpring({
measuresY: (height - measureHeight) / 2,
transform: `translate(${x},${y})`,
config: springConfig,
immediate: !animate,
}) as AnimatedValue<{
measuresY: number;
transform: string;
}>

return (
<Motion
style={{
x: spring(x, springConfig),
y: spring(y, springConfig),
measuresY: spring((height - measureHeight) / 2, springConfig),
}}
>
{values => (
<g transform={`translate(${values.x},${values.y})`}>
{rangeNodes}
<BulletRects
data={computedMeasures}
scale={scale}
layout={layout}
reverse={reverse}
x={0}
y={values.measuresY}
width={width}
height={measureHeight}
component={measureComponent}
onMouseEnter={(measure, event) => {
showTooltip(
<BasicTooltip
id={<strong>{measure.v1}</strong>}
enableChip={true}
color={measure.color}
/>,
event
)
}}
onMouseLeave={hideTooltip}
onClick={(measure, event) => {
onMeasureClick?.({ id, ...measure }, event)
}}
{...motionProps}
/>
{axis}
{markerNodes}
{titleNode}
</g>
)}
</Motion>
<animated.g transform={animatedProps.transform}>
{rangeNodes}
<BulletRects
animatedProps={animatedProps}
data={computedMeasures}
scale={scale}
layout={layout}
reverse={reverse}
x={0}
y={0}
width={width}
height={measureHeight}
component={measureComponent}
onMouseEnter={(measure, event) => {
showTooltip(
<BasicTooltip
id={<strong>{measure.v1}</strong>}
enableChip={true}
color={measure.color}
/>,
event
)
}}
onMouseLeave={hideTooltip}
onClick={(measure, event) => {
onMeasureClick?.({ id, ...measure }, event)
}}
/>
{axis}
{markerNodes}
{titleNode}
</animated.g>
)
}
108 changes: 45 additions & 63 deletions packages/bullet/src/BulletMarkers.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import React from 'react'
import { TransitionMotion, spring } from 'react-motion'
import { useTransition } from 'react-spring'
// @ts-ignore
import { useMotionConfig } from '@nivo/core'
// @ts-ignore
import { interpolateColor, getInterpolatedColor } from '@nivo/colors'
import { BulletMarkersProps, ComputedMarkersDatum } from './types'
import {
BulletMarkersProps,
ComputedMarkersDatum,
MarkerWithPosition,
PositionWithColor,
} from './types'

type MouseEventWithDatum = (
datum: ComputedMarkersDatum,
Expand Down Expand Up @@ -45,76 +52,51 @@ export const BulletMarkers = ({
height,
markerSize,
component,
animate,
motionStiffness,
motionDamping,
onMouseEnter,
onMouseLeave,
onClick,
}: BulletMarkersProps & EventHandlers) => {
const getPosition = getPositionGenerator({ layout, reverse, scale, height, markerSize })

if (animate !== true) {
return (
<>
{markers.map(marker =>
React.createElement(component, {
key: marker.index,
...marker,
...getPosition(marker),
data: marker,
onMouseEnter: event => onMouseEnter(marker, event),
onMouseMove: event => onMouseEnter(marker, event),
onMouseLeave: event => onMouseLeave(marker, event),
onClick: event => onClick(marker, event),
})
)}
</>
)
}

const springConfig = {
damping: motionDamping,
stiffness: motionStiffness,
}
const { animate, config: springConfig } = useMotionConfig()
const transitions = useTransition<MarkerWithPosition, PositionWithColor>(
markers.map(marker => ({ ...marker, position: getPosition(marker) })),
markers.map(marker => `${marker.index}`),
{
enter: ({ color, position }: MarkerWithPosition) => ({
color,
transform: `rotate(${position.rotation}, ${position.x}, ${position.y})`,
x: position.x,
y1: position.y - position.size / 2,
y2: position.y + position.size / 2,
}),
update: ({ color, position }: MarkerWithPosition) => ({
color,
transform: `rotate(${position.rotation}, ${position.x}, ${position.y})`,
x: position.x,
y1: position.y - position.size / 2,
y2: position.y + position.size / 2,
}),
config: springConfig,
immediate: !animate,
} as any
)

return (
<TransitionMotion
styles={markers.map((marker, i) => {
const position = getPosition(marker)

return {
key: `${i}`,
<>
{transitions.map(({ item: { position, ...marker }, props, key }) =>
React.createElement(component, {
key,
...marker,
...position,
animatedProps: props,
data: marker,
style: {
x: spring(position.x, springConfig),
y: spring(position.y, springConfig),
size: spring(position.size, springConfig),
rotation: spring(position.rotation, springConfig),
...interpolateColor(marker.color, springConfig),
},
}
})}
>
{interpolatedStyles => (
<>
{interpolatedStyles.map(({ key, style, data: marker }) => {
const color = getInterpolatedColor(style)

return React.createElement(component, {
key,
...marker,
...style,
color,
data: marker,
onMouseEnter: event => onMouseEnter(marker, event),
onMouseMove: event => onMouseEnter(marker, event),
onMouseLeave: event => onMouseLeave(marker, event),
onClick: event => onClick(marker, event),
})
})}
</>
onMouseEnter: event => onMouseEnter(marker, event),
onMouseMove: event => onMouseEnter(marker, event),
onMouseLeave: event => onMouseLeave(marker, event),
onClick: event => onClick(marker, event),
})
)}
</TransitionMotion>
</>
)
}
15 changes: 6 additions & 9 deletions packages/bullet/src/BulletMarkersItem.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,21 @@
import React from 'react'
import { BulletMarkersItemProps } from './types'
import { animated } from 'react-spring'

export const BulletMarkersItem = ({
x,
y,
size,
rotation,
color,
animatedProps: { color, transform, x, y1, y2 },
onMouseEnter,
onMouseMove,
onMouseLeave,
onClick,
}: BulletMarkersItemProps) => {
return (
<line
transform={`rotate(${rotation}, ${x}, ${y})`}
<animated.line
transform={transform}
x1={x}
x2={x}
y1={y - size / 2}
y2={y + size / 2}
y1={y1}
y2={y2}
fill="none"
stroke={color}
strokeWidth="5"
Expand Down
Loading

0 comments on commit 04f0709

Please sign in to comment.