Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance Coffee Cup Image with Parallax Effect #54

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"dependencies": {
"@splidejs/splide": "^4.1.4",
"@splidejs/splide-extension-auto-scroll": "^0.5.3",
"aos": "^2.3.4",
"autoprefixer": "^10.4.19",
"clsx": "^2.1.1",
"framer-motion": "^11.5.6",
Expand Down
69 changes: 64 additions & 5 deletions frontend/src/components/ui/Landing.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,45 @@
import { useState, useEffect } from 'react';
import heropic from "../../assets/landing/hero pic.jpg";
import coffecup from "../../assets/landing/coffecup.png";
import { motion } from 'framer-motion';
import AOS from 'aos'
import 'aos/dist/aos.css'

const parallaxVariants = {
initial: { scale: 1 },
animate: { scale: 1.05 },
};

const transition = {
type: "spring",
stiffness: 200,
damping: 10,
};

export default function Landing() {
useEffect(() => {
AOS.init({
duration: 1000,
once: true,
})
}, [])

const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 });

const handleMouseMove = (e) => {
const { clientX, clientY } = e;
setMousePosition({ x: clientX, y: clientY });
};
Comment on lines +29 to +32
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Throttle handleMouseMove for Improved Performance

Updating state on every mouse move event can lead to performance issues due to excessive re-renders. To optimize performance, consider throttling the handleMouseMove function.

You can use requestAnimationFrame to limit updates to once per animation frame:

+import { useRef } from 'react';

 export default function Landing() {

   const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 });
+  const animationFrame = useRef(null);
 
   const handleMouseMove = (e) => {
+    if (animationFrame.current === null) {
+      animationFrame.current = requestAnimationFrame(() => {
         const { clientX, clientY } = e;
         setMousePosition({ x: clientX, y: clientY });
+        animationFrame.current = null;
+      });
+    }
   };

This ensures that state updates occur at most once per frame, reducing the render load.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const handleMouseMove = (e) => {
const { clientX, clientY } = e;
setMousePosition({ x: clientX, y: clientY });
};
import { useRef } from 'react';
export default function Landing() {
const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 });
const animationFrame = useRef(null);
const handleMouseMove = (e) => {
if (animationFrame.current === null) {
animationFrame.current = requestAnimationFrame(() => {
const { clientX, clientY } = e;
setMousePosition({ x: clientX, y: clientY });
animationFrame.current = null;
});
}
};


const parallaxEffect = {
x: mousePosition.x / 100,
y: mousePosition.y / 100,


};
Comment on lines +34 to +39
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Adjust parallaxEffect Implementation for Correct Motion

The parallaxEffect object currently sets x and y properties based on the mouse position and applies them directly to the style prop of the motion.img. However, in Framer Motion, to animate positional properties like x and y, these should be motion values or controlled via the animate prop. Using plain numbers in the style prop won't produce the intended animation effect.

Consider using motion values or updating the animate prop to achieve the desired parallax effect. Here's how you can modify the code:

+import { useMotionValue, useTransform } from 'framer-motion';

...

+const x = useMotionValue(0);
+const y = useMotionValue(0);

...

 const handleMouseMove = (e) => {
-  const { clientX, clientY } = e;
-  setMousePosition({ x: clientX, y: clientY });
+  const { clientX, clientY } = e;
+  // Calculate the offset from the center of the screen
+  const offsetX = (clientX - window.innerWidth / 2) / 20;
+  const offsetY = (clientY - window.innerHeight / 2) / 20;
+  x.set(offsetX);
+  y.set(offsetY);
 };

-const parallaxEffect = {
-  x: mousePosition.x / 100,
-  y: mousePosition.y / 100,
-};

...

<motion.img
  src={coffecup}
  alt="Coffee Cup"
  className="cursor-pointer"
  variants={parallaxVariants}
  initial="initial"
  animate="animate"
  whileHover={{ scale: 1.1 }}
  transition={transition}
- style={parallaxEffect }
+ style={{ x, y }}
/>

This approach uses useMotionValue to create reactive x and y values that Framer Motion can animate efficiently.

Also applies to: 89-91

return (
<div>
<section className="relative pb-24 h-screen-dvh w-screen bg-cover bg-center overflow-hidden">
<section className="relative pb-24 mb-36 h-screen-dvh w-screen bg-cover bg-center overflow-hidden" >
<div className="flex-col md:flex pt-20 z-1">
{/* Text Content */}
<div className="w-screen p-4 md:w-1/2 mb-6 md:mb-0 text-center md:text-left z-10 pt-14">
Expand All @@ -27,7 +61,7 @@ export default function Landing() {
</section>


<section className="flex flex-row justify-center items-center p-32">
<section className="flex flex-row justify-center items-center p-32" >
{/* <div className="w-3/5 p-28 mt-20">
<h1 className="text-8xl font-bold text-black ">
Our name says it all!
Expand All @@ -50,12 +84,37 @@ export default function Landing() {
<button className="p-2 border-2 border-slate-500">Learn more↗️</button>
</div> */}

<div className="w-1/2 absolute p-4 md:right-40 m-auto">
<img src={coffecup} alt="" className="w-96 rotate-12"/>
<div className="w-1/2 absolute p-4 md:right-40 m-auto rotate-12" onMouseMove={handleMouseMove}>
<motion.img
src={coffecup}
alt="Coffee Cup"
className="cursor-pointer"
variants={parallaxVariants}
initial="initial"
animate="animate"
whileHover={{ scale: 1.1 }}
transition={transition}
style={parallaxEffect }

/>
</div>

<div className="py-28 z-10">
<h1 className="text-[4rem] md:text-[18rem] font-bold text-black">
PLAYCAFE
<span
data-aos="fade-left"
data-aos-delay="600"
className=""
>
PLAY
</span>
<span
data-aos="fade-left"
data-aos-delay="1000"
className=""
>
CAFE
</span>
</h1>
</div>
</section>
Expand Down