Interaction
Parallax Blur Gradient Cards in Framer
Created by
About the resource
I had a pretty easy job creating these cards since I just had to use some of the resources already available here at Framer University.
Parallax hover
First, let's see how I achieved the parallax hover effect.
I divided the content of the card into three layers. We have the "Sky" in the background, the "Text" in the middle, and the "Castle" in the foreground.
Then, I used a slightly adjusted version of my parallax hover code override (you can copy it from below) to make these layers follow my cursor with different intensities.
About the resource
I had a pretty easy job creating these cards since I just had to use some of the resources already available here at Framer University.
Parallax hover
First, let's see how I achieved the parallax hover effect.
I divided the content of the card into three layers. We have the "Sky" in the background, the "Text" in the middle, and the "Castle" in the foreground.
Then, I used a slightly adjusted version of my parallax hover code override (you can copy it from below) to make these layers follow my cursor with different intensities.
About the resource
I had a pretty easy job creating these cards since I just had to use some of the resources already available here at Framer University.
Parallax hover
First, let's see how I achieved the parallax hover effect.
I divided the content of the card into three layers. We have the "Sky" in the background, the "Text" in the middle, and the "Castle" in the foreground.
Then, I used a slightly adjusted version of my parallax hover code override (you can copy it from below) to make these layers follow my cursor with different intensities.
The slight adjustment in the override includes two new properties: "maxOffsetX" and "maxOffsetY". I need these values so I can not only change the intensity of the cursor follow but also ensure that the images do not move beyond a certain point on the X axis to prevent revealing the edges of the foreground images.
The slight adjustment in the override includes two new properties: "maxOffsetX" and "maxOffsetY". I need these values so I can not only change the intensity of the cursor follow but also ensure that the images do not move beyond a certain point on the X axis to prevent revealing the edges of the foreground images.
The slight adjustment in the override includes two new properties: "maxOffsetX" and "maxOffsetY". I need these values so I can not only change the intensity of the cursor follow but also ensure that the images do not move beyond a certain point on the X axis to prevent revealing the edges of the foreground images.
As you can see in the image above, at the highlighted parts, you can change the intensity (10), maxOffsetX (400), and maxOffsetY (2000).
Blur Gradient
For the blur gradient, I simply used my component and placed it above the card's content so it blurs everything below it.
Parallax hover code override
Feel free to copy the code override from below and create it for yourself in Framer from scratch.
As you can see in the image above, at the highlighted parts, you can change the intensity (10), maxOffsetX (400), and maxOffsetY (2000).
Blur Gradient
For the blur gradient, I simply used my component and placed it above the card's content so it blurs everything below it.
Parallax hover code override
Feel free to copy the code override from below and create it for yourself in Framer from scratch.
As you can see in the image above, at the highlighted parts, you can change the intensity (10), maxOffsetX (400), and maxOffsetY (2000).
Blur Gradient
For the blur gradient, I simply used my component and placed it above the card's content so it blurs everything below it.
Parallax hover code override
Feel free to copy the code override from below and create it for yourself in Framer from scratch.
import { useState, useEffect, ComponentType, useRef } from "react"
import { motion, useMotionValue, useSpring, useInView } from "framer-motion"
const withIntensity = (
Component,
maxDistancePercentage,
maxOffsetX,
maxOffsetY
): ComponentType => {
const SPRING_CONFIG = { damping: 100, stiffness: 400 }
return (props) => {
const x = useMotionValue(0)
const y = useMotionValue(0)
const ref = useRef(null)
const springX = useSpring(x, SPRING_CONFIG)
const springY = useSpring(y, SPRING_CONFIG)
const isInView = useInView(ref)
useEffect(() => {
if (!isInView) {
x.set(0)
y.set(0)
}
}, [isInView])
useEffect(() => {
const calculateDistance = (e) => {
if (ref.current && isInView) {
const rect = ref.current.getBoundingClientRect()
const centerX = rect.left + rect.width / 2
const centerY = rect.top + rect.height / 2
let distanceX = e.clientX - centerX
let distanceY = e.clientY - centerY
distanceX = Math.max(
Math.min(distanceX, maxOffsetX),
-maxOffsetX
)
distanceY = Math.max(
Math.min(distanceY, maxOffsetY),
-maxOffsetY
)
x.set(distanceX * (maxDistancePercentage / 100))
y.set(distanceY * (maxDistancePercentage / 100))
}
}
document.addEventListener("mousemove", calculateDistance)
return () => {
document.removeEventListener("mousemove", calculateDistance)
}
}, [ref, isInView, maxOffsetX, maxOffsetY])
return (
<Component
{...props}
ref={ref}
style={{
x: springX,
y: springY,
}}
/>
)
}
}
export const withIntensity10 = (Component): ComponentType =>
withIntensity(Component, 10, 400, 2000)
export const withIntensity5 = (Component): ComponentType =>
withIntensity(Component, 5, 2000, 2000)
export const withIntensity1 = (Component): ComponentType =>
withIntensity(Component, 1, 2000, 2000)
import { useState, useEffect, ComponentType, useRef } from "react"
import { motion, useMotionValue, useSpring, useInView } from "framer-motion"
const withIntensity = (
Component,
maxDistancePercentage,
maxOffsetX,
maxOffsetY
): ComponentType => {
const SPRING_CONFIG = { damping: 100, stiffness: 400 }
return (props) => {
const x = useMotionValue(0)
const y = useMotionValue(0)
const ref = useRef(null)
const springX = useSpring(x, SPRING_CONFIG)
const springY = useSpring(y, SPRING_CONFIG)
const isInView = useInView(ref)
useEffect(() => {
if (!isInView) {
x.set(0)
y.set(0)
}
}, [isInView])
useEffect(() => {
const calculateDistance = (e) => {
if (ref.current && isInView) {
const rect = ref.current.getBoundingClientRect()
const centerX = rect.left + rect.width / 2
const centerY = rect.top + rect.height / 2
let distanceX = e.clientX - centerX
let distanceY = e.clientY - centerY
distanceX = Math.max(
Math.min(distanceX, maxOffsetX),
-maxOffsetX
)
distanceY = Math.max(
Math.min(distanceY, maxOffsetY),
-maxOffsetY
)
x.set(distanceX * (maxDistancePercentage / 100))
y.set(distanceY * (maxDistancePercentage / 100))
}
}
document.addEventListener("mousemove", calculateDistance)
return () => {
document.removeEventListener("mousemove", calculateDistance)
}
}, [ref, isInView, maxOffsetX, maxOffsetY])
return (
<Component
{...props}
ref={ref}
style={{
x: springX,
y: springY,
}}
/>
)
}
}
export const withIntensity10 = (Component): ComponentType =>
withIntensity(Component, 10, 400, 2000)
export const withIntensity5 = (Component): ComponentType =>
withIntensity(Component, 5, 2000, 2000)
export const withIntensity1 = (Component): ComponentType =>
withIntensity(Component, 1, 2000, 2000)
import { useState, useEffect, ComponentType, useRef } from "react"
import { motion, useMotionValue, useSpring, useInView } from "framer-motion"
const withIntensity = (
Component,
maxDistancePercentage,
maxOffsetX,
maxOffsetY
): ComponentType => {
const SPRING_CONFIG = { damping: 100, stiffness: 400 }
return (props) => {
const x = useMotionValue(0)
const y = useMotionValue(0)
const ref = useRef(null)
const springX = useSpring(x, SPRING_CONFIG)
const springY = useSpring(y, SPRING_CONFIG)
const isInView = useInView(ref)
useEffect(() => {
if (!isInView) {
x.set(0)
y.set(0)
}
}, [isInView])
useEffect(() => {
const calculateDistance = (e) => {
if (ref.current && isInView) {
const rect = ref.current.getBoundingClientRect()
const centerX = rect.left + rect.width / 2
const centerY = rect.top + rect.height / 2
let distanceX = e.clientX - centerX
let distanceY = e.clientY - centerY
distanceX = Math.max(
Math.min(distanceX, maxOffsetX),
-maxOffsetX
)
distanceY = Math.max(
Math.min(distanceY, maxOffsetY),
-maxOffsetY
)
x.set(distanceX * (maxDistancePercentage / 100))
y.set(distanceY * (maxDistancePercentage / 100))
}
}
document.addEventListener("mousemove", calculateDistance)
return () => {
document.removeEventListener("mousemove", calculateDistance)
}
}, [ref, isInView, maxOffsetX, maxOffsetY])
return (
<Component
{...props}
ref={ref}
style={{
x: springX,
y: springY,
}}
/>
)
}
}
export const withIntensity10 = (Component): ComponentType =>
withIntensity(Component, 10, 400, 2000)
export const withIntensity5 = (Component): ComponentType =>
withIntensity(Component, 5, 2000, 2000)
export const withIntensity1 = (Component): ComponentType =>
withIntensity(Component, 1, 2000, 2000)