mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-17 05:13:32 +00:00
de9a7a87fd
* refactor(project structure): UI * refactor(project structure): extract utilities * refactor(project structure): remove unused * refactor(project structure): electron * refactor(project structure): server refactor: migrate to vitest refactor: monorepo config * refactor: extract application menu * refactor: exit process * refactor: extract tray menu * chore: electron build * Added Seconds in studio clock #282 --------- Co-authored-by: Fabian Posenau <fabian@fphome.de> --------- Co-authored-by: Fabian Posenau <fabian.p99@gmx.de> Co-authored-by: Fabian Posenau <fabian@fphome.de>
187 lines
4.1 KiB
React
187 lines
4.1 KiB
React
import { useEffect, useState } from 'react';
|
|
import { AnimatePresence, motion } from 'framer-motion';
|
|
|
|
import NavigationMenu from '../../../common/components/navigation-menu/NavigationMenu';
|
|
|
|
import './LowerLines.scss';
|
|
|
|
export default function LowerLines(props) {
|
|
const { lower, title, options } = props;
|
|
const defaults = {
|
|
size: 1,
|
|
transitionIn: 3,
|
|
textColour: '#fffffa',
|
|
bgColour: '#00000033',
|
|
};
|
|
const [showLower, setShowLower] = useState(true);
|
|
|
|
// Unmount if fadeOut
|
|
useEffect(() => {
|
|
if (!options.fadeOut) return;
|
|
|
|
// Calculate time
|
|
const fadeOutTime =
|
|
(parseInt(options.fadeOut, 10) +
|
|
(options.transitionIn || defaults.transitionIn)) *
|
|
1000;
|
|
if (isNaN(fadeOutTime)) return;
|
|
|
|
const timeout = setTimeout(() => {
|
|
setShowLower(false);
|
|
}, fadeOutTime);
|
|
|
|
return () => clearTimeout(timeout);
|
|
}, [options.fadeOut, options.transitionIn, defaults.transitionIn]);
|
|
|
|
useEffect(() => {
|
|
setShowLower(title.showNow);
|
|
}, [title.showNow]);
|
|
|
|
// Format messages
|
|
const showLowerMessage = lower.text !== '' && lower.visible;
|
|
|
|
// motion
|
|
// transition segments
|
|
const t = options.transitionIn || defaults.transitionIn;
|
|
const eight = t / 8;
|
|
const quarter = t / 4;
|
|
const third = t / 3;
|
|
const half = t / 2;
|
|
|
|
const lowerThirdVariants = {
|
|
hidden: {
|
|
opacity: 0,
|
|
},
|
|
visible: {
|
|
opacity: 1,
|
|
transition: {
|
|
duration: third,
|
|
},
|
|
},
|
|
exit: {
|
|
opacity: 0,
|
|
x: -1000,
|
|
transition: {
|
|
duration: third,
|
|
},
|
|
},
|
|
};
|
|
|
|
const titleContainerVariants = {
|
|
hidden: {
|
|
left: -1000,
|
|
},
|
|
visible: {
|
|
left: 0,
|
|
transition: {
|
|
duration: third,
|
|
},
|
|
},
|
|
};
|
|
|
|
const titleVariants = {
|
|
hidden: {
|
|
opacity: 0,
|
|
},
|
|
visible: {
|
|
opacity: 1,
|
|
transition: {
|
|
delay: quarter,
|
|
duration: half,
|
|
},
|
|
},
|
|
};
|
|
|
|
const subtitleContainerVariants = {
|
|
hidden: {
|
|
left: -1000,
|
|
},
|
|
visible: {
|
|
left: 0,
|
|
transition: {
|
|
delay: eight,
|
|
duration: third,
|
|
},
|
|
},
|
|
};
|
|
|
|
const subtitleVariants = {
|
|
hidden: {
|
|
opacity: 0,
|
|
},
|
|
visible: {
|
|
opacity: 1,
|
|
transition: {
|
|
delay: third,
|
|
duration: third * 2,
|
|
},
|
|
},
|
|
};
|
|
|
|
const sizeMultiplier = (options.size || 1) * 4;
|
|
|
|
return (
|
|
<div
|
|
className='lower-third lines'
|
|
style={{
|
|
backgroundColor: options.keyColour || defaults.keyColour,
|
|
color: options.textColour || defaults.textColour,
|
|
fontSize: `${sizeMultiplier}vh`,
|
|
}}
|
|
>
|
|
|
|
<NavigationMenu />
|
|
|
|
<AnimatePresence>
|
|
{showLower && (
|
|
<motion.div
|
|
className='lower-container'
|
|
style={{ backgroundColor: options.bgColour || defaults.bgColour }}
|
|
variants={lowerThirdVariants}
|
|
initial='hidden'
|
|
animate='visible'
|
|
exit='exit'
|
|
>
|
|
<motion.div
|
|
className='title-container'
|
|
variants={titleContainerVariants}
|
|
>
|
|
<motion.div className='title' variants={titleVariants}>
|
|
{title.titleNow}
|
|
</motion.div>
|
|
<div className='title-decor' />
|
|
</motion.div>
|
|
<motion.div
|
|
className='subtitle-container'
|
|
variants={subtitleContainerVariants}
|
|
>
|
|
<div className='sub-decor' />
|
|
<motion.div
|
|
className='subtitle'
|
|
variants={subtitleVariants}
|
|
>
|
|
{title.presenterNow}
|
|
</motion.div>
|
|
</motion.div>
|
|
</motion.div>
|
|
)}
|
|
</AnimatePresence>
|
|
|
|
<AnimatePresence>
|
|
{showLowerMessage && (
|
|
<motion.div
|
|
className='message-container'
|
|
key='modal'
|
|
initial={{ opacity: 0 }}
|
|
animate={{ opacity: 1 }}
|
|
exit={{ scaleY: 0, opacity: 0 }}
|
|
transition={{ duration: 0.5 }}
|
|
>
|
|
<div className='message'>{lower.text}</div>
|
|
</motion.div>
|
|
)}
|
|
</AnimatePresence>
|
|
</div>
|
|
);
|
|
}
|