Skip to content

Commit

Permalink
[feat]: added 3dcard and cursor doc
Browse files Browse the repository at this point in the history
  • Loading branch information
VineeTagarwaL-code committed Oct 11, 2024
1 parent e3d38a9 commit 60fdfaf
Show file tree
Hide file tree
Showing 64 changed files with 2,002 additions and 3,540 deletions.
Binary file modified bun.lockb
Binary file not shown.
167 changes: 167 additions & 0 deletions components/Card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
"use client";
import { cn } from "../utils/cn";
import React, {
createContext,
useState,
useContext,
useRef,
useEffect,
} from "react";

const MouseEnterContext = createContext<
[boolean, React.Dispatch<React.SetStateAction<boolean>>] | undefined
>(undefined);

const CardContainer = ({
children,
className,
containerClassName,
}: {
children?: React.ReactNode;
className?: string;
containerClassName?: string;
}) => {
const containerRef = useRef<HTMLDivElement>(null);
const [isMouseEntered, setIsMouseEntered] = useState(false);

const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {
if (!containerRef.current) return;
const { left, top, width, height } =
containerRef.current.getBoundingClientRect();
const x = (e.clientX - left - width / 2) / 25;
const y = (e.clientY - top - height / 2) / 25;
containerRef.current.style.transform = `rotateY(${x}deg) rotateX(${y}deg)`;
};

const handleMouseEnter = (e: React.MouseEvent<HTMLDivElement>) => {
setIsMouseEntered(true);
if (!containerRef.current) return;
};

const handleMouseLeave = (e: React.MouseEvent<HTMLDivElement>) => {
if (!containerRef.current) return;
setIsMouseEntered(false);
containerRef.current.style.transform = "rotateY(0deg) rotateX(0deg)";
};
return (
<MouseEnterContext.Provider value={[isMouseEntered, setIsMouseEntered]}>
<div
className={cn("flex items-center justify-center", containerClassName)}
style={{
perspective: "1000px",
}}
>
<div
ref={containerRef}
onMouseEnter={handleMouseEnter}
onMouseMove={handleMouseMove}
onMouseLeave={handleMouseLeave}
className={cn(
"flex items-center justify-center relative transition-all duration-200 ease-linear",
className
)}
style={{
transformStyle: "preserve-3d",
}}
>
{children}
</div>
</div>
</MouseEnterContext.Provider>
);
};

export const CardItem = ({
children,
className,
translateX = 0,
translateY = 0,
translateZ = 0,
rotateX = 0,
rotateY = 0,
rotateZ = 0,
...rest
}: {
as?: React.ElementType;
children: React.ReactNode;
className?: string;
translateX?: number | string;
translateY?: number | string;
translateZ?: number | string;
rotateX?: number | string;
rotateY?: number | string;
rotateZ?: number | string;
}) => {
const ref = useRef<HTMLDivElement>(null);
const [isMouseEntered] = useMouseEnter();

useEffect(() => {
handleAnimations();
}, [isMouseEntered]);

const handleAnimations = () => {
if (!ref.current) return;
if (isMouseEntered) {
ref.current.style.transform = `translateX(${translateX}px) translateY(${translateY}px) translateZ(${translateZ}px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) rotateZ(${rotateZ}deg)`;
} else {
ref.current.style.transform =
"translateX(0px) translateY(0px) translateZ(0px) rotateX(0deg) rotateY(0deg) rotateZ(0deg)";
}
};

return (
<div
ref={ref}
className={cn("w-fit transition duration-200 ease-linear", className)}
{...rest}
>
{children}
</div>
);
};

// Create a hook to use the context
export const useMouseEnter = () => {
const context = useContext(MouseEnterContext);
if (context === undefined) {
throw new Error("useMouseEnter must be used within a MouseEnterProvider");
}
return context;
};

/**
* @description CardItem component
*/
const Card = () => {
return (
<div className="flex justify-center items-center h-fit py-7 w-full px-2 ">
<div className="relative cursor-pointer animate-float md:block mr-8">
<CardContainer className=" cursor-pointer">
<div className="px-8 py-7 max-w-[400px] border-solid gap-5 bg-black flex flex-col justify-start item-center border-2 rounded-2xl">
<CardItem>
<img
src={"/V.png"}
alt={"platform"}
width={400}
height={400}
className="rounded-[3rem]"
/>
</CardItem>

<div className="px-4 flex flex-col justify-center items-start gap-5">
<h1 className="text-4xl text-white font-bold">V3cn</h1>

<h4 className="text-lg text-white">
Here you will get components which you wont get anywhere.
</h4>

<p className="text-purple-400">Made by Vineet & Team</p>
</div>
</div>
</CardContainer>
</div>
</div>
);
};

export { Card };
76 changes: 76 additions & 0 deletions components/Cursor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
"use client";
import { cn } from "../utils/cn";
import { useState, useEffect, useRef } from "react";
import { motion } from "framer-motion";

type cursorProp = {
cursorClass?: string;
};
export const Cursor = ({ cursorClass }: cursorProp) => {
const [isInteracting, setIsInteracting] = useState(false);
const [isClicked, setIsClicked] = useState(false);

const cursorRef = useRef(null);
const animateTrailer = (e: any) => {
const x =
e.clientX - (cursorRef.current as unknown as HTMLElement).offsetWidth / 2;
const y =
e.clientY -
(cursorRef.current as unknown as HTMLElement).offsetHeight / 2;

const keyframes = {
transform: `translate(${x}px, ${y}px) scale(${isInteracting ? 3 : 1})`,
};

(cursorRef.current as unknown as HTMLElement)?.animate(keyframes, {
duration: 100,
fill: "forwards",
});
};

useEffect(() => {
const handleMouseMove = (e: MouseEvent) => {
const interactable = (e.target as HTMLElement).closest(".interactable");
const interacting = interactable !== null;

animateTrailer(e);

setIsInteracting(interacting);
};

window.addEventListener("mousemove", handleMouseMove);

return () => {
window.removeEventListener("mousemove", handleMouseMove);
};
}, [isInteracting]);
useEffect(() => {
const handleClick = () => {
setIsClicked(true);
setTimeout(() => {
setIsClicked(false);
}, 100);
};

window.addEventListener("click", handleClick);

return () => {
window.removeEventListener("click", handleClick);
};
}, []);
return (
<>
<motion.div
whileTap={{ scale: 0.9 }}
id="trailer"
style={{ top: `0px`, left: `0px` }}
className={cn(
"bg-transparent rounded-full fixed z-50 pointer-events-none border-[3px] border-slate-500 border-solid w-10 h-10 transition-all",
isClicked && "w-8 h-8",
cursorClass
)}
ref={cursorRef}
></motion.div>
</>
);
};
3 changes: 3 additions & 0 deletions globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
Loading

0 comments on commit 60fdfaf

Please sign in to comment.