{"id":13788917,"url":"https://github.com/jhsware/inferno-animation","last_synced_at":"2025-05-12T03:30:55.689Z","repository":{"id":92670840,"uuid":"92815700","full_name":"jhsware/inferno-animation","owner":"jhsware","description":"Animate Inferno.js components on mount and dismount","archived":true,"fork":false,"pushed_at":"2022-10-13T15:23:32.000Z","size":556,"stargazers_count":13,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-11-18T02:39:06.385Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jhsware.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2017-05-30T09:09:18.000Z","updated_at":"2023-01-27T20:16:36.000Z","dependencies_parsed_at":"2023-06-14T05:15:43.231Z","dependency_job_id":null,"html_url":"https://github.com/jhsware/inferno-animation","commit_stats":null,"previous_names":[],"tags_count":48,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jhsware%2Finferno-animation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jhsware%2Finferno-animation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jhsware%2Finferno-animation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jhsware%2Finferno-animation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jhsware","download_url":"https://codeload.github.com/jhsware/inferno-animation/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253667956,"owners_count":21944944,"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-08-03T21:00:55.762Z","updated_at":"2025-05-12T03:30:55.372Z","avatar_url":"https://github.com/jhsware.png","language":"JavaScript","funding_links":[],"categories":["Summary"],"sub_categories":["Components"],"readme":"# inferno-animation\n[![gzip size](http://img.badgesize.io/https://unpkg.com/inferno-animation/dist/cjs/index.min.js?compression=gzip)](https://unpkg.com/inferno-animation/dist/cjs/index.min.js)\n\n**NOTE! As of Inferno 8.0 there is native support for animations. The package inferno-animation will be part of [the core repos](https://github.com/infernojs/inferno/tree/master/packages/inferno-animation) and performance will be greatly improved.** Only minor changes are required to migrate. Code examples can be found in the [animation demos](https://github.com/infernojs/inferno/tree/master/docs)\n\n## Compatibility\ninferno-animation 7.x supports Inferno v7\n\ninferno-animation 6.x supports Inferno v6\n\ninferno-animation 5.x supports Inferno v5\n\ninferno-animation 4.x supports Inferno v4\n\ninferno-animation 3.x supports Inferno v3\n\n## About\nLibrary to animate Inferno components on mount and dismount. Also supports cross-fade, where height and/or\nwidth animates from source size to target size.\n\nThis lib allows you to animate all css-properties including width and height using css-animations.\nTimeouts are automatically calculated based on the provided CSS rules.\n\nIMPORTANT: This lib assumes you have set `box-sizing: border-box;` on the elements being animated!\n\nIf the component that is added has `display: none` no height calculations will be performed.\n\nYou can animate your components by adding the animation helpers to `componentDidMount` and `componentWillUnmoun` \nor by wrapping your component in the `\u003cAnimated /\u003e` component.\n\nIn lists, unlike `ReactTransitionGroup`, you need to wrap every item to animate them.\n\nTo perform a cross-fade you wrap the components in a `\u003cCrossFade /\u003e` component.\nNote: you can only have one (1) mounting and one (1) unmounting component during a cross-fade. To cross-fade\nlists you need to wrap each of them in a container.\n\nCurrently tested on (polyfills from https://polyfill.io):\n- Chrome/FF/Safari (latest) on macOS 10.12 (Sierra)\n- IE10/IE11 on Windows 7\n- Edge on Windows 10\n\nRun the visual tests (instructions at end of this document) to see the animations in practice. Enjoy!\n\n## Debuggging animations\nThere is a setTimeout fallback in case transitions are interrupted to make sure they clean up properly. This\ntimeout isn't aware of Chrome Devtools animation slowdown feature. In order to debug animations you can disable\nthese timeouts by setting:\n\n```\nwindow.debugAnimations = true\n\n```\n\n## Animate component on add or remove\n\nAdd calls on `componentDidMount` and `componentWillUnmount` to animate a component when it is added or removed.\nNOTE: Make sure you set a `key` for the component or it won't be animated properly.\n\nYou can use this to animate single components or components in a list.\n\nBoth `animateOnAdd` and `animateOnRemove` allow you to animate **width** and **height**.\n\n```JavaScript\nimport { animateOnAdd, animateOnRemove } from 'inferno-animation'\n\ncomponentDidMount () {\n  animateOnAdd(this, 'PageAnimation')\n}\n\ncomponentWillUnmount () {\n  animateOnRemove(this, 'PageAnimation')\n}\n```\n\n### Passing custom class names and callback\nYou can optionally pass custom class names to be used during the animation. You can also\npass a callback which is fired when the animations are finished. This is the firing order:\n\n1. add **start**\n2. add **active**\n3. add **end**, remove **start**\n  - the animation plays and when done:\n4. remove **active**, remove **end**\n5. call optional **callback**\n6. if leaving, remove the element\n\nExample:\n\n```JavaScript\nimport { animateOnAdd, animateOnRemove } from 'inferno-animation'\nimport { findDOMNode } from 'inferno-extras'\n\nconst enterCls = {\n  start: 'willEnter',\n  active: 'animationActiveClass',\n  end: 'didEnterClass'\n}\ncomponentDidMount () {\n  animateOnAdd(findDOMNode(this), enterCls, (el) =\u003e {\n    // Element 'el' is now visible\n  })\n}\n\nconst leaveCls = {\n  start: 'willLeaveClass',\n  active: 'animationActiveClass',\n  end: 'didLeaveClass'\n}\ncomponentWillUnmount () {\n  animateOnRemove(findDOMNode(this), leaveCls, (el) =\u003e { \n    // Element 'el' will be removed when this callback has returned\n  })\n}\n```\n\n## Use wrapper to animate children\nYou can use the prodvided wrapper `Animated` to animate components. It is useful if you want to\nreuse a component in different places with separate animations, or when you use other components\nthat you can't modify.\n\n```JavaScript\nimport { Animated } from 'inferno-animation'\n\n\u003cAnimated key={...} prefix=\"PageAnimation\"\u003e\n  \u003cMyListItem data={...} /\u003e\n\u003c/Animated\u003e\n\n/* Specify what element to render by passing attribute \"el\" */\n\u003cAnimated key={...} el=\"li\" prefix=\"PageAnimation\"\u003e\n  \u003cMyListItem data={...} /\u003e\n\u003c/Animated\u003e\n\n/* \"tag\" is an alias for \"el\" to harmonise with inferno-bootstrap */\n\u003cAnimated key={...} tag=\"li\" prefix=\"PageAnimation\"\u003e\n  \u003cMyListItem data={...} /\u003e\n\u003c/Animated\u003e\n\n\u003cAnimated key={...} className=\"Something\" prefix=\"PageAnimation\"\u003e\n  \u003cMyListItem data={...} /\u003e\n\u003c/Animated\u003e\n```\n\nNote you can get a reference to the rendered dom element by passing a callback as prop `domRef`:\n\n```JavaScript\n\u003cAnimated key={...} domRef={(domEl) =\u003e this._el = domEl} prefix=\"PageAnimation\"\u003e...\u003c/Animated\u003e\n```\n\nWhen you add and remove the `Animated` container it will animate according to your CSS-rules.\n\n## Define your animations with CSS\n\n```css\n.PageAnimation-enter {\n  /* Enter animation start state */ \n}\n\n.PageAnimation-enter-active {\n  /* Enter animation transitions */\n}\n\n.PageAnimation-enter-end {\n  /* Enter animation end state */\n}\n\n/* ----------------------------- */\n\n.PageAnimation-leave {\n  /* Leave animation start state */\n}\n\n.PageAnimation-leave-active {\n  /* Leave animation transitions */ \n}\n\n.PageAnimation-leave-end {\n  /* Leave animation end state */\n}\n```\n\nA note on animation timings. I use these rules of thumb:\n\n- 0.1s is too fast, brain doesn't really have time to react\n- 0.2s gives a sense of smoothness but feels instant\n- 0.3s is fast but noticeable\n- 0.5s is smooth\n- \\\u003e0.5s user starts feeling that they are waiting for animation to end, make sure what ever you use it for is worth it\n\nI often combine a fade and height animation with different timings to get a nice result.\n\n### Sample: Animate height and fade-in/out\n```scss\n.PageAnimation {\n    \u0026-leave {\n        // Leave animation start state\n        // width: auto;\n        opacity: 1;\n    }\n\n    \u0026-leave-active {\n        // Leave animation transitions\n        overflow: hidden;\n        transition: height 0.3s ease-out, opacity 0.2s ease-in;\n    }\n\n    \u0026-leave-end {\n        // Leave animation end state\n        // width: 0;\n        height: 0;\n        opacity: 0;\n    }\n\n    \u0026-enter {\n        // Enter animation start state\n        height: 0;\n        opacity: 0;\n    }\n\n    \u0026-enter-active {\n        // Enter animation transitions\n        transition: height 0.2s ease-out, opacity 0.5s ease-in;\n    }\n\n    \u0026-enter-end {\n        // Enter animation end state\n        opacity: 1;\n    }\n}\n```\n\n## Cross-fade between components\n\nThis example shows how to cross-fade between the components `PageOne` and `PageTwo`. The CrossFade components\nadds a class `InfernoAnimation--noAnim` when being mounted to prevent triggering the cross-fade animation on\nmount.\n\n```JavaScript\nimport { CrossFade } from 'inferno-animation'\n\n...\n\nrender () {\n  return (\n    \u003cCrossFade className=\"CrossFadeContainer\" prefix=\"CrossFade--Animation\"\u003e\n      {this.state.visible === 'one' \u0026\u0026 \u003cPageOne /\u003e}\n      {this.state.visible === 'two' \u0026\u0026 \u003cPageTwo /\u003e}\n    \u003c/CrossFade\u003e\n  )\n}\n```\n\n### Sample cross-fade animation\n```css\n.CrossFade--Animation-cross-fade-active {\n  transition: height .7s ease-out;\n}\n\n.CrossFade--Animation-enter,\n.CrossFade--Animation-leave-end {\n  /* Enter animation start state */\n  /* Leave animation end state */\n  opacity: 0;\n}\n\n.CrossFade--Animation-enter-active,\n.CrossFade--Animation-leave-active {\n  /* Enter animation transitions */\n  /* Leave animation transitions */\n  transition: opacity .7s ease-in;\n}\n\n.CrossFade--Animation-enter-end,\n.CrossFade--Animation-leave {\n  /* Enter animation end state */\n  /* Leave animation start state */\n  opacity: 1;\n}\n```\n\n### Avoiding jumps at beginning or end of animation\nIf the content contains text elements you will get strange behaviour due\nto how the browser calculates margins. To avoid this, set the top and bottom\nmargin of the first and last text element to 0. Add those margins to the container\ninstead.\n\n```css\n/* Make sure we don't get jumps att beginning and end of animation */\n.CrossFadeContainer :first-child {\n  margin-top: 0;\n}\n\n.CrossFadeContainer :last-child {\n  margin-bottom: 0;\n}\n\n.CrossFadeContainer {\n  padding: 1em 0;\n  overflow-y: hidden;\n  background-color: rgba(0,0,255,0.2);\n}\n/* Jump reset over */\n```\n\n### Avoid nested animations causing jumping\nIf you have animations in the child components they can cause jumping if\nthe transition times are slower than that of the cross-fade. So we make sure\nwe override them to get smooth transitions and correct size calculation:\n\n```css\n/**\n * Nested animations require some extra rules to avoid jumping around\n */\n\n/* Needed to make sure nested animations don't make the crossfade jump around */\n/* TODO: This should perhaps be set with Javascript? */\n.CrossFade--Animation-cross-fade-active .InfernoAnimation-active {\n  transition: all .7s ease-out;\n}\n```\n\nNote 1: When a parent element is cross-fading it sets the class `InfernoAnimation--noAnim`\nwhich prevents children from animating.\n\nNote 2: If you have async operations causing your mounting component to mutate, the height and width\ncalculations might be wrong because they are performed prior to the async operation has\ncompleted.\n\n## Running the tests\n1. `$ npm run install \u0026\u0026 npm build \u0026\u0026 npm run test-browser`\n\n2. Open test page in browser `http://localhost:8080`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjhsware%2Finferno-animation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjhsware%2Finferno-animation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjhsware%2Finferno-animation/lists"}