{"id":13422283,"url":"https://github.com/azazdeaz/react-gsap-enhancer","last_synced_at":"2025-05-16T04:04:04.363Z","repository":{"id":38184485,"uuid":"37862060","full_name":"azazdeaz/react-gsap-enhancer","owner":"azazdeaz","description":"Use the full power of React and GSAP together","archived":false,"fork":false,"pushed_at":"2023-07-05T12:21:30.000Z","size":3755,"stargazers_count":729,"open_issues_count":16,"forks_count":38,"subscribers_count":31,"default_branch":"master","last_synced_at":"2025-05-05T14:02:16.136Z","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":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/azazdeaz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2015-06-22T15:02:28.000Z","updated_at":"2025-03-13T15:27:34.000Z","dependencies_parsed_at":"2023-10-20T18:12:26.525Z","dependency_job_id":null,"html_url":"https://github.com/azazdeaz/react-gsap-enhancer","commit_stats":{"total_commits":139,"total_committers":5,"mean_commits":27.8,"dds":0.07913669064748197,"last_synced_commit":"4523f8102b71201e6365963bbd2a85f27026340f"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/azazdeaz%2Freact-gsap-enhancer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/azazdeaz%2Freact-gsap-enhancer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/azazdeaz%2Freact-gsap-enhancer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/azazdeaz%2Freact-gsap-enhancer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/azazdeaz","download_url":"https://codeload.github.com/azazdeaz/react-gsap-enhancer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253336891,"owners_count":21892796,"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-07-30T23:00:41.044Z","updated_at":"2025-05-16T04:04:04.344Z","avatar_url":"https://github.com/azazdeaz.png","language":"JavaScript","funding_links":[],"categories":["UI Animation","Uncategorized","Ferramentas","JavaScript"],"sub_categories":["Form Components","Uncategorized","GraphQL"],"readme":"# react-gsap-enhancer [![Build Status](https://img.shields.io/travis/azazdeaz/react-gsap-enhancer.svg?style=flat-square)](https://travis-ci.org/azazdeaz/react-gsap-enhancer) [![Coveralls branch](https://img.shields.io/coveralls/azazdeaz/react-gsap-enhancer/master.svg?style=flat-square)](https://coveralls.io/github/azazdeaz/react-gsap-enhancer)  [![npm](https://img.shields.io/npm/dm/react-gsap-enhancer.svg?style=flat-square)](https://www.npmjs.com/package/react-gsap-enhancer) ![maintainance](https://img.shields.io/badge/actively%20maintained-%20not%20%3A\\(%20sorry-red.svg?style=flat-square)\n\n\n[![Join the chat at https://gitter.im/azazdeaz/react-gsap-enhancer](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/azazdeaz/react-gsap-enhancer?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n\n|[Demos](#demos)|[Why?](#why)|[How it works?](#how-it-works)|[Usage](#usage)|[API](#api)|\n|---------------|------------|------------------------------|---------------|-----------|\n\nA [React] component enhancer for applying [GSAP] animations on components without side effects.\n\n\u003eFor simple use cases, **you might not need this tool**. See [this egghead.io tutorial](https://egghead.io/lessons/react-using-tweenmax-with-react).\n\n*Developed as part of the [Animachine project](https://github.com/animachine/animachine).*\n\n**Requirements:** \n - From v0.2 react-gsap-enhancer requires **[react v0.14+][react-npm]**. Check out [this release notes](https://github.com/azazdeaz/react-gsap-enhancer/releases/tag/v0.2.0) for upgrading from v0.1.x.\n - **GSAP v1.18+** ([*NPM*][gsap-npm], [*CDN*][gsap-cdn])\n\n### Demos\n - Playground\n  - [update the component while it's animating](http://azazdeaz.github.io/react-gsap-enhancer/#/demo/update-and-animate-transform)\n  - [control timeline with component events](http://azazdeaz.github.io/react-gsap-enhancer/#/demo/morphing-search-input)\n  - [use options (ES5)](http://azazdeaz.github.io/react-gsap-enhancer/#/demo/sending-options-to-the-animation-source)\n  - [use with react-addons-transition-group (ES5)](http://azazdeaz.github.io/react-gsap-enhancer/#/demo/using-transition-group)\n  - [and more...!](http://azazdeaz.github.io/react-gsap-enhancer/#/demo/select-target-with-options)\n - CodePen\n  - [Material Login Dialog](http://codepen.io/azazdeaz/pen/yYavVK?editors=001)\n\n### Why?\nWe have great tools (like [react-motion], or [Animated]) to animate the state and props of our React components, but if you ever needed to create a longer animation sequence with React you can still feel the desire to reach out for a tool like [GSAP] which makes it easy to compose your animation and apply it on the DOM with its super performance and bulit-in polyfills. Unfortunately, if you let anything mutate the DOM of a component, React can break on the next update because it is supposed that the DOM looks exacly the same like after the last update. This tool is a workaround for this problem.\n\n### How it works?\nIt's pretty simple: in every render cycle:\n - after each render, save the attributes of the rendered DOM elements then start/restart the added animations.\n - before each render, stop the animations and restore the saved attributes (so React will find the DOM as it was after the update)\n\n\u003eIn this way, you can even update a style of an element (like ```transform: 'translateX(${mouse.x})'```) while animating the same style relative to its original value (like: ```.to(node, 1, {x: '+=300', yoyo: true}```)\n\n\u003e[Check it out!](http://azazdeaz.github.io/react-gsap-enhancer/#/demo/update-and-animate-transform) \n\n### Usage\nFirst you have to enhance the component with react-gsap-enhancer:\n\n**ES5**\n```javascript\nvar GSAP = require('react-gsap-enhancer')\nvar MyComponent = GSAP()(React.createClass({\n  render: function() {/*...*/}\n}))\n```\n**ES6**\n```javascript\nimport GSAP from 'react-gsap-enhancer'\n\nclass MyComponent extends Component {\n  render() {/*...*/}\n}\n\nexport default GSAP()(MyComponent)\n```\n**ES7**\n```javascript\nimport GSAP from 'react-gsap-enhancer'\n\n@GSAP()\nexport default class MyComponent extends Component {\n  render() {/*...*/}\n}\n```\n\nNow you can attach animations to the component with ```addAnimation(animationSource)```. The ```animationsSource``` is a function that returns a GSAP Animation (ex. TweenLite, or TimelineMax) like this:\n```javascript\nfunction moveAnimation(utils) {\n  return TweenMax.to(utils.target, 1, {x: '+=123'})\n}\n```\nthe utils.target refers to the root node of the component but you can select any of it's children by their props in the good old jQuery style:\n```javascript\nfunction moveAnimation({target}) {//just ES6 syntax sugar\n  var footer = target.find({type: 'footer'})\n  var buttons = footer.findAll({type: 'button'})\n  ...\n}\n```\nand later in a component you can use it like:\n```javascript\n...\nhandleClick() {\n  var controller = this.addAnimation(moveAnimation)\n...\n```\nthe ```addAnimation()``` returns a [controller object](#controller) that has the same API like the original GSAP Animation so you are free to control it like:\n```javascript\n...\nhandleStartLoad() {\n  this.progressAnim = this.addAnimation(progressAnim)\n  this.otherAnim.timeScale(3.4).reverse()\n}\nhandleProgress(progress) {\n  this.progressAnim.tweenTo(progress)\n}\n...\n```\n\n### API\n\n##### addAnimation()\n - ```enhancedComponent.addAnimation(animationSource[, options]) -\u003e controller```: Adds an animation to the component with the given source and returns a Controller for it. The options will be passed to the animationSource.\n\n##### ```controller```\nWraps the GSAP Animation returned from the ```animationSource```. It's exposing the following GSAP API methods:  \n*For TweenMax and TweenLite:*  \n\u003e [delay](http://greensock.com/docs/#/HTML5/GSAP/TweenMax/delay/)\\*,\n[duration](http://greensock.com/docs/#/HTML5/GSAP/TweenMax/duration/)\\*,\n[eventCallback](http://greensock.com/docs/#/HTML5/GSAP/TweenMax/eventCallback/),\n[invalidate](http://greensock.com/docs/#/HTML5/GSAP/TweenMax/invalidate/),\n[isActive](http://greensock.com/docs/#/HTML5/GSAP/TweenMax/isActive/),\n[pause](http://greensock.com/docs/#/HTML5/GSAP/TweenMax/pause/),\n[paused](http://greensock.com/docs/#/HTML5/GSAP/TweenMax/paused/),\n[play](http://greensock.com/docs/#/HTML5/GSAP/TweenMax/play/),\n[progress](http://greensock.com/docs/#/HTML5/GSAP/TweenMax/progress/),\n[restart](http://greensock.com/docs/#/HTML5/GSAP/TweenMax/restart/),\n[resume](http://greensock.com/docs/#/HTML5/GSAP/TweenMax/resume/),\n[reverse](http://greensock.com/docs/#/HTML5/GSAP/TweenMax/reverse/),\n[reversed](http://greensock.com/docs/#/HTML5/GSAP/TweenMax/reversed/),\n[seek](http://greensock.com/docs/#/HTML5/GSAP/TweenMax/seek/),\n[startTime](http://greensock.com/docs/#/HTML5/GSAP/TweenMax/startTime/)\\*,\n[time](http://greensock.com/docs/#/HTML5/GSAP/TweenMax/time/),\n[timeScale](http://greensock.com/docs/#/HTML5/GSAP/TweenMax/timeScale/),\n[totalDuration](http://greensock.com/docs/#/HTML5/GSAP/TweenMax/totalDuration/)\\*,\n[totalProgress](http://greensock.com/docs/#/HTML5/GSAP/TweenMax/totalProgress/)\\*,\n[totalTime](http://greensock.com/docs/#/HTML5/GSAP/TweenMax/totalTime/)\\*,\n\n*For TimelineMax and TimelineLite:*  \n\u003e [currentLabel](http://greensock.com/docs/#/HTML5/GSAP/TimelineMax/currentLabel/),\n[duration](http://greensock.com/docs/#/HTML5/GSAP/TimelineMax/duration/)\\*,\n[endTime](http://greensock.com/docs/#/HTML5/GSAP/TimelineMax/endTime/)\\*,\n[eventCallback](http://greensock.com/docs/#/HTML5/GSAP/TimelineMax/eventCallback/),\n[from](http://greensock.com/docs/#/HTML5/GSAP/TimelineMax/from/),\n[fromTo](http://greensock.com/docs/#/HTML5/GSAP/TimelineMax/fromTo/),\n[getLabelAfter](http://greensock.com/docs/#/HTML5/GSAP/TimelineMax/getLabelAfter/),\n[getLabelBefore](http://greensock.com/docs/#/HTML5/GSAP/TimelineMax/getLabelBefore/),\n[getLabelArray](http://greensock.com/docs/#/HTML5/GSAP/TimelineMax/getLabelArray/),\n[getLabelTime](http://greensock.com/docs/#/HTML5/GSAP/TimelineMax/getLabelTime/),\n[invalidate](http://greensock.com/docs/#/HTML5/GSAP/TimelineMax/invalidate/),\n[isActive](http://greensock.com/docs/#/HTML5/GSAP/TimelineMax/isActive/),\n[pause](http://greensock.com/docs/#/HTML5/GSAP/TimelineMax/pause/),\n[paused](http://greensock.com/docs/#/HTML5/GSAP/TimelineMax/paused/),\n[play](http://greensock.com/docs/#/HTML5/GSAP/TimelineMax/play/),\n[progress](http://greensock.com/docs/#/HTML5/GSAP/TimelineMax/progress/),\n[restart](http://greensock.com/docs/#/HTML5/GSAP/TimelineMax/restart/),\n[resume](http://greensock.com/docs/#/HTML5/GSAP/TimelineMax/resume/),\n[reverse](http://greensock.com/docs/#/HTML5/GSAP/TimelineMax/reverse/),\n[reversed](http://greensock.com/docs/#/HTML5/GSAP/TimelineMax/reversed/),\n[seek](http://greensock.com/docs/#/HTML5/GSAP/TimelineMax/seek/),\n[startTime](http://greensock.com/docs/#/HTML5/GSAP/TimelineMax/startTime/)\\*,\n[time](http://greensock.com/docs/#/HTML5/GSAP/TimelineMax/time/),\n[timeScale](http://greensock.com/docs/#/HTML5/GSAP/TimelineMax/timeScale/),\n[totalDuration](http://greensock.com/docs/#/HTML5/GSAP/TimelineMax/totalDuration/)\\*,\n[totalProgress](http://greensock.com/docs/#/HTML5/GSAP/TimelineMax/totalProgress/)\\*,\n[totalTime](http://greensock.com/docs/#/HTML5/GSAP/TimelineMax/totalTime/)\\*,\n[tweenFromTo](http://greensock.com/docs/#/HTML5/GSAP/TimelineMax/tweenFromTo/),\n[tweenTo](http://greensock.com/docs/#/HTML5/GSAP/TimelineMax/tweenTo/),\n\n**Notes:**\n  - Some of the methods above aren't available for TweenLite and TimelineLite. Please check the GSAP docs for more details.\n  - controller.kill() will also remove all the effects the animation made on your component.\n  - As you can see, the editor methods (like ```.to()``` or ```.add()```) aren't exposed by the controller so you can only use them inside the [animationSource](#animationsource) function while you construct the animation.\n\n***\\**** Through the controller, you can only get values with these methods.\n\n```javascript\nvar controller = this.addAnimation(animationSource)\ncontroller.timeScale(2).play()\n```\n\n##### ```animationSource```\n - ```({target, options}) -\u003e GSAP Animation```\n\nA function that returns a GSAP Animation.\n```javascript\nfunction animationSource(utils) {\n  return TweenMax.to(utils.target, 1, {x: 100})\n}\nthis.addAnimation(animationSource)\n```\n\n##### ```target```\njQuery-like object that refers to the root component and lets select its children with chainable find methods and [selectors](#selector).\n - ```target.find(selector)```: returns with the first match\n - ```target.findAll(selector)```: returns with all the matches\n - ```target.findInChildren(selector)```: returns with the first match in the direct children\n - ```target.findAllInChildren(selector)```: returns with all the matches in the direct children\n```javascript\nfunction animationSource(utils) {\n  var button = utils.target.findAll({type: 'button'}).find({role: 'submit'})\n  return TweenMax.to(button, 1, {x: 100})\n}\n```\n\n##### ```options```\nArbitrary object. Passed to the [addAnimation](#methods-added-to-the-component) call as the second argument and will be passed to the [animationSource](#animationsource)\n```javascript\nthis.addAnimation(animationSource, {offset: this.props.offset})\n\n...\n\nfunction animationSource(utils) {\n  return TweenMax.to(utils.target, 1, {x: utils.options.offset})\n}\n```\n\n##### ```selector```\nSelectors are usually simple objects and the \"find\" functions are using it to select the elements with matching props, i.e. ```{key: 'head'}```, ```{color: 'red'}```, and ```{key: 'head', color:  'red}``` are all matches to ```\u003cdiv key='head' color='red'/\u003e```.\n\nI'm looking forward to your feedback!\n\n[react-motion]: https://github.com/chenglou/react-motion\n[Animated]: https://facebook.github.io/react-native/docs/animations.html#animated\n[GSAP]: http://greensock.com/\n[React]: https://github.com/facebook/react\n[react-npm]: https://www.npmjs.com/package/react\n[gsap-npm]: https://www.npmjs.com/package/gsap\n[gsap-cdn]: https://cdnjs.com/libraries/gsap\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fazazdeaz%2Freact-gsap-enhancer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fazazdeaz%2Freact-gsap-enhancer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fazazdeaz%2Freact-gsap-enhancer/lists"}