feat: lower third

This commit is contained in:
cv
2021-04-20 23:50:49 +02:00
parent 2f205bcb55
commit 4e36e58a21
8 changed files with 313 additions and 8 deletions
+3 -1
View File
@@ -4,6 +4,8 @@
}
.App {
background: linear-gradient(90deg, #202020 0%, #121212 100%);
margin: 0px auto;
overflow: hidden;
background-color: rgba(0, 0, 0, 0);
height: 100vh;
}
+5 -4
View File
@@ -8,6 +8,7 @@ import SocketProvider from './app/context/socketContext';
import PresenterSimple from './features/viewers/presenter/PresenterSimple';
import StageManager from './features/viewers/backstage/StageManager';
import withSocket from './features/viewers/ViewWrapper';
import Lower from './features/viewers/lower/Lower';
const queryClient = new QueryClient();
@@ -15,20 +16,20 @@ const SDefault = withSocket(DefaultPresenter);
const SSpeaker = withSocket(PresenterView);
const SSpeakerSimple = withSocket(PresenterSimple);
const SStageManager = withSocket(StageManager);
const SLowerThird = withSocket(Lower);
function App() {
return (
<SocketProvider>
<QueryClientProvider client={queryClient}>
<div className='App'>
<Switch>
<div className='App'>
<Route exact path='/' component={SDefault} />
<Route exact path='/sm' component={SStageManager} />
<Route exact path='/speaker' component={SSpeaker} />
<Route exact path='/speakersimple' component={SSpeakerSimple} />
<Route exact path='/editor' component={Editor} />
</Switch>
</div>
<Route path='/lower' component={SLowerThird} />
</div>
</QueryClientProvider>
</SocketProvider>
);
@@ -1,5 +1,6 @@
.mainContainer {
width: 95%;
background: linear-gradient(90deg, #202020 0%, #121212 100%);
width: 100%;
margin: auto;
height: 95vh;
color: #fffd;
+144
View File
@@ -0,0 +1,144 @@
import { AnimatePresence, motion } from 'framer-motion';
import style from './Lower.module.css';
export default function Lower(props) {
const { pres, publ, lower, title, time, events, selectedId, general } = props;
// getting config from URL
// like http://localhost:3000/lower?bg=ff2&text=f00&size=0.6&transition=5
let params = new URLSearchParams(props.location.search);
const preset = params.get('preset') ? params.get('preset') : 1;
const size = params.get('size') ? params.get('size') : 1;
const transitionIn = params.get('transition') ? params.get('transition') : 3;
const textColour = params.get('bg') ? `#${params.get('text')}` : '#fffffa';
const bgColour = params.get('bg') ? `#${params.get('bg')}` : '#00000033';
const key = params.get('key') ? `#${params.get('key')}` : 'null';
// Format messages
const showLower = lower.text !== '' && lower.visible;
// transition segments
const eight = transitionIn / 8;
const quarter = transitionIn / 4;
const third = transitionIn / 3;
const half = transitionIn / 2;
// motion
const lowerThirdVariants = {
hidden: {
opacity: 0,
},
visible: {
opacity: 1,
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,
},
},
};
return (
<div
className={style.lowerThird}
style={{
backgroundColor: key,
color: textColour,
fontSize: `${size * 4}vh`,
}}
>
<motion.div
className={style.lowerContainer}
style={{ backgroundColor: bgColour }}
variants={lowerThirdVariants}
initial='hidden'
animate='visible'
exit={{ opacity: 0 }}
>
<motion.div
className={style.titleContainer}
variants={titleContainerVariants}
>
<motion.div className={style.title} variants={titleVariants}>
{title.titleNow}
</motion.div>
<div className={style.titleDecor} />
</motion.div>
<motion.div
className={style.subtitleContainer}
variants={subtitleContainerVariants}
>
<div className={style.subDecor} />
<motion.div className={style.subtitle} variants={subtitleVariants}>
{title.presenterNow}
</motion.div>
</motion.div>
</motion.div>
<AnimatePresence>
{showLower && (
<motion.div
className={style.messageContainer}
key='modal'
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ scaleY: 0 }}
transition={{ duration: 0.5 }}
>
<div className={style.message}>{lower.text}</div>
</motion.div>
)}
</AnimatePresence>
</div>
);
}
@@ -0,0 +1,89 @@
.lowerThird {
color: #fffffa;
font-size: 4vh;
width: 100%;
height: 100%;
}
.lowerContainer {
position: absolute;
top: 70vh;
background-color: #00000033;
padding: 1vw 1vw 1vw 0;
display: flex;
flex-direction: column;
width: 45vw;
gap: 3vh;
border-radius: 0 1vh 1vh 0;
}
.messageContainer,
.messageContainerHidden {
position: absolute;
bottom: 2vh;
width: 100%;
text-align: center;
filter: blur(0);
}
.titleContainer,
.subtitleContainer {
display: grid;
grid-template-columns: auto max-content;
grid-template-areas: 'decor text';
align-items: center;
position: relative;
}
.titleDecor,
.subDecor {
grid-area: decor;
height: 4vh;
background-color: #ff6969;
background: linear-gradient(
90deg,
rgba(255, 105, 105, 1) 0%,
rgba(255, 132, 132, 1) 100%
);
}
.titleDecor,
.subDecor {
width: 100%;
}
.title,
.subtitle {
grid-area: text;
padding-left: 1vw;
justify-self: right;
width: fit-content;
}
.title {
}
.subtitleContainer {
}
.subtitle {
}
.messageContainer {
background-color: #00000033;
opacity: 1;
transition: 0.5s;
transition-property: opacity;
}
.messageContainerHidden {
background-color: #00000033;
opacity: 0;
transition: 0.5s;
transition-property: opacity;
}
.message {
font-size: 3.5vh;
}
@@ -86,7 +86,7 @@
font-size: 18vw;
line-height: 18vw;
font-weight: 600;
color: #ff5353;
color: #ff6969;
padding: 0;
}
@@ -97,7 +97,7 @@
}
.container__grayFinished {
border: 1vw solid #ff5353;
border: 1vw solid #ff6969;
}
/* =================== OVERLAY ===================*/