File size: 2,809 Bytes
4114d85 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
import PropTypes from 'prop-types'
import { forwardRef } from 'react'
// third-party
import { motion, useCycle } from 'framer-motion'
// ==============================|| ANIMATION BUTTON ||============================== //
const AnimateButton = forwardRef(function AnimateButton({ children, type, direction, offset, scale }, ref) {
let offset1
let offset2
switch (direction) {
case 'up':
case 'left':
offset1 = offset
offset2 = 0
break
case 'right':
case 'down':
default:
offset1 = 0
offset2 = offset
break
}
const [x, cycleX] = useCycle(offset1, offset2)
const [y, cycleY] = useCycle(offset1, offset2)
switch (type) {
case 'rotate':
return (
<motion.div
ref={ref}
animate={{ rotate: 360 }}
transition={{
repeat: Infinity,
repeatType: 'loop',
duration: 2,
repeatDelay: 0
}}
>
{children}
</motion.div>
)
case 'slide':
if (direction === 'up' || direction === 'down') {
return (
<motion.div
ref={ref}
animate={{ y: y !== undefined ? y : '' }}
onHoverEnd={() => cycleY()}
onHoverStart={() => cycleY()}
>
{children}
</motion.div>
)
}
return (
<motion.div ref={ref} animate={{ x: x !== undefined ? x : '' }} onHoverEnd={() => cycleX()} onHoverStart={() => cycleX()}>
{children}
</motion.div>
)
case 'scale':
default:
if (typeof scale === 'number') {
scale = {
hover: scale,
tap: scale
}
}
return (
<motion.div ref={ref} whileHover={{ scale: scale?.hover }} whileTap={{ scale: scale?.tap }}>
{children}
</motion.div>
)
}
})
AnimateButton.propTypes = {
children: PropTypes.node,
offset: PropTypes.number,
type: PropTypes.oneOf(['slide', 'scale', 'rotate']),
direction: PropTypes.oneOf(['up', 'down', 'left', 'right']),
scale: PropTypes.oneOfType([PropTypes.number, PropTypes.object])
}
AnimateButton.defaultProps = {
type: 'scale',
offset: 10,
direction: 'right',
scale: {
hover: 1,
tap: 0.9
}
}
export default AnimateButton
|