A Performant Customizable Tilt Component for React
npm install react-next-tiltA Performant Customizable Tilt Component for React
Main Demo •
Control Element Demo •
Storybook
"Scale on Hover/Touch" support
"Shadow on Hover/Touch" support
"Disable Scroll on Touch" support
"Full-Page Listening" support
"Control Element" support
requestAnimationFrame(), will-change, and other optimizations)
bash
$ npm install react-next-tilt
`
Once the package is installed, you can import the component:
`js
import { Tilt } from 'react-next-tilt';
`
Usage
$3
Place the element/component you want the tilt effect to be applied to inside of .
`js
`
> You can place any element/component inside of (doesn't have to be an image)
$3
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 place it inside of
You can read this article to learn more about how to set up the 3D parallax effect.
> ⚠️ Setting lineGlareMixBlendMode and/or spotGlareMixBlendMode properties to anything other than "normal" will break the parallax effect.
Props
> All props are optional.
> In addition to these props, you can use any valid HTMLDivElement props like className='', data-...='...', onMouseMove={...} etc. they will be applied to the container element.
> While you can tilt the component to a given angle by adjusting the initial angles, it will cause the component to re-render. It is advised to use the tilt() function exposed by the component's ref instead.
Name Description Default width Width of the componentnote: You can also set the width using "className", "style", etc. instead of using this propertyexample: 100, '200px', '10rem', '20%'string | number - height Height of the componentnote: You can also set the height using "className", "style", etc. instead of using this propertyexample: 100, '200px', '10rem', '20%'string | number - borderRadius Border radius of the component (applied to glare elements as well)example: '4px', '1em', '2rem'string - perspective Determines how far the elements are from the userexample: '1000px', '60em', '50rem'string "1000px" scale Amount of scale applied to the component on hover/touchnumber 1 shadowEnable Enables/Disables the shadow applied to the container or tilt element on hover/touchboolean false shadow The shadow applied to the container or tilt element on hover/touchstring "0 0 1rem rgba(0,0,0,0.5)" shadowType Type of the shadow applied on hover/touchIf set to 'box', shadow is applied as box-shadow to the tilt elementIf set to 'drop', shadow is applied as filter: drop-shadow() to the container elementnote: Set to 'drop' if you have a setup where elements go outside the tilt element and want to apply the shadow to them as well,Or if you have multiple elements inside the tilt element and want the shadow to apply to them individually and not the whole tilt element"box" | "drop" "box" lineGlareEnable Enables/Disables the line glare effectboolean true lineGlareBlurEnable Enables/Disables the blur applied to the line glare effectboolean true lineGlareBlurAmount Amount of blur applied to the line glare effectexample: '4px', '1em', '2rem'string "4px" lineGlareWidthPercent Width of the line glare in relation to the componentnumber 10 lineGlareMaxOpacity Maximum opacity of the line glare effectnumber 0.1 lineGlareMixBlendMode mix-blend-mode applied to the line glare effectnote: Using a "mix-blend-mode" other than "normal" will break the parallax effectstring (Property.MixBlendMode)"normal" lineGlareColor Color of the line glare effectexample: 'lightblue', '#445566AA', 'rgba(50,150,250,0.5)', 'hsla(100,50%,50%,0.2)'string (Property.Color) "white" lineGlareReverse Reverses the movement of the line glare effectboolean false lineGlareDirection Changes the direction/angle of the line glare effect"to-bottom-right" | "to-bottom-left" "to-bottom-right" lineGlareHoverPosition Determines the areas of the component that show the line glare effect when hovered/touched"top-left" | "top-right" | "bottom-left" | "bottom-right" "top-left" lineGlareFixedPosition Sets the position of the line glare element to a fixed position inside the component.note: The position determines the center of the line glare element.The left property can be specified in pixels ('px') or percentage ('%').When set, the line glare element will not respond to hover/touch and will always be at the specified position."left" | "right" | "center" | { left: ${number}px | ${number}%; } - spotGlareEnable Enables/Disables the spot glare effectboolean true spotGlareSizePercent Size of the spot glare effect in relation to the component between 0 to Infinitynote: If spotGlarePosition is set to anything other than 'all', only half of the spot glare effect is visible at any time.That's why the default value is 200 to cover the whole element.number 200 spotGlareMaxOpacity Maximum opacity of the spot glare effectnumber 0.5 spotGlareMixBlendMode mix-blend-mode applied to the spot glare effectnote: Using a "mix-blend-mode" other than "normal" will break the parallax effectstring (Property.MixBlendMode)"normal" spotGlarePosition Determines the position of the spot glare effect inside the component"top" | "right" | "bottom" | "left" | "all" "top" spotGlareColor Color of the line glare effectexample: 'lightblue', '#445566AA', 'rgba(50,150,250,0.5)', 'hsla(100,50%,50%,0.2)'string (Property.Color) "white" spotGlareReverse Reverses the movement of the spot glare effectboolean false spotGlareFixedPosition Sets the position of the spot glare element to a fixed position inside the component.note: The position determines the center of the spot glare element.The left and top properties can be specified in pixels ('px') or percentage ('%').When set, the spot glare element will not respond to hover/touch and will always be at the specified position."top-left" | "top-right" | "bottom-left" | "bottom-right" | "center" | { left: ${number}px | ${number}%; top: ${number}px | ${number}%; } - tiltMaxAngleX Maximum tilt angle around the X axis between 0 to 90note: Setting to 0 will disable rotation around the X axisnumber 20 tiltMaxAngleY Maximum tilt angle around the Y axis between 0 to 90note: Setting to 0 will disable rotation around the Y axisnumber 20 tiltReverse Reverses the tilt direction/movementboolean false tiltReset Enables/Disables resetting the tilt effect on mouseLeave/touchEndboolean true initialAngleX Initial tilt/rotation angle around the X axisnote: Is limited to [-tiltMaxAngleX - tiltMaxAngleX] rangenumber - initialAngleY Initial tilt/rotation angle around the Y axisnote: Is limited to [-tiltMaxAngleY - tiltMaxAngleY] rangenumber - disableScrollOnTouch Disables scrolling (overflow: hidden) during touch inetraction to prevent unwanted movementnote: Disables scrolling on "body" if set to "boolean". You can also pass an "HTMLElement" which scrolling will be disabled for, instead of "body"boolean | HTMLElement true style Style passed to the component's container elementCSSProperties - tiltStyle Style passed to the component's tilt elementCSSProperties - tiltClass className passed to the component's tilt elementstring - tiltProps Properties passed to the tilt elementHTMLAttributes<HTMLDivElement> & { [data: data-${string}]: string; } - gyroMaxAngleX Maximum tilt angle around the X axis for gyroscope between 0 to 90note: Setting to 0 will disable rotation around the X axis for gyroscopenumber 0 gyroMaxAngleY Maximum tilt angle around the Y axis for gyroscope between 0 to 90note: Setting to 0 will disable rotation around the Y axis for gyroscopenumber 0 gyroReverse Reverses the tilt direction for gyroscopeboolean false disabled Disables the tilt effect and applies the disabledFilter to the containerboolean false disabledFilter CSS filter applied to the container when disabled = truestring "grayscale(1) brightness(125%)" CSSTransition CSS transition applied to the tilt, line glare, and spot glare elementsstring "all 0.4s cubic-bezier(0.03, 0.98, 0.52, 0.99)" TiltWrapper Component wrapping the tilt elementnote: Is useful when integrating this component into another componentFC<{ children?: ReactNode; }> ({ children }: PropsWithChildren) => <>{children}</> fullPageListening Enables/Disables full-page listening. This component's event handlers will be added to the "document"ote: If set to "true", "controlElement", "controlElementOnly", and "disableScrollOnTouch" properties will have no effectboolean false controlElement
Element(s) that control(s) this component. This component's event handlers will be added to themnote: You can pass an HTMLElement, a ref, or an array of themThis property will have no effect if "fullPageListening" is set to "true"example: element, ref, [element, ref], [ref1, ref2]HTMLElement | RefObject<unknown> | (HTMLElement | RefObject<unknown>)[] - controlElementOnly If set to "true", events will be disabled for the component and it will be controlled by the controlElement(s) onlyThis property will have no effect if "fullPageListening" is set to "true"boolean false preserve3dEnable If set to true, adds transform-style: preserve-3d; to the container and tilt elementsnote: Enable if you want to set up a parallax effect and translate elements along the Z axisDisable if you are having problems with blurwarning: Can cause blur on scale (prevents re-rastering at higher scales by Chrome's compositor and the element is always rasterized at scale 1)boolean true testIdEnable Adds the data-testid=... property to all elements for testing purposesnote: Can also be used to select/grab and modify each element if you want to do heavy customizationboolean false
Events/Callbacks
Name Description Parameters onTilt Callback function that is called with the current tilt angle at every tilt event(angle: Angle, gyro:boolean) => void angle: Tilt angle ({angleX: number, angleY: number})gyro: Whether the event is triggered by gyroscope or notonReset Callback function that is called when the tilt angle is reset() => void
Ref
The component's ref object contains these properties:
Name Description Parameters element The component's main container elementHTMLDivElement | null- tilt Tilts the component to the given angle(angle: Angle, changeScaleAndShadow?: boolean, gyro?: boolean) => voidangle: Tilt angle ({angleX: number, angleY: number})changeScaleAndShadow=false: Whether to apply the scale and shadow properties or notgyro=false: Whether the event is triggered by gyro or not reset Resets the component (rotation/scale and glare effects)() => void- angle Returns the current tilt angle ({angleX: number, angleY: number})() => Angle- updateWillChange Adds/Removes the "will-change" CSS property to the tilt and glare elementsnote: Can improve performance when doing a series of animations using the "TiltRef.tilt()" function(add?: boolean) => voidadd=true: Whether to add the property (true) or remove it (false)
> Ref functions don't re-render the component.
$3
`ts
import { Tilt } from 'react-next-tilt';
const MyComponent = () => {
return (
ref={(ref) => {
if (ref) {
//do something with the ref
}
}}
>
...
);
};
`
$3
`js
import { useRef, useEffect } from 'react';
import { Tilt, TiltRef } from 'react-next-tilt';
const MyComponent = () => {
const ref = useRef(null);
useEffect(() => {
if (ref.current) {
//do something with the ref
}
}, []);
return ... ;
};
`
$3
`ts
import { useRef, useEffect } from 'react';
import { Tilt, TiltRef } from 'react-next-tilt';
const MyComponent = () => {
const ref = useRef(null);
useEffect(()=>{
if (ref.current) {
//do something else with the ref
}
},[]);
return (
ref={(r) => {
if (r) {
console.log( angle = ${JSON.stringify(r.angle())});
r.tilt({ angleX: 10, angleY: 10 });
console.log(angle = ${JSON.stringify(r.angle())});
ref.current = r;
}
}}
...
>
...
);
};
``