react-next-tilt
TypeScript icon, indicating that this package has built-in type declarations

0.4.3 • Public • Published

React Next Tilt

A Performant Customizable Tilt Component for React

Main DemoControl Element DemoStorybook

install size npm bundle size npm downloads Known Vulnerabilities

React Next Tilt Demo Image

Table of Contents

Features

  • Easy to use
  • Zero dependencies
  • Highly customizable
  • Touch and Gyroscope support
  • Two customizable glare effects (spot/line)
  • Parallax ready
  • "Scale on Hover/Touch" support
  • "Shadow on Hover/Touch" support
  • "Disable Scroll on Touch" support
  • "Full-Page Listening" support
  • "Control Element" support
  • No jittery movement around the edges
  • Built with performance in mind (requestAnimationFrame(), will-change, and other optimizations)
  • Built from the ground up using React Hooks/TypeScript (is not a port of another library)
  • Minimum amount of component re-renders
  • Typed props with JSDoc descriptions
  • Tested extensively using Cypress/Storybook

Installation

$ npm install react-next-tilt

Once the package is installed, you can import the component:

import { Tilt } from 'react-next-tilt';

Usage

Basic Usage

Place the element/component you want the tilt effect to be applied to inside of <Tilt></Tilt>.

<Tilt>
  <img src="path/to/image.jpg" />
</Tilt>

You can place any element/component inside of <Tilt></Tilt> (doesn't have to be an image)

Parallax Effect

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 <Tilt></Tilt>

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 component
note: You can also set the width using "className", "style", etc. instead of using this property
example: 100, '200px', '10rem', '20%'
string | number
-
height
Height of the component
note: You can also set the height using "className", "style", etc. instead of using this property
example: 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 user
example: '1000px', '60em', '50rem'
string
"1000px"
scale
Amount of scale applied to the component on hover/touch
number
1
shadowEnable
Enables/Disables the shadow applied to the container or tilt element on hover/touch
boolean
false
shadow
The shadow applied to the container or tilt element on hover/touch
string
"0 0 1rem rgba(0,0,0,0.5)"
shadowType
Type of the shadow applied on hover/touch
If set to 'box', shadow is applied as box-shadow to the tilt element
If set to 'drop', shadow is applied as filter: drop-shadow() to the container element
note: 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 effect
boolean
true
lineGlareBlurEnable
Enables/Disables the blur applied to the line glare effect
boolean
true
lineGlareBlurAmount
Amount of blur applied to the line glare effect
example: '4px', '1em', '2rem'
string
"4px"
lineGlareWidthPercent
Width of the line glare in relation to the component
number
10
lineGlareMaxOpacity
Maximum opacity of the line glare effect
number
0.1
lineGlareMixBlendMode
mix-blend-mode applied to the line glare effect
note: Using a "mix-blend-mode" other than "normal" will break the parallax effect
string (Property.MixBlendMode)
"normal"
lineGlareColor
Color of the line glare effect
example: '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 effect
boolean
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 effect
boolean
true
spotGlareSizePercent
Size of the spot glare effect in relation to the component between 0 to Infinity
note: 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 effect
number
0.5
spotGlareMixBlendMode
mix-blend-mode applied to the spot glare effect
note: Using a "mix-blend-mode" other than "normal" will break the parallax effect
string (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 effect
example: '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 effect
boolean
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 90
note: Setting to 0 will disable rotation around the X axis
number
20
tiltMaxAngleY
Maximum tilt angle around the Y axis between 0 to 90
note: Setting to 0 will disable rotation around the Y axis
number
20
tiltReverse
Reverses the tilt direction/movement
boolean
false
tiltReset
Enables/Disables resetting the tilt effect on mouseLeave/touchEnd
boolean
true
initialAngleX
Initial tilt/rotation angle around the X axis
note: Is limited to [-tiltMaxAngleX - tiltMaxAngleX] range
number
-
initialAngleY
Initial tilt/rotation angle around the Y axis
note: Is limited to [-tiltMaxAngleY - tiltMaxAngleY] range
number
-
disableScrollOnTouch
Disables scrolling (overflow: hidden) during touch inetraction to prevent unwanted movement
note: 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 element
CSSProperties
-
tiltStyle
Style passed to the component's tilt element
CSSProperties
-
tiltClass
className passed to the component's tilt element
string
-
tiltProps
Properties passed to the tilt element
HTMLAttributes<HTMLDivElement> & { [data: `data-${string}`]: string; }
-
gyroMaxAngleX
Maximum tilt angle around the X axis for gyroscope between 0 to 90
note: Setting to 0 will disable rotation around the X axis for gyroscope
number
0
gyroMaxAngleY
Maximum tilt angle around the Y axis for gyroscope between 0 to 90
note: Setting to 0 will disable rotation around the Y axis for gyroscope
number
0
gyroReverse
Reverses the tilt direction for gyroscope
boolean
false
disabled
Disables the tilt effect and applies the disabledFilter to the container
boolean
false
disabledFilter
CSS filter applied to the container when disabled = true
string
"grayscale(1) brightness(125%)"
CSSTransition
CSS transition applied to the tilt, line glare, and spot glare elements
string
"all 0.4s cubic-bezier(0.03, 0.98, 0.52, 0.99)"
TiltWrapper
Component wrapping the tilt element
note: Is useful when integrating this component into another component
FC<{ 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 effect
boolean
false
controlElement
Element(s) that control(s) this component. This component's event handlers will be added to them
note: You can pass an HTMLElement, a ref, or an array of them
This 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) only
This 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 elements
note: Enable if you want to set up a parallax effect and translate elements along the Z axis
Disable if you are having problems with blur
warning: 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 purposes
note: Can also be used to select/grab and modify each element if you want to do heavy customization
boolean
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 not
onReset
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 element
HTMLDivElement | null
-
tilt
Tilts the component to the given angle
(angle: Angle, changeScaleAndShadow?: boolean, gyro?: boolean) => void
angle: Tilt angle ({angleX: number, angleY: number})
changeScaleAndShadow=false: Whether to apply the scale and shadow properties or not
gyro=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 elements
note: Can improve performance when doing a series of animations using the "TiltRef.tilt()" function
(add?: boolean) => void
add=true: Whether to add the property (true) or remove it (false)

Ref functions don't re-render the component.

Ref Usage (ref function)

import { Tilt } from 'react-next-tilt';

const MyComponent = () => {
  return (
    <Tilt
      ref={(ref) => {
        if (ref) {
          //do something with the ref
        }
      }}
    >
      ...
    </Tilt>
  );
};

Ref Usage (useEffect)

import { useRef, useEffect } from 'react';
import { Tilt, TiltRef } from 'react-next-tilt';

const MyComponent = () => {
  const ref = useRef<TiltRef>(null);

  useEffect(() => {
    if (ref.current) {
      //do something with the ref
    }
  }, []);

  return <Tilt ref={ref}>...</Tilt>;
};

Tilt on Mount

import { useRef, useEffect } from 'react';
import { Tilt, TiltRef } from 'react-next-tilt';

const MyComponent = () => {
  const ref = useRef<TiltRef | null>(null);

  useEffect(()=>{
    if (ref.current) {
    //do something else with the ref
    }
  },[]);

  return (
    <Tilt
      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;
        }
      }}
      ...
    >
      ...
    </Tilt>
  );
};

Author

Rashid Shamloo (github.com/rashidshamloo)

License

MIT

Package Sidebar

Install

npm i react-next-tilt

Weekly Downloads

140

Version

0.4.3

License

MIT

Unpacked Size

111 kB

Total Files

6

Last publish

Collaborators

  • rashidshamloo