cssreactjsreact-motion

Rotating and Scaling with React-Motion


Struggling to get my head round 'rotating' and 'scaling' in React Motion v4 and cant seem to find much about how to do it online. Its easy to change a simple css property along with a simple state change like below:

<Motion 
 defaultStyle={{opacity: 0}}
 style={{opacity: spring(this.state.isActive ? 1 : 0, {stiffness: 200, damping: 12})}}>
 {style => 
  <div style={{opacity: style.opacity}} className="action-panel">
   <div id="action-content" className="action-panel-content"></div>
  </div>
 }                            
</Motion>

However how do i do the above with more complex css properties such as 'transform: rotate(90deg)' for example ?

Finally if i want to have more complex state logic, such as animation that occurs on rollover and rollout and if various states are true or false where's best to do that ? Prior to using React Motion I was updating the inline styles of the element based on its state and some conditionals, I'm not really sure how to do this now just using React Motion. Your thoughts would be welcomed! :D

t xx


Solution

  • For rotate & scale you can use tagged template literals ${ expresion }.

    let me show you

    <Motion
      defaultStyle={{ rotate: 0, scale: 1}}
      style={{ rotate: spring(180), scale: spring(3)}}
    >
    
      {style => 
        (
          <div style={{ 
           transform: `rotate( ${style.rotate}deg )`,
           transform: `scale( ${style.scale}, ${style.scale} )`
         }}> </div>    
        )
      }
    
    </Motion>
    

    notice the use of backticks

    For interactive animation, React is very good in accessing the DOM and uses SyntheticEvents which includes Mouse Events.

    onClick onContextMenu onDoubleClick onDrag onDragEnd onDragEnter onDragExit onDragLeave onDragOver onDragStart onDrop onMouseDown onMouseEnter onMouseLeave onMouseMove onMouseOut onMouseOver onMouseUp

    here's a mouse hover example using setState

    import React, { Component } from 'react'
    import { Motion, spring } from 'react-motion'
    
    class App extends Component { 
      state = {
       rotate: 0
      }
      enter(){
        this.setState({rotate: 180})
      }
      leave(){
        this.setState({rotate: 0})
      }
      render(){
        return (
          <Motion
            defaultStyle={{ rotate: 0}}
            style={{ rotate: spring(this.state.rotate)}}
          >
    
           {style => 
             (
               <div 
                 style={{ 
                   transform: `rotate( ${style.rotate}deg )`,
                 }}
                 onMouseEnter={this.enter.bind(this)}
                 onMouseLeave={this.leave.bind(this)}
               > </div>    
             )
            }
    
          </Motion>
         )
      }
    }
    export default App
    

    now this won't show anything since there is no pre-defined dimensions of the div. to do this, let's declare styles object.

    below the import lines

    const styles = {
      div: {
        height: 100,
        width: 100,
        backgroundColor: 'papayawhip'
      }
    }
    

    then you can use it like so:

    style={ Object.assign( {},
      styles.div,
      { 
        transform: `rotate( ${style.rotate}deg )`,
        // more styles here...
      })
    }