Effect
3D Hover Override
This is a 3D hover code override that you can apply to any element to achieve a pleasing 3D hover effect. For an enhanced effect, there's an additional override in the file applicable to a 'shine' layer. This will make the shine follow the cursor, producing an illusion of light shining on the card when you hover over it.
About the resource
The file contains the necessary override for the 3D hover effect, which should be applied to the card. It also includes an override that makes the layer follow the cursor, which should be applied to the 'shine' layer.
Watch the tutorial video for detailed instructions on how to utilize this effect.
Code override for 3D hover
You can also copy the code for the 3D hover override and create the override from scratch in your project.
About the resource
The file contains the necessary override for the 3D hover effect, which should be applied to the card. It also includes an override that makes the layer follow the cursor, which should be applied to the 'shine' layer.
Watch the tutorial video for detailed instructions on how to utilize this effect.
Code override for 3D hover
You can also copy the code for the 3D hover override and create the override from scratch in your project.
About the resource
The file contains the necessary override for the 3D hover effect, which should be applied to the card. It also includes an override that makes the layer follow the cursor, which should be applied to the 'shine' layer.
Watch the tutorial video for detailed instructions on how to utilize this effect.
Code override for 3D hover
You can also copy the code for the 3D hover override and create the override from scratch in your project.
// © Framer University. All rights reserved. import type { ComponentType } from "react" import { motion, useSpring } from "framer-motion" import React, { useState, useRef, useEffect } from "react" // Learn more: https://www.framer.com/docs/guides/overrides/ //Spring animation parameters const spring = { type: "spring", stiffness: 300, damping: 30, } /** * Based on the code created by Joshua Guo * * @framerSupportedLayoutWidth fixed * @framerSupportedLayoutHeight fixed */ export function with3D(Component): ComponentType { return (props) => { const [rotateXaxis, setRotateXaxis] = useState(0) const [rotateYaxis, setRotateYaxis] = useState(0) const ref = useRef(null) const handleMouseMove = (event) => { const element = ref.current const elementRect = element.getBoundingClientRect() const elementWidth = elementRect.width const elementHeight = elementRect.height const elementCenterX = elementWidth / 2 const elementCenterY = elementHeight / 2 const mouseX = event.clientY - elementRect.y - elementCenterY const mouseY = event.clientX - elementRect.x - elementCenterX const degreeX = (mouseX / elementWidth) * -20 //The number is the rotation factor const degreeY = (mouseY / elementHeight) * -20 //The number is the rotation factor setRotateXaxis(degreeX) setRotateYaxis(degreeY) } const handleMouseEnd = () => { setRotateXaxis(0) setRotateYaxis(0) } const dx = useSpring(0, spring) const dy = useSpring(0, spring) useEffect(() => { dx.set(-rotateXaxis) dy.set(rotateYaxis) }, [rotateXaxis, rotateYaxis]) return ( <motion.div transition={spring} style={{ perspective: "1200px", transformStyle: "preserve-3d", width: `${props.width}`, height: `${props.height}`, }} > <motion.div ref={ref} whileHover={{ scale: 1.1 }} //Change the scale of zooming in when hovering onMouseMove={handleMouseMove} onMouseLeave={handleMouseEnd} transition={spring} style={{ width: "100%", height: "100%", rotateX: dx, rotateY: dy, }} > <div style={{ perspective: "1200px", transformStyle: "preserve-3d", width: "100%", height: "100%", }} > <motion.div transition={spring} style={{ width: "100%", height: "100%", backfaceVisibility: "hidden", position: "absolute", }} > <Component {...props} variant="Front" style={{ width: "100%", height: "100%", }} /> </motion.div> <motion.div initial={{ rotateY: 180 }} transition={spring} style={{ width: "100%", height: "100%", zIndex: 0, backfaceVisibility: "hidden", position: "absolute", }} > <Component {...props} variant="Back" style={{ width: "100%", height: "100%", }} /> </motion.div> </div> </motion.div> </motion.div> ) } }
// © Framer University. All rights reserved. import type { ComponentType } from "react" import { motion, useSpring } from "framer-motion" import React, { useState, useRef, useEffect } from "react" // Learn more: https://www.framer.com/docs/guides/overrides/ //Spring animation parameters const spring = { type: "spring", stiffness: 300, damping: 30, } /** * Based on the code created by Joshua Guo * * @framerSupportedLayoutWidth fixed * @framerSupportedLayoutHeight fixed */ export function with3D(Component): ComponentType { return (props) => { const [rotateXaxis, setRotateXaxis] = useState(0) const [rotateYaxis, setRotateYaxis] = useState(0) const ref = useRef(null) const handleMouseMove = (event) => { const element = ref.current const elementRect = element.getBoundingClientRect() const elementWidth = elementRect.width const elementHeight = elementRect.height const elementCenterX = elementWidth / 2 const elementCenterY = elementHeight / 2 const mouseX = event.clientY - elementRect.y - elementCenterY const mouseY = event.clientX - elementRect.x - elementCenterX const degreeX = (mouseX / elementWidth) * -20 //The number is the rotation factor const degreeY = (mouseY / elementHeight) * -20 //The number is the rotation factor setRotateXaxis(degreeX) setRotateYaxis(degreeY) } const handleMouseEnd = () => { setRotateXaxis(0) setRotateYaxis(0) } const dx = useSpring(0, spring) const dy = useSpring(0, spring) useEffect(() => { dx.set(-rotateXaxis) dy.set(rotateYaxis) }, [rotateXaxis, rotateYaxis]) return ( <motion.div transition={spring} style={{ perspective: "1200px", transformStyle: "preserve-3d", width: `${props.width}`, height: `${props.height}`, }} > <motion.div ref={ref} whileHover={{ scale: 1.1 }} //Change the scale of zooming in when hovering onMouseMove={handleMouseMove} onMouseLeave={handleMouseEnd} transition={spring} style={{ width: "100%", height: "100%", rotateX: dx, rotateY: dy, }} > <div style={{ perspective: "1200px", transformStyle: "preserve-3d", width: "100%", height: "100%", }} > <motion.div transition={spring} style={{ width: "100%", height: "100%", backfaceVisibility: "hidden", position: "absolute", }} > <Component {...props} variant="Front" style={{ width: "100%", height: "100%", }} /> </motion.div> <motion.div initial={{ rotateY: 180 }} transition={spring} style={{ width: "100%", height: "100%", zIndex: 0, backfaceVisibility: "hidden", position: "absolute", }} > <Component {...props} variant="Back" style={{ width: "100%", height: "100%", }} /> </motion.div> </div> </motion.div> </motion.div> ) } }
// © Framer University. All rights reserved. import type { ComponentType } from "react" import { motion, useSpring } from "framer-motion" import React, { useState, useRef, useEffect } from "react" // Learn more: https://www.framer.com/docs/guides/overrides/ //Spring animation parameters const spring = { type: "spring", stiffness: 300, damping: 30, } /** * Based on the code created by Joshua Guo * * @framerSupportedLayoutWidth fixed * @framerSupportedLayoutHeight fixed */ export function with3D(Component): ComponentType { return (props) => { const [rotateXaxis, setRotateXaxis] = useState(0) const [rotateYaxis, setRotateYaxis] = useState(0) const ref = useRef(null) const handleMouseMove = (event) => { const element = ref.current const elementRect = element.getBoundingClientRect() const elementWidth = elementRect.width const elementHeight = elementRect.height const elementCenterX = elementWidth / 2 const elementCenterY = elementHeight / 2 const mouseX = event.clientY - elementRect.y - elementCenterY const mouseY = event.clientX - elementRect.x - elementCenterX const degreeX = (mouseX / elementWidth) * -20 //The number is the rotation factor const degreeY = (mouseY / elementHeight) * -20 //The number is the rotation factor setRotateXaxis(degreeX) setRotateYaxis(degreeY) } const handleMouseEnd = () => { setRotateXaxis(0) setRotateYaxis(0) } const dx = useSpring(0, spring) const dy = useSpring(0, spring) useEffect(() => { dx.set(-rotateXaxis) dy.set(rotateYaxis) }, [rotateXaxis, rotateYaxis]) return ( <motion.div transition={spring} style={{ perspective: "1200px", transformStyle: "preserve-3d", width: `${props.width}`, height: `${props.height}`, }} > <motion.div ref={ref} whileHover={{ scale: 1.1 }} //Change the scale of zooming in when hovering onMouseMove={handleMouseMove} onMouseLeave={handleMouseEnd} transition={spring} style={{ width: "100%", height: "100%", rotateX: dx, rotateY: dy, }} > <div style={{ perspective: "1200px", transformStyle: "preserve-3d", width: "100%", height: "100%", }} > <motion.div transition={spring} style={{ width: "100%", height: "100%", backfaceVisibility: "hidden", position: "absolute", }} > <Component {...props} variant="Front" style={{ width: "100%", height: "100%", }} /> </motion.div> <motion.div initial={{ rotateY: 180 }} transition={spring} style={{ width: "100%", height: "100%", zIndex: 0, backfaceVisibility: "hidden", position: "absolute", }} > <Component {...props} variant="Back" style={{ width: "100%", height: "100%", }} /> </motion.div> </div> </motion.div> </motion.div> ) } }
Code override for cursor follow
You can also copy the code for the cursor follow override and create the override from scratch in your project.
Code override for cursor follow
You can also copy the code for the cursor follow override and create the override from scratch in your project.
Code override for cursor follow
You can also copy the code for the cursor follow override and create the override from scratch in your project.
// © Framer University. All rights reserved. import type { ComponentType } from "react" import { useRef, useState } from "react" import { useEffect } from "react" import { useSpring, animated } from "react-spring" export function withCursorFollow(Component): ComponentType { return (props) => { const ref = useRef(null) const [isHovering, setIsHovering] = useState(false) const [originalPosition, setOriginalPosition] = useState({ left: 0, top: 0, }) const [centerPosition, setCenterPosition] = useState({ left: 0, top: 0, }) const springProps = useSpring({ left: isHovering ? originalPosition.left : centerPosition.left, top: isHovering ? originalPosition.top : centerPosition.top, config: { mass: 1, tension: 170, friction: 26 }, }) useEffect(() => { if (!ref.current) return const buttonRect = ref.current.getBoundingClientRect() const elementRect = ref.current.getBoundingClientRect() setCenterPosition({ left: buttonRect.width / 2 - elementRect.width / 2, top: buttonRect.height / 2 - elementRect.height / 2, }) const handleMouseMove = (e) => { if (!ref.current) return if (e.target.closest("button")) { setIsHovering(true) const buttonRect = e.target.getBoundingClientRect() const elementRect = ref.current.getBoundingClientRect() setOriginalPosition({ left: e.clientX - buttonRect.left - elementRect.width / 2, top: e.clientY - buttonRect.top - elementRect.height / 2, }) setCenterPosition({ left: buttonRect.width / 2 - elementRect.width / 2, top: buttonRect.height / 2 - elementRect.height / 2, }) } else { setIsHovering(false) } } window.addEventListener("mousemove", handleMouseMove) return () => { window.removeEventListener("mousemove", handleMouseMove) } }, []) return ( <animated.div ref={ref} style={{ position: "absolute", pointerEvents: "none", left: springProps.left, top: springProps.top, }} > <Component {...props} /> </animated.div> ) } }
// © Framer University. All rights reserved. import type { ComponentType } from "react" import { useRef, useState } from "react" import { useEffect } from "react" import { useSpring, animated } from "react-spring" export function withCursorFollow(Component): ComponentType { return (props) => { const ref = useRef(null) const [isHovering, setIsHovering] = useState(false) const [originalPosition, setOriginalPosition] = useState({ left: 0, top: 0, }) const [centerPosition, setCenterPosition] = useState({ left: 0, top: 0, }) const springProps = useSpring({ left: isHovering ? originalPosition.left : centerPosition.left, top: isHovering ? originalPosition.top : centerPosition.top, config: { mass: 1, tension: 170, friction: 26 }, }) useEffect(() => { if (!ref.current) return const buttonRect = ref.current.getBoundingClientRect() const elementRect = ref.current.getBoundingClientRect() setCenterPosition({ left: buttonRect.width / 2 - elementRect.width / 2, top: buttonRect.height / 2 - elementRect.height / 2, }) const handleMouseMove = (e) => { if (!ref.current) return if (e.target.closest("button")) { setIsHovering(true) const buttonRect = e.target.getBoundingClientRect() const elementRect = ref.current.getBoundingClientRect() setOriginalPosition({ left: e.clientX - buttonRect.left - elementRect.width / 2, top: e.clientY - buttonRect.top - elementRect.height / 2, }) setCenterPosition({ left: buttonRect.width / 2 - elementRect.width / 2, top: buttonRect.height / 2 - elementRect.height / 2, }) } else { setIsHovering(false) } } window.addEventListener("mousemove", handleMouseMove) return () => { window.removeEventListener("mousemove", handleMouseMove) } }, []) return ( <animated.div ref={ref} style={{ position: "absolute", pointerEvents: "none", left: springProps.left, top: springProps.top, }} > <Component {...props} /> </animated.div> ) } }
// © Framer University. All rights reserved. import type { ComponentType } from "react" import { useRef, useState } from "react" import { useEffect } from "react" import { useSpring, animated } from "react-spring" export function withCursorFollow(Component): ComponentType { return (props) => { const ref = useRef(null) const [isHovering, setIsHovering] = useState(false) const [originalPosition, setOriginalPosition] = useState({ left: 0, top: 0, }) const [centerPosition, setCenterPosition] = useState({ left: 0, top: 0, }) const springProps = useSpring({ left: isHovering ? originalPosition.left : centerPosition.left, top: isHovering ? originalPosition.top : centerPosition.top, config: { mass: 1, tension: 170, friction: 26 }, }) useEffect(() => { if (!ref.current) return const buttonRect = ref.current.getBoundingClientRect() const elementRect = ref.current.getBoundingClientRect() setCenterPosition({ left: buttonRect.width / 2 - elementRect.width / 2, top: buttonRect.height / 2 - elementRect.height / 2, }) const handleMouseMove = (e) => { if (!ref.current) return if (e.target.closest("button")) { setIsHovering(true) const buttonRect = e.target.getBoundingClientRect() const elementRect = ref.current.getBoundingClientRect() setOriginalPosition({ left: e.clientX - buttonRect.left - elementRect.width / 2, top: e.clientY - buttonRect.top - elementRect.height / 2, }) setCenterPosition({ left: buttonRect.width / 2 - elementRect.width / 2, top: buttonRect.height / 2 - elementRect.height / 2, }) } else { setIsHovering(false) } } window.addEventListener("mousemove", handleMouseMove) return () => { window.removeEventListener("mousemove", handleMouseMove) } }, []) return ( <animated.div ref={ref} style={{ position: "absolute", pointerEvents: "none", left: springProps.left, top: springProps.top, }} > <Component {...props} /> </animated.div> ) } }