forked from 77media/video-flow
处理控制台报错
This commit is contained in:
parent
8a282143fe
commit
b8bae86ae7
@ -1,5 +1,6 @@
|
|||||||
import React, { useEffect, useRef } from 'react';
|
import React, { useEffect, useRef } from 'react';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
import dynamic from 'next/dynamic';
|
||||||
|
|
||||||
// 导入图片资源
|
// 导入图片资源
|
||||||
import mono from '@/assets/3dr_mono.png';
|
import mono from '@/assets/3dr_mono.png';
|
||||||
@ -56,7 +57,8 @@ const Parallax = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (pageX) {
|
if (pageX) {
|
||||||
pageX.addEventListener('mousemove', parallax as EventListener, false);
|
// Add the passive flag to the event listener to improve scrolling performance
|
||||||
|
pageX.addEventListener('mousemove', parallax as EventListener, { passive: true });
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
pageX.removeEventListener('mousemove', parallax as EventListener);
|
pageX.removeEventListener('mousemove', parallax as EventListener);
|
||||||
@ -226,4 +228,5 @@ const CardTitle = styled.p`
|
|||||||
color: #fff;
|
color: #fff;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default Parallax;
|
// Export with noSSR to prevent server-side rendering issues
|
||||||
|
export default dynamic(() => Promise.resolve(Parallax), { ssr: false });
|
||||||
@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
import React, { useRef, useEffect, memo } from 'react'
|
import React, { useRef, useEffect, memo } from 'react'
|
||||||
import dynamic from 'next/dynamic'
|
import dynamic from 'next/dynamic'
|
||||||
// Import THREE only once and use it consistently
|
// Remove direct import of THREE to avoid SSR issues
|
||||||
import * as THREE from 'three'
|
// import * as THREE from 'three'
|
||||||
|
|
||||||
interface VantaHaloBackgroundProps {
|
interface VantaHaloBackgroundProps {
|
||||||
onLoaded?: () => void;
|
onLoaded?: () => void;
|
||||||
@ -14,6 +14,7 @@ interface VantaHaloBackgroundProps {
|
|||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
VANTA: any;
|
VANTA: any;
|
||||||
|
THREE: any; // Add THREE to window type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +69,7 @@ const VantaHaloBackground = memo(({ onLoaded }: VantaHaloBackgroundProps) => {
|
|||||||
if (window.VANTA && window.VANTA.HALO) {
|
if (window.VANTA && window.VANTA.HALO) {
|
||||||
effectInstance.current = window.VANTA.HALO({
|
effectInstance.current = window.VANTA.HALO({
|
||||||
el: vantaRef.current,
|
el: vantaRef.current,
|
||||||
THREE, // Pass the imported THREE instance
|
THREE: window.THREE, // Use THREE from window instead of import
|
||||||
mouseControls: true,
|
mouseControls: true,
|
||||||
touchControls: true,
|
touchControls: true,
|
||||||
gyroControls: false,
|
gyroControls: false,
|
||||||
@ -136,4 +137,5 @@ const VantaHaloBackground = memo(({ onLoaded }: VantaHaloBackgroundProps) => {
|
|||||||
|
|
||||||
VantaHaloBackground.displayName = 'VantaHaloBackground'
|
VantaHaloBackground.displayName = 'VantaHaloBackground'
|
||||||
|
|
||||||
export default VantaHaloBackground
|
// Export with noSSR to prevent server-side rendering
|
||||||
|
export default dynamic(() => Promise.resolve(VantaHaloBackground), { ssr: false })
|
||||||
|
|||||||
@ -1,6 +1,9 @@
|
|||||||
|
'use client'; // Add this to ensure it's a client component
|
||||||
|
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { Edit2, Trash2, Play } from 'lucide-react';
|
import { Edit2, Trash2, Play } from 'lucide-react';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
|
import dynamic from 'next/dynamic';
|
||||||
|
|
||||||
interface VideoGridLayoutProps {
|
interface VideoGridLayoutProps {
|
||||||
videos: {
|
videos: {
|
||||||
@ -13,7 +16,7 @@ interface VideoGridLayoutProps {
|
|||||||
onDelete?: (id: string) => void;
|
onDelete?: (id: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function VideoGridLayout({ videos, onEdit, onDelete }: VideoGridLayoutProps) {
|
function VideoGridLayoutComponent({ videos, onEdit, onDelete }: VideoGridLayoutProps) {
|
||||||
const [hoveredId, setHoveredId] = useState<string | null>(null);
|
const [hoveredId, setHoveredId] = useState<string | null>(null);
|
||||||
const [isPlaying, setIsPlaying] = useState<{ [key: string]: boolean }>({});
|
const [isPlaying, setIsPlaying] = useState<{ [key: string]: boolean }>({});
|
||||||
|
|
||||||
@ -58,6 +61,7 @@ export function VideoGridLayout({ videos, onEdit, onDelete }: VideoGridLayoutPro
|
|||||||
<video
|
<video
|
||||||
id={`video-${video.id}`}
|
id={`video-${video.id}`}
|
||||||
src={video.url}
|
src={video.url}
|
||||||
|
suppressHydrationWarning
|
||||||
className="w-full h-full object-cover"
|
className="w-full h-full object-cover"
|
||||||
loop
|
loop
|
||||||
muted
|
muted
|
||||||
@ -113,3 +117,8 @@ export function VideoGridLayout({ videos, onEdit, onDelete }: VideoGridLayoutPro
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Export as a client-only component to prevent hydration issues
|
||||||
|
export const VideoGridLayout = dynamic(() => Promise.resolve(VideoGridLayoutComponent), {
|
||||||
|
ssr: false
|
||||||
|
});
|
||||||
@ -1,6 +1,9 @@
|
|||||||
|
'use client'; // Add this to ensure it's a client component
|
||||||
|
|
||||||
import React, { useState, useRef, useEffect } from 'react';
|
import React, { useState, useRef, useEffect } from 'react';
|
||||||
import { ChevronLeft, ChevronRight } from 'lucide-react';
|
import { ChevronLeft, ChevronRight } from 'lucide-react';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
|
import dynamic from 'next/dynamic';
|
||||||
|
|
||||||
interface VideoScreenLayoutProps {
|
interface VideoScreenLayoutProps {
|
||||||
videos: {
|
videos: {
|
||||||
@ -10,7 +13,7 @@ interface VideoScreenLayoutProps {
|
|||||||
}[];
|
}[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function VideoScreenLayout({ videos }: VideoScreenLayoutProps) {
|
function VideoScreenLayoutComponent({ videos }: VideoScreenLayoutProps) {
|
||||||
const [currentIndex, setCurrentIndex] = useState(0);
|
const [currentIndex, setCurrentIndex] = useState(0);
|
||||||
const [isAnimating, setIsAnimating] = useState(false);
|
const [isAnimating, setIsAnimating] = useState(false);
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
@ -74,9 +77,10 @@ export function VideoScreenLayout({ videos }: VideoScreenLayoutProps) {
|
|||||||
style={getPanelStyle(index)}
|
style={getPanelStyle(index)}
|
||||||
>
|
>
|
||||||
<div className="relative w-full h-full overflow-hidden rounded-lg">
|
<div className="relative w-full h-full overflow-hidden rounded-lg">
|
||||||
{/* 视频 */}
|
{/* 视频 - Add suppressHydrationWarning to prevent className mismatch warnings */}
|
||||||
<video
|
<video
|
||||||
src={video.url}
|
src={video.url}
|
||||||
|
suppressHydrationWarning
|
||||||
className="w-full h-full object-cover"
|
className="w-full h-full object-cover"
|
||||||
autoPlay
|
autoPlay
|
||||||
loop
|
loop
|
||||||
@ -123,3 +127,8 @@ export function VideoScreenLayout({ videos }: VideoScreenLayoutProps) {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Export as a client-only component to prevent hydration issues
|
||||||
|
export const VideoScreenLayout = dynamic(() => Promise.resolve(VideoScreenLayoutComponent), {
|
||||||
|
ssr: false
|
||||||
|
});
|
||||||
Loading…
x
Reference in New Issue
Block a user