Portfolio - Copy this React, Tailwind Component to your project
puedes o no usar esto de fondo? este es mi layout.jsx import { Metadata } from "next"; import localFont from "next/font/local"; import "./globals.css"; const geistSans = localFont({ src: "./fonts/GeistVF.woff", variable: "--font-geist-sans", weight: "100 900", }); const geistMono = localFont({ src: "./fonts/GeistMonoVF.woff", variable: "--font-geist-mono", weight: "100 900", }); export const metadata = { title: "Create Next App", description: "Generated by create next app", }; export default function RootLayout({ children }) { return ( <html lang="en"> <body className={`${geistSans.variable} ${geistMono.variable} antialiased`} > {children} </body> </html> ); } este es mi page.jsx import RotatingBackground from '../components/RotatingBackground' export default function Home() { return ( <main className="min-h-screen"> <RotatingBackground /> <div className="container mx-auto px-4 py-20"> <h1 className="text-4xl font-bold mb-8 text-center">Mi Portfolio</h1> <div className="space-y-20"> {[...Array(5)].map((_, i) => ( <section key={i} className="bg-white bg-opacity-80 p-8 rounded-lg shadow-lg"> <h2 className="text-2xl font-semibold mb-4">Proyecto {i + 1}</h2> <p className="text-gray-700"> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. </p> </section> ))} </div> </div> </main> ) } este es mi rotate.jsx import { motion, useScroll, useTransform } from 'framer-motion' const AnimatedBoxes = ({ boxes }) => { const { scrollYProgress } = useScroll() return ( <motion.div style={{ overflow: 'auto', height: '100vh' }}> {boxes.map((box, index) => ( <motion.div key={index} style={{ width: 100, height: 100, background: `hsl(${index * 70}, 100%, 50%)`, position: 'absolute', left: 0, top: 0, rotate: useTransform(scrollYProgress, [0, 1], [0, 360]), scale: useTransform(scrollYProgress, [0, 1], [1, 1.5]), x: useTransform(scrollYProgress, [0, 1], [0, (index % 2 === 0 ? 100 : -100)]), y: useTransform(scrollYProgress, [0, 1], [0, ((index % 3) - 1) * 100]), }} /> ))} </motion.div> ) } export default AnimatedBoxes este es mi roatatingbackground.jsx 'use client' import { useEffect, useState, useMemo } from 'react' import { motion, useScroll, useSpring, useTransform } from 'framer-motion' import Image from 'next/image' const images = [ 'https://i.ibb.co/s6kTxBd/image1.jpg', 'https://i.ibb.co/MPfTGpq/image2.jpg', 'https://i.ibb.co/3z5Cv5S/image3.jpg', 'https://i.ibb.co/PrG4JP2/image4.jpg', 'https://i.ibb.co/fpZmMxD/image5.jpg', 'https://i.ibb.co/VgNCJP7/image6.jpg' ] const AnimatedImage = ({ src, index, scrollYProgress }) => { const rotate = useSpring( useTransform(scrollYProgress, [0, 1], [0, 360]), { stiffness: 50, damping: 30 } ) const scale = useSpring( useTransform(scrollYProgress, [0, 1], [1, 1.5]), { stiffness: 50, damping: 30 } ) const x = useSpring( useTransform(scrollYProgress, [0, 1], [0, (index % 2 === 0 ? 100 : -100)]), { stiffness: 50, damping: 30 } ) const y = useSpring( useTransform(scrollYProgress, [0, 1], [0, ((index % 3) - 1) * 100]), { stiffness: 50, damping: 30 } ) return ( <motion.div className="absolute" style={{ width: '30vmin', height: '30vmin', top: `${(index % 3) * 33}%`, left: `${Math.floor(index / 3) * 33}%`, rotate, scale, x, y, }} > <Image src={src} alt={`Background ${index + 1}`} layout="fill" objectFit="cover" className="rounded-lg" /> </motion.div> ) } export default function RotatingBackground() { const [isMounted, setIsMounted] = useState(false) const { scrollYProgress } = useScroll() useEffect(() => { setIsMounted(true) }, []) const animatedImages = useMemo(() => images.map((src, index) => ( <AnimatedImage key={src} src={src} index={index} scrollYProgress={scrollYProgress} /> )), [scrollYProgress] ) return ( <div className="fixed inset-0 -z-10 overflow-hidden"> {isMounted && animatedImages} </div> ) }