Search code examples
javascriptreactjsanimationreact-motion

How to make React animation on Hover?


I need to move menu item underline like in this example.

With jQuery I would do it simply getting left position and width of a menu item. And then perform stop.animation on hover.

I'm trying to do such animation with React. But I can't figure out how to. After google research I found the popular react-motion library for animation. But I can't find the way how to trigger animation on hover.

My task is move blue underline on div hover. Please help me to find the solution.enter image description here


Solution

  • You can do this using a css transition and an absolutely positioned stripe for the under line. Then update the left property of the stripe when the element is hovered.

    class App extends React.Component {
      constructor() {
        super()
        this.state = {
          left: 0,
        }
      }
      
      handleMouseEnter = (e) => {
        this.setState({
          left: e.target.getBoundingClientRect().x - 8,
        });
      }
    
      render() {
        return (
          <div className="App">
            <div className="box" onMouseEnter={this.handleMouseEnter} />
            <div className="box" onMouseEnter={this.handleMouseEnter}  />
            <div className="box" onMouseEnter={this.handleMouseEnter}  />
            <div className="box" onMouseEnter={this.handleMouseEnter}  />
            <div className="stripe" style={{ left: this.state.left }}/>
          </div>
        );
      }
    }
    
    ReactDOM.render(
      <App />,
      document.getElementById('root')
    );
    .App {
      width: 900px;
      overflow: hidden;
      position: relative;
      padding-bottom: 20px;
    }
    .box {
      width: 200px;
      height: 200px;
      background: #eee;
      border: 1px solid #333;
      float: left;
      margin-right: 10px;
    }
    .stripe {
      width: 200px;
      height: 10px;
      background: blue;
      position: absolute;
      bottom: 0;
      transition: left 0.3s;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    <div id="root"></div>

    Here is an example on codepen