retilt
Version:
``` ______ __ __ ______ /\__ _\ /\ \ /\ \ /\__ _\ \/_/\ \/ \ \ \ \ \ \____ \/_/\ \/ \ \_\ \ \_\ \ \_____\ \ \_\ \/_/ \/_/ \/_____/ \/_/ ```
104 lines (90 loc) • 2.73 kB
JavaScript
/**
* ______ __ __ ______
* /\__ _\ /\ \ /\ \ /\__ _\
* \/_/\ \/ \ \ \ \ \ \____ \/_/\ \/
* \ \_\ \ \_\ \ \_____\ \ \_\
* \/_/ \/_/ \/_____/ \/_/
**/
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import PropTypes from 'prop-types'
export default class Tilt extends Component {
constructor (props) {
super(props)
this.element = null
this.elementPosition = null
this.perspective = this.props.perspective || 300
this.keepTilt = this.props.keepTilt || false
this.maxTilt = this.props.maxTilt || 45
this.mouseX = 0
this.mouseY = 0
this.elementX = 0
this.elementY = 0
this.width = 0
this.height = 0
this.percentageX = 0
this.percentageY = 0
this.defaultStyle = {
display: 'inline-block',
transition: '.2s all',
transformOrigin: '50% 50%',
transformStyle: 'preserve-3d'
}
this.state = {
tilt: `perspective(${this.perspective}px) rotateX(0) rotateY(0)`
}
// Bind methos
this.getMousePosition = this.getMousePosition.bind(this)
this.calculateTilt = this.calculateTilt.bind(this)
this.mouseLeave = this.mouseLeave.bind(this)
}
componentDidMount () {
this.element = ReactDOM.findDOMNode(this)
}
getMousePosition (event) {
const { clientX, clientY } = event
const { elementX, elementY, width, height } = this
this.elementPosition = this.element.getBoundingClientRect()
this.elementX = this.elementPosition.left
this.elementY = this.elementPosition.top
this.width = this.elementPosition.width
this.height = this.elementPosition.height
this.mouseX = clientX
this.mouseY = clientY
this.percentageX = (clientX - (elementX + (width / 2)))
this.percentageY = (clientY - (elementY + (height / 2)))
this.calculateTilt()
}
calculateTilt () {
const { percentageX, percentageY } = this
const tiltX = ((percentageX / this.maxTilt)).toFixed(2)
const tiltY = ((percentageY / this.maxTilt)).toFixed(2)
this.setState({
tilt: `perspective(${this.perspective}px) rotateX(${tiltY}deg) rotateY(${tiltX}deg)`
})
}
mouseLeave () {
if (!this.keepTilt) {
this.setState({
tilt: `perspective(${this.perspective}px) rotateX(0deg) rotateY(0deg)`
})
}
}
render () {
return (
<div
style={this.defaultStyle}
onMouseMove={this.getMousePosition}
onMouseLeave={this.mouseLeave}>
<div style={{transform: this.state.tilt}}>
{this.props.children}
</div>
</div>
)
}
}
Tilt.propTypes = {
perspective: PropTypes.number,
keepTilt: PropTypes.bool,
maxTilt: PropTypes.number
}