Skip to content

Commit

Permalink
Add useSpring
Browse files Browse the repository at this point in the history
  • Loading branch information
pomber committed Mar 3, 2019
1 parent 11526b0 commit 0f88685
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 0 deletions.
46 changes: 46 additions & 0 deletions src/use-spring.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// based on https://github.com/streamich/react-use/blob/master/src/useSpring.ts
import { SpringSystem } from "rebound";
import { useState, useEffect } from "react";

export default function useSpring({
target = 0,
current = null,
tension = 0,
friction = 10
}) {
const [spring, setSpring] = useState(null);
const [value, setValue] = useState(target);

useEffect(() => {
const listener = {
onSpringUpdate: spring => {
const value = spring.getCurrentValue();
setValue(value);
}
};

if (!spring) {
const newSpring = new SpringSystem().createSpring(tension, friction);
newSpring.setCurrentValue(target);
setSpring(newSpring);
newSpring.addListener(listener);
return;
}

return () => {
spring.removeListener(listener);
setSpring(null);
};
}, [tension, friction]);

useEffect(() => {
if (spring) {
spring.setEndValue(target);
if (current != null) {
spring.setCurrentValue(current);
}
}
}, [target, current]);

return value;
}
66 changes: 66 additions & 0 deletions src/use-spring.story.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import React from "react";
import { storiesOf } from "@storybook/react";
import useSpring from "./use-spring";

function Test() {
const [{ target, current }, setState] = React.useState({
target: 0,
current: null
});
const value = useSpring({ target, current });

return (
<div>
<div style={{ display: "flex" }}>
<span style={{ flex: 0.3 }}>Target</span>
<input
value={target}
onChange={e =>
setState({
target: +e.target.value,
current: null
})
}
style={{ flex: 1 }}
type="range"
/>
<span style={{ flex: 0.3 }}>{target}</span>
</div>
<div style={{ display: "flex" }}>
<span style={{ flex: 0.3 }}>Current</span>
<input
value={current}
onChange={e =>
setState({
target: +e.target.value,
current: +e.target.value
})
}
style={{ flex: 1 }}
type="range"
/>
<span style={{ flex: 0.3 }}>{current}</span>
</div>
<div style={{ display: "flex" }}>
<span style={{ flex: 0.3 }}>Value</span>
<input value={value} type="range" readOnly style={{ flex: 1 }} />
<span style={{ flex: 0.3 }}>{Math.round(value * 1000) / 1000}</span>
</div>
</div>
);
}

storiesOf("useSpring", module).add("test", () => (
<div
style={{
display: "flex",
alignItems: "center",
justifyContent: "center",
height: "90vh"
}}
>
<div style={{ width: "60%" }}>
<Test />
</div>
</div>
));

0 comments on commit 0f88685

Please sign in to comment.