A Performant Customizable React Component Providing the Flip-Tilt Effect
Main Demo • Main Demo (Parallax) • Flip Direction Demo • Control Element Demo • Storybook
$ npm install framer-motion react-flip-tilt
Once the package is installed, you can import
the component:
import { FlipTilt } from 'react-flip-tilt';
You can set the front
/back
properties to either an image source as string
or an element/component
<FlipTilt front="/front.webp" back="/back.webp" />
<FlipTilt front={<div>...</div>} back={<MyComponent />} />
<FlipTilt front="/front.webp" back={<MyComponent />} />
This component is "parallax ready", meaning you don't need to change any settings for it to work.
You just need to set up your parallax effect in JSX/CSS and set it as the front/back element.
You can read this article to learn more about how to set up the 3D parallax effect.
Follow the usage guide on react-next-parallax
's readme.
Instead of placing your scene inside <Parallax></Parallax>
, set it as the front/back element.
All props are optional
In addition to these props, you can use:
- Any valid
HTMLDivElement
props likeclassName=''
,data-...='...'
,onMouseMove={...}
etc. they will be applied to the container element.- Any of the
react-next-tilt
props likescale
,disableScrollOnTouch
,controlElement
, etc.- Any of the
react-next-parallax
props likeanimationMode
,animationReverse
,offsetMultiplier
, etc. (whentype
is set to'parallax'
)While you can flip the component by changing the
flipped
prop, it will cause the component to re-render and interrupts the animation. It is advised to use theflip()
function exposed by the component's ref instead.
Name | Description | Default |
---|---|---|
front | Front image/element note: You can pass either an image source as string or an element/component example: 'path/to/image.jpg', <div>...</div>, <Component /> ReactNode | <></> |
back | Back image/element note: You can pass either an image source as string or an element/component example: 'path/to/image.jpg', <div>...</div>, <Component /> ReactNode | <></> |
direction | Direction of the flip animation see the Flip Direction Demo "horizontal" | "vertical" | "horizontal" |
flipReverse | Reverses the rotation of the flip animation see the Flip Direction Demo boolean | false |
flipBackReverse | Reverses the rotation of the flip back animation see the Flip Direction Demo boolean | false |
borderWidth | Border width applied to the back image/element example: '4px', '1em', '2rem' string | "2px" |
borderColor | Border color applied to the back image/element example: 'lightblue', '#445566AA', 'rgba(50,150,250,0.5)', 'hsla(100,50%,50%,0.2)' string(Property.BorderColor) | white |
borderStyle | Border style applied to the back image/element example: 'solid', 'dashed', 'dotted' string (Property.BorderStyle) | solid |
mass | Mass of the element in framer-motion 's spring animation. Higher values will result in more lethargic movement.number | 0.5 |
stiffness | Stiffness of the spring in framer-motion 's spring animation. Higher values will create more sudden movement.number | 120 |
flipped | Locks the component to one side
boolean | - |
type | "tilt" | "parallax" | "tilt" |
The component has the following events/callbacks in addition to react-next-tilt
events/callbacks:
Name | Description | Parameters |
---|---|---|
onFlip | Callback function that is called with the container element when the component flips and the back side is visible (element: HTMLDivElement) => void | element : The component's container element |
onFlipBack | Callback function that is called with the container element when the component flips back and the front side is visible (element: HTMLDivElement) => void | element : The component's container element |
The component's ref object contains the following properties in addition to react-next-tilt
ref properties:
Name | Description | Parameters |
---|---|---|
isFlipped | Returns whether the element is flipped or not () => boolean | - |
flip | Animates/Flips the component without re-rendering it. () => Promise<void> | - |
import { FlipTilt } from 'react-flip-tilt';
const MyComponent = () => {
return (
<FlipTilt
ref={(ref) => {
if (ref) {
//do something with the ref
}
}}
...
/>
);
};
import { useRef, useEffect } from 'react';
import { FlipTilt, FlipTiltRef } from 'react-flip-tilt';
const MyComponent = () => {
const ref = useRef<FlipTiltRef>(null);
useEffect(() => {
if (ref.current) {
//do something with the ref
}
}, []);
return <FlipTilt ref={ref} ... />;
};
import { useRef, useEffect } from 'react';
import { FlipTilt, FlipTiltRef } from 'react-flip-tilt';
const MyComponent = () => {
const ref = useRef<FlipTiltRef | null>(null);
useEffect(()=>{
if (ref.current) {
//do something else with the ref
}
},[]);
return (
<FlipTilt
ref={async (r) => {
if (r) {
console.log(`isFlipped = ${r.isFlipped()}`);
await r.flip();
console.log(`isFlipped = ${r.isFlipped()}`);
ref.current = r;
}
}}
...
/>
);
};
Animated using framer-motion
Inspired by evolany.com
Rashid Shamloo (github.com/rashidshamloo)