forked from 77media/video-flow
添加相关按钮
This commit is contained in:
parent
561516bc0c
commit
018e432328
@ -153,7 +153,7 @@
|
|||||||
min-height: 0;
|
min-height: 0;
|
||||||
}
|
}
|
||||||
.videoContainer-qteKNi {
|
.videoContainer-qteKNi {
|
||||||
flex: 1;
|
/* flex: 1; */
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import React, { useRef, useEffect, useState } from 'react';
|
import React, { useRef, useEffect, useState } from 'react';
|
||||||
import { motion, AnimatePresence } from 'framer-motion';
|
import { motion, AnimatePresence } from 'framer-motion';
|
||||||
import { Edit3, Play, Pause, Volume2, VolumeX } from 'lucide-react';
|
import { Edit3, Play, Pause, Volume2, VolumeX, Maximize, Minimize } from 'lucide-react';
|
||||||
import { ProgressiveReveal, presets } from '@/components/ui/progressive-reveal';
|
import { ProgressiveReveal, presets } from '@/components/ui/progressive-reveal';
|
||||||
import { GlassIconButton } from '@/components/ui/glass-icon-button';
|
import { GlassIconButton } from '@/components/ui/glass-icon-button';
|
||||||
|
|
||||||
@ -45,6 +45,10 @@ export function MediaViewer({
|
|||||||
// 音量控制状态
|
// 音量控制状态
|
||||||
const [isMuted, setIsMuted] = useState(false);
|
const [isMuted, setIsMuted] = useState(false);
|
||||||
const [volume, setVolume] = useState(0.8);
|
const [volume, setVolume] = useState(0.8);
|
||||||
|
|
||||||
|
// 最终视频控制状态
|
||||||
|
const [isFinalVideoPlaying, setIsFinalVideoPlaying] = useState(true);
|
||||||
|
const [isFullscreen, setIsFullscreen] = useState(false);
|
||||||
|
|
||||||
// 音量控制函数
|
// 音量控制函数
|
||||||
const toggleMute = () => {
|
const toggleMute = () => {
|
||||||
@ -75,6 +79,37 @@ export function MediaViewer({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 最终视频播放控制
|
||||||
|
const toggleFinalVideoPlay = () => {
|
||||||
|
if (finalVideoRef.current) {
|
||||||
|
if (isFinalVideoPlaying) {
|
||||||
|
finalVideoRef.current.pause();
|
||||||
|
} else {
|
||||||
|
finalVideoRef.current.play();
|
||||||
|
}
|
||||||
|
setIsFinalVideoPlaying(!isFinalVideoPlaying);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 全屏控制
|
||||||
|
const toggleFullscreen = () => {
|
||||||
|
if (!document.fullscreenElement) {
|
||||||
|
// 进入全屏
|
||||||
|
if (finalVideoRef.current) {
|
||||||
|
finalVideoRef.current.requestFullscreen?.() ||
|
||||||
|
(finalVideoRef.current as any).webkitRequestFullscreen?.() ||
|
||||||
|
(finalVideoRef.current as any).msRequestFullscreen?.();
|
||||||
|
setIsFullscreen(true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 退出全屏
|
||||||
|
document.exitFullscreen?.() ||
|
||||||
|
(document as any).webkitExitFullscreen?.() ||
|
||||||
|
(document as any).msExitFullscreen?.();
|
||||||
|
setIsFullscreen(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 视频播放控制
|
// 视频播放控制
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (mainVideoRef.current) {
|
if (mainVideoRef.current) {
|
||||||
@ -112,6 +147,23 @@ export function MediaViewer({
|
|||||||
}
|
}
|
||||||
}, [volume, isMuted]);
|
}, [volume, isMuted]);
|
||||||
|
|
||||||
|
// 监听全屏状态变化
|
||||||
|
useEffect(() => {
|
||||||
|
const handleFullscreenChange = () => {
|
||||||
|
setIsFullscreen(!!document.fullscreenElement);
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener('fullscreenchange', handleFullscreenChange);
|
||||||
|
document.addEventListener('webkitfullscreenchange', handleFullscreenChange);
|
||||||
|
document.addEventListener('msfullscreenchange', handleFullscreenChange);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener('fullscreenchange', handleFullscreenChange);
|
||||||
|
document.removeEventListener('webkitfullscreenchange', handleFullscreenChange);
|
||||||
|
document.removeEventListener('msfullscreenchange', handleFullscreenChange);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
// 渲染音量控制组件
|
// 渲染音量控制组件
|
||||||
const renderVolumeControls = () => (
|
const renderVolumeControls = () => (
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
@ -198,10 +250,12 @@ export function MediaViewer({
|
|||||||
className="w-full h-full object-cover rounded-lg"
|
className="w-full h-full object-cover rounded-lg"
|
||||||
src={finalVideo.url}
|
src={finalVideo.url}
|
||||||
poster={taskSketch[currentSketchIndex]?.url}
|
poster={taskSketch[currentSketchIndex]?.url}
|
||||||
autoPlay
|
autoPlay={isFinalVideoPlaying}
|
||||||
loop
|
loop
|
||||||
playsInline
|
playsInline
|
||||||
onLoadedData={() => applyVolumeSettings(finalVideoRef.current!)}
|
onLoadedData={() => applyVolumeSettings(finalVideoRef.current!)}
|
||||||
|
onPlay={() => setIsFinalVideoPlaying(true)}
|
||||||
|
onPause={() => setIsFinalVideoPlaying(false)}
|
||||||
/>
|
/>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
|
||||||
@ -250,14 +304,52 @@ export function MediaViewer({
|
|||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
|
||||||
{/* 底部音量控制 */}
|
{/* 底部控制区域 */}
|
||||||
<motion.div
|
<motion.div
|
||||||
className="absolute bottom-4 left-4 z-10 flex items-center gap-3"
|
className="absolute bottom-20 left-4 z-10 flex items-center gap-3"
|
||||||
initial={{ opacity: 0, scale: 0.8 }}
|
initial={{ opacity: 0, scale: 0.8 }}
|
||||||
animate={{ opacity: 1, scale: 1 }}
|
animate={{ opacity: 1, scale: 1 }}
|
||||||
transition={{ delay: 1, duration: 0.6 }}
|
transition={{ delay: 1, duration: 0.6 }}
|
||||||
>
|
>
|
||||||
|
{/* 播放/暂停按钮 */}
|
||||||
|
<motion.div
|
||||||
|
whileHover={{ scale: 1.1 }}
|
||||||
|
whileTap={{ scale: 0.9 }}
|
||||||
|
className="relative"
|
||||||
|
>
|
||||||
|
{/* 播放时的发光效果 */}
|
||||||
|
{isFinalVideoPlaying && (
|
||||||
|
<motion.div
|
||||||
|
className="absolute inset-0 rounded-full blur-md"
|
||||||
|
animate={{
|
||||||
|
scale: [1, 1.2, 1],
|
||||||
|
opacity: [0.5, 0.8, 0.5]
|
||||||
|
}}
|
||||||
|
transition={{
|
||||||
|
duration: 2,
|
||||||
|
repeat: Infinity,
|
||||||
|
ease: "easeInOut"
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<GlassIconButton
|
||||||
|
icon={isFinalVideoPlaying ? Pause : Play}
|
||||||
|
tooltip={isFinalVideoPlaying ? "Pause video" : "Play video"}
|
||||||
|
onClick={toggleFinalVideoPlay}
|
||||||
|
size="sm"
|
||||||
|
/>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
{/* 音量控制 */}
|
||||||
{renderVolumeControls()}
|
{renderVolumeControls()}
|
||||||
|
|
||||||
|
{/* 全屏按钮 */}
|
||||||
|
<GlassIconButton
|
||||||
|
icon={isFullscreen ? Minimize : Maximize}
|
||||||
|
tooltip={isFullscreen ? "退出全屏" : "全屏"}
|
||||||
|
onClick={toggleFullscreen}
|
||||||
|
size="sm"
|
||||||
|
/>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
|
||||||
{/* 完成标记 */}
|
{/* 完成标记 */}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user