{"id":20674702,"url":"https://github.com/asbjornh/use-spring-effect","last_synced_at":"2025-03-10T18:27:30.736Z","repository":{"id":57388400,"uuid":"217037469","full_name":"asbjornh/use-spring-effect","owner":"asbjornh","description":"React hooks for spring animated side effects","archived":false,"fork":false,"pushed_at":"2020-01-11T16:47:47.000Z","size":483,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-10-16T01:31:56.965Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/asbjornh.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-10-23T11:10:26.000Z","updated_at":"2020-03-25T04:26:30.000Z","dependencies_parsed_at":"2022-09-09T18:12:55.348Z","dependency_job_id":null,"html_url":"https://github.com/asbjornh/use-spring-effect","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asbjornh%2Fuse-spring-effect","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asbjornh%2Fuse-spring-effect/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asbjornh%2Fuse-spring-effect/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asbjornh%2Fuse-spring-effect/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/asbjornh","download_url":"https://codeload.github.com/asbjornh/use-spring-effect/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242901508,"owners_count":20203953,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-16T21:06:44.807Z","updated_at":"2025-03-10T18:27:30.691Z","avatar_url":"https://github.com/asbjornh.png","language":"TypeScript","readme":"# useSpringEffect\n\n[![npm version](https://img.shields.io/npm/v/use-spring-effect)](https://npmjs.com/package/use-spring-effect)\n![](https://img.shields.io/badge/dependencies-1-green)\n![](https://img.shields.io/bundlephobia/min/use-spring-effect)\n\nReact hooks for spring-animated side effects.\n\n```\nnpm install use-spring-effect\n```\n\nSpring dynamics are a great alternative to the traditional duration/easing model of UI animation. There are lots of good alternatives out there, like `react-motion`, `react-spring` or `animated`. Most of these, however, rely on React state. Running animations through state in React can sometimes come at a significant performance cost, as React desperately attempts to evaluate huge subtrees 60 times per second.\n\n`use-spring-effect` attempts to solve this problem by exposing a spring as a side effect rather than through state. If this makes you uncomfortable there is also a stateful `useSpring` included.\n\nIf you're not sure what spring animation is, Cheng Lou has an [excellent talk](https://www.youtube.com/watch?v=1tavDv5hXpo) about it.\n\n## TDLR usage\n\n```jsx\n// Animate scroll position\nimport useSpringEffect from 'use-spring-effect';\n\nconst Component = () =\u003e {\n  const [transitionTo] = useSpringEffect(0, value =\u003e {\n    document.scrollingElement.scrollTop = value;\n  });\n\n  return \u003cbutton onClick={() =\u003e transitionTo(1000)}\u003eScroll!\u003c/button\u003e;\n};\n```\n\n```jsx\n// Animate the transform property of .box\nimport { useSpringStyle } from 'use-spring-effect';\n\nconst Component = () =\u003e {\n  const [ref, transitionTo] = useSpringStyle(0, value =\u003e ({\n    transform: `translateX(${value}px)`\n  }));\n\n  return (\n    \u003cdiv\u003e\n      \u003cdiv className=\"box\" ref={ref} /\u003e\n      \u003cbutton onClick={() =\u003e transitionTo(100)}\u003eMove!\u003c/button\u003e\n    \u003c/div\u003e\n  );\n};\n```\n\n## API\n\n### useSpringEffect\n\n```js\nimport useSpringEffect from 'use-spring-effect';\nconst [transitionTo, setValue] = useSpringEffect();\n```\n\n```ts\nfunction useSpringEffect(\n  initialValue: number,\n  onUpdate: (value: number) =\u003e void,\n  configOrDependencies?: SpringConfig | any[],\n  dependencies?: any[]\n): ((value: number) =\u003e void)[];\n```\n\nSee usage example above. The third argument can be either a dependency array or a `SpringConfig` (see below). When `transitionTo` is called with a value, the spring will start animating towards that value. `setValue` sets the value immediately, without animation.\n\n### useSpringStyle\n\n```js\nimport { useSpringStyle } from 'use-spring-effect';\nconst [ref, transitionTo, setValue] = useSpringStyle();\n```\n\n```ts\nfunction useSpringStyle(\n  initialValue: number,\n  getStyle: (value: number) =\u003e InlineStyle,\n  configOrDependencies?: SpringConfig | any[],\n  dependencies = []\n): [React.Dispatch\u003cany\u003e, UpdateSpring, UpdateSpring];\n\ntype UpdateSpring = (\n  value: number | ((element: HTMLElement) =\u003e number)\n) =\u003e void;\n```\n\nSee usage example above. This hook returns a `ref` that needs to be connected to the element you want to apply animation to. While animating the hook will apply the inline styles to the `ref`. The second argument to `useSpringStyle` is a function that is called with the current spring value and should return an object of inline styles. `transitionTo` and `setValue` take a number or a function. In case of a function, it will be called with the animated element (example below).\n\n```jsx\nimport { useSpringStyle } from 'use-spring-effect';\n\nconst Component = () =\u003e {\n  const [ref, transitionTo] = useSpringStyle(0, value =\u003e ({\n    transform: `translateX(${value}px)`\n  }));\n\n  return (\n    \u003cdiv\u003e\n      \u003cdiv className=\"box\" ref={ref} /\u003e\n      \u003cbutton onClick={() =\u003e transitionTo(element =\u003e element.offsetWidth)}\u003e\n        Move!\n      \u003c/button\u003e\n    \u003c/div\u003e\n  );\n};\n```\n\n### useMultiSpringEffect\n\n```js\nimport { useMultiSpringEffect } from 'use-spring-effect';\nconst [transitionTo, setValue] = useMultiSpringEffect();\n```\n\n```ts\nfunction useMultiSpringEffect(\n  initialValue: NumberDict,\n  onUpdate: (value: NumberDict) =\u003e void,\n  configOrDependencies?: SpringConfig | any[],\n  dependencies?: any[]\n): ((value: NumberDict) =\u003e void)[];\n\ntype NumberDict = { [key: string]: number };\n```\n\nThis hook works the same way as `useSpringEffect` except for the fact that it can animate multiple values at the same time. This is useful for stuff like tracking the mouse position or other things that depend on two or more values. You can't add other properties to the object other than those specified in `initialValue` (but you don't need to update all of the properties at the same time)\n\nExample (moves `.box` when the mouse is moved over the outer div):\n\n```jsx\nimport { useMultiSpringEffect } from '../../source/index';\n\nconst Component = () =\u003e {\n  const [el, setEl] = React.useState();\n  const [transitionTo] = useMultiSpringEffect(\n    { x: 0, y: 0 },\n    ({ x, y }) =\u003e {\n      if (el) el.style.transform = `translate(${x}px, ${y}px)`;\n    },\n    [el]\n  );\n  const onMouseMove = e =\u003e {\n    transitionTo({\n      x: e.clientX,\n      y: e.clientY\n    });\n  };\n\n  return (\n    \u003cdiv onMouseMove={onMouseMove}\u003e\n      \u003cdiv className=\"box\" ref={setEl} /\u003e\n    \u003c/div\u003e\n  );\n};\n```\n\n### useSpring\n\n```js\nimport { useSpring } from 'use-spring-effect';\nconst [value, transitionTo, setValue] = useSpring();\n```\n\n```ts\nfunction useSpring(\n  initialValue: number,\n  configOrDependencies?: SpringConfig | any[],\n  dependencies?: any[]\n): [number, (v: number) =\u003e void, (v: number) =\u003e void] {\n```\n\nThis hook returns an animated `value`. Otherwise this hook works like `useSpringEffect`.\n\n### SpringConfig\n\n```ts\ntype SpringConfig = {\n  stiffness?: number;\n  damping?: number;\n  precision?: number;\n};\n```\n\n**`stiffness: number = 200`**\n\nStiffness controls how \"fast\" your animation will be. Higher values result in faster motion.\n\n**`damping: number = 10`**\n\nDamping controls how much friction is applied to the spring. You can think about this as how \"wobbly\" the resulting motion is. Lower values result in more wobbly-ness.\n\n**`precision: number = 100`**\n\nUsed to determine when to stop animating. With a precision of `0` the spring will reach its end value immediately. With really high values it might keep animating fractions of a pixel for a long time. Tweak this value if animations end abruptly or linger for too long. When tweaking this value you'll want to make big changes in order to see an effect (like adding/removing zeros).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasbjornh%2Fuse-spring-effect","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fasbjornh%2Fuse-spring-effect","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasbjornh%2Fuse-spring-effect/lists"}