这是我的文件夹结构。该页面由分解的客户端组件组成,尤其是“hero.jsx”。 在此输入图片描述
在 page.jsx 或主页中,我导入了所有这些组件并确保它们不是 SSR
页面.jsx
**"use client";**
**import dynamic from "next/dynamic";**
import styles from "./page.module.css";
import LocomotiveScroll from "locomotive-scroll";
import { useEffect } from "react";
// Dynamically import components with SSR disabled
**const Hero = dynamic(() => import("./components/home/hero/hero"), {
ssr: false,
});
const Services = dynamic(() => import("./components/home/services/services"), {
ssr: false,
});
const Splash = dynamic(() => import("./components/splash/splash"), {
ssr: false,
});
const Navbar = dynamic(() => import("./components/navbar/navbar"), {
ssr: false,
});
**
const Home = () => {
**useEffect(() => {**
** if (typeof window !== 'undefined') {**
const locomotiveScroll = new LocomotiveScroll();
setIsClient(true)
** } **
}, []);
return (
<main
className={styles.main}
style={{
paddingBottom: "600px",
}}
>
<Navbar></Navbar>
<Splash></Splash>
<Hero></Hero>
<Services></Services>
</main>
);
};
export default Home;
动画发生在 Hero.jsx 中,窗口变量名为
英雄.jsx
**"use client";**
import styles from "./styles.module.css";
import Image from "next/image";
import gsap from "gsap";
import { useEffect, useRef } from "react";
import { ScrollTrigger } from "gsap/ScrollTrigger";
export default function Hero() {
//ref for texts
const bioText = useRef(null)
const descText = useRef(null)
const ctaText = useRef(null)
//ref for sliders
const firstList = useRef(null)
const secondList = useRef(null)
const slider = useRef(null)
const textWeb = useRef(null)
let xPercent = 0;
let direction = -1;
** useEffect(()=>{**
** if (typeof window !== "undefined") {**
requestAnimationFrame(animation)
gsap.registerPlugin(ScrollTrigger)
const timeline = gsap.timeline()
timeline
.to(slider.current, {
scrollTrigger: {
trigger: document.documentElement,
start: 0,
end: **window**.innerHeight,
scrub: 0.25,
onUpdate: (e) => (direction = e.direction * -1),
},
// x:'-=300px'
})
.to([slider.current, textWeb.current], {
duration: 2.5,
clipPath: "inset(0% 0% 0% 0%)",
ease: "power1.inOut",
})
.to(bioText.current, {
duration: 1,
clipPath: "inset(0% 0% 0% 0%)",
ease: "power1.inOut",
}, 1)
.to(descText.current, {
duration: 1,
clipPath: "inset(0% 0% 0% 0%)",
ease: "power1.inOut",
}, 1)
.to(ctaText.current, {
duration: 1,
clipPath: "inset(0% 0% 0% 0%)",
ease: "power1.inOut",
}, 1);
** }**
** }, [])**
const animation = () =>{
if(xPercent <= -100){
xPercent = 0;
}
if(xPercent > 0){
xPercent = -100;
}
gsap.set(firstList.current, {
xPercent: xPercent
})
gsap.set(secondList.current, {
xPercent: xPercent
})
xPercent += 0.01 * direction;
requestAnimationFrame(animation)
}
return (
<div className={styles.hero}>
<div className={styles.upperColumn}>
<div ref={bioText} data-scroll data-scroll-speed='0.2' className={styles.textWrapper}>
<div className={styles.profilePicture}>
<Image
src={"/images/pp rayyan.jpg"}
fill={true}
alt="profile picture rayyan"
/>
</div>
<p className={styles.mainParagraph}>
Rayyan is a web designer, <span className={styles.bolderText}>combining the skills of a designer and a
developer
</span>.
</p>
</div>
<div ref={ctaText} data-scroll data-scroll-speed='0.05' className={styles.textWrapper}>
<p className={styles.mainParagraph}>Know more about him.</p>
</div>
</div>
<div className={styles.midColumn}>
<h1 ref={textWeb} className={styles.webText}>WEB</h1>
<div ref={descText} className={styles.textWrapper}>
<p className={styles.mainParagraph}>
He is known for his web designs, animations, and interactions,
utilizing his React expertise to implement prototypes.
</p>
</div>
</div>
<div className={styles.lowColumn}>
<div data-scroll ref={slider} className={styles.slider}>
<div ref={firstList} className={styles.sliderList}>
<h1>DESIGNER</h1>
<div className={styles.svgContainer}>
<svg xmlns="http://www.w3.org/2000/svg" width="182" height="182" viewBox="0 0 182 182" fill="none">
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.047 144.74L54.7868 106H0V76H54.7868L16.047 37.2602L37.2602 16.047L75.567 54.3538V0H105.567V55.2198L144.74 16.0463L165.954 37.2595L127.213 76H182V106H127.213L165.954 144.74L144.74 165.954L105.567 126.78V182H75.567V127.646L37.2602 165.953L16.047 144.74Z" fill="#FF4D00"/>
</svg>
</div>
<h1>DEVELOPER</h1>
<div className={styles.svgContainer}>
<svg xmlns="http://www.w3.org/2000/svg" width="182" height="182" viewBox="0 0 182 182" fill="none">
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.047 144.74L54.7868 106H0V76H54.7868L16.047 37.2602L37.2602 16.047L75.567 54.3538V0H105.567V55.2198L144.74 16.0463L165.954 37.2595L127.213 76H182V106H127.213L165.954 144.74L144.74 165.954L105.567 126.78V182H75.567V127.646L37.2602 165.953L16.047 144.74Z" fill="#FF4D00"/>
</svg>
</div>
</div>
<div ref={secondList} className={styles.sliderList}>
<h1>DESIGNER</h1>
<div className={styles.svgContainer}>
<svg xmlns="http://www.w3.org/2000/svg" width="182" height="182" viewBox="0 0 182 182" fill="none">
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.047 144.74L54.7868 106H0V76H54.7868L16.047 37.2602L37.2602 16.047L75.567 54.3538V0H105.567V55.2198L144.74 16.0463L165.954 37.2595L127.213 76H182V106H127.213L165.954 144.74L144.74 165.954L105.567 126.78V182H75.567V127.646L37.2602 165.953L16.047 144.74Z" fill="#FF4D00"/>
</svg>
</div>
<h1>DEVELOPER</h1>
<div className={styles.svgContainer}>
<svg xmlns="http://www.w3.org/2000/svg" width="182" height="182" viewBox="0 0 182 182" fill="none">
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.047 144.74L54.7868 106H0V76H54.7868L16.047 37.2602L37.2602 16.047L75.567 54.3538V0H105.567V55.2198L144.74 16.0463L165.954 37.2595L127.213 76H182V106H127.213L165.954 144.74L144.74 165.954L105.567 126.78V182H75.567V127.646L37.2602 165.953L16.047 144.74Z" fill="#FF4D00"/>
</svg>
</div>
</div>
</div>
</div>
</div>
);
}
无法部署并出现这样的错误,即使它不会影响开发环境中的视觉或动画。
日志:
开发环境中的错误(在浏览器渲染后仍然有效,即使服务器控制台说窗口未定义,一切都很好):
** ⨯ ReferenceError:窗口未定义** 在 webpack_require (C:\Users\HP\Document