# full-screen-youtube-video
This component adds an easy way to load Youtube videos throughout your application, inside a full screen modal.
This module is a work in progress. This module can work with GIFs, but is inteneded for mp4s.
To do:- destroy and load mp4 on each button press
# Example
<template>
<div>
<FullScreenYoutubeVideo
class="gtm-visibility"
v-if="fullScreenYoutubeVideo.active"
@close="fullScreenYoutubeVideo.active = false"
:videoId="fullScreenYoutubeVideo.videoId"
:ready="ready"
:ended="ended"
:paused="paused"
:playing="playing"
:buffering="buffering"
:qued="qued"
/>
<button
class="gtm-click-link play-button"
@click="fullScreenYoutubeVideo.active = true"
>
Click Me!
</button>
</div>
</template>
<script>
import { FullScreenYoutubeVideo } from '@rescue/vue-modules';
export default {
components: {
FullScreenYoutubeVideo,
},
data() {
return {
loader: true,
fullScreenYoutubeVideo: {
active: false,
videoId: 'sVGn26bo9y4',
},
};
},
methods: {
ready() {
this.loader = false;
console.log('ready');
},
ended() {
console.log('ended');
},
playing() {
console.log('playing');
},
paused() {
console.log('paused');
},
buffering() {
console.log('buffering');
},
qued() {
console.log('qued');
},
},
};
</script>
# Demo
# Installation
Install @rescue/vue-modules and vue-youtube-embed.
npm install @rescue/vue-modules vue-youtube-embed
You also need node-sass and sass-loader (If you don't have them already).
npm install node-sass sass-loader
# Usage
First import the component inside your script tags:
import { FullScreenYoutubeVideo } from '@rescue/vue-modules';
Then, register the component:
export default {
components: {
FullScreenYoutubeVideo,
},
};
Create the following object inside your data object:
export default {
components: {
FullScreenYoutubeVideo,
},
data() {
return {
fullScreenYoutubeVideo: {
active: false,
videoId: '',
},
};
},
};
Now add your component inside your template markup as such:
<template>
<FullScreenYoutubeVideo
v-if="fullScreenYoutubeVideo.active"
@close="fullScreenYoutubeVideo.active = false"
:video-id="fullScreenYoutubeVideo.videoId"
/>
</template>
To toggle a video, you need to set a youtube video ID, and a button to activate it, as such:
<template>
<FullScreenYoutubeVideo
v-if="fullScreenYoutubeVideo.active"
@close="fullScreenYoutubeVideo.active = false"
:video-id="fullScreenYoutubeVideo.videoId"
/>
<button @click="fullScreenYoutubeVideo.active = true">
Click Me!
</button>
</template>
<script>
export default {
components: {
FullScreenYoutubeVideo,
},
data() {
return {
fullScreenYoutubeVideo: {
active: false,
videoId: 'sVGn26bo9y4',
},
};
},
};
</script>
# props
videoId (Optional) (String) Youtube video ID.
ready (Optional) (Function) When video is ready.
ended (Optional) (Function) When video has ended.
playing (Optional) (Function) When video is playing.
paused (Optional) (Function) When video is paused.
buffering (Optional) (Function) When video is buffering.
qued (Optional) (Function) When video is qued.
loader (Optional) (Boolean) Set spinner loader to true or false.
# Source Code
<template>
<div @click="$emit('close')" class="full-screen-youtube-video">
<button @click="$emit('close')" class="close-btn gtm-click-link">
<span></span>
<span></span>
</button>
<component
v-if="vidReady"
:is="youtubeEmbed"
@click.stop
@ready="ready"
:video-id="videoId"
@ended="ended"
@playing="playing"
@paused="paused"
@buffering="buffering"
@qued="qued"
:player-vars="{ autoplay: 1 }"
></component>
<div @click.stop :class="{ active: loader }" class="loader">
<svg
class="spinner"
width="65px"
height="65px"
viewBox="0 0 66 66"
xmlns="http://www.w3.org/2000/svg"
>
<circle
class="path"
fill="none"
stroke-width="6"
stroke-linecap="round"
cx="33"
cy="33"
r="30"
/>
</svg>
</div>
</div>
</template>
<script>
import Vue from 'vue';
export default {
props: [
'videoId',
'ready',
'ended',
'playing',
'paused',
'buffering',
'qued',
'loader',
],
data() {
return {
youtubeEmbed: null,
vidReady: false,
};
},
mounted() {
import('vue-youtube-embed').then((module) => {
module.default.install(Vue);
this.youtubeEmbed = module.YouTubePlayer;
this.vidReady = true;
});
},
};
</script>
<style lang="scss">
$offset: 187;
$duration: 1.4s;
.full-screen-youtube-video {
width: 100vw;
height: 100vh;
background: rgba(0, 0, 0, 1);
position: fixed;
top: 0px;
left: 0px;
z-index: 50;
opacity: 0;
animation: opacity-in 0.25s linear;
animation-fill-mode: forwards;
@media (min-width: 767px) {
background: rgba(0, 0, 0, 0.75);
}
.close-btn {
position: absolute;
right: 25px;
top: 25px;
border: 1px solid white;
width: 50px;
height: 50px;
border-radius: 25px;
cursor: pointer;
z-index: 10;
background: rgba(0, 0, 0, 0.4);
box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.5);
transition: 0.25s transform ease-in-out,
0.25s background-color ease-in-out;
&:hover,
&:active {
transform: scale(1.05);
background-color: rgba(0, 0, 0, 0.4);
}
span {
width: 30px;
display: block;
height: 1px;
background: white;
margin-left: 2px;
&:nth-child(1) {
transform: rotate(45deg);
}
&:nth-child(2) {
transform: rotate(-45deg);
}
}
i {
font-size: 1.5em;
color: white;
}
}
iframe {
position: absolute;
left: 50%;
width: 100%;
height: 70%;
transform: translate(-50%, -50%);
top: 50%;
box-shadow: 0px 4px 20px rgba(0, 0, 0, 0.4);
@media (min-width: 767px) {
width: 90%;
}
}
.loader {
position: absolute;
left: 50%;
width: 100%;
height: 70%;
transform: translate(-50%, -50%);
top: 50%;
background: transparent;
opacity: 0;
pointer-events: none;
transition: 0.25s opacity ease-in-out;
transform-origin: 50% 50%;
display: flex;
justify-content: center;
align-items: center;
@media (min-width: 767px) {
background: rgb(50, 50, 50);
width: 90%;
}
&.active {
opacity: 1;
pointer-events: all;
}
.spinner {
animation: rotator $duration linear infinite;
}
.path {
stroke-dasharray: $offset;
stroke-dashoffset: 0;
transform-origin: center;
animation: dash $duration ease-in-out infinite,
colors ($duration * 4) ease-in-out infinite;
}
}
}
@keyframes opacity-in {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@keyframes rotator {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(270deg);
}
}
@keyframes colors {
0% {
stroke: #4285f4;
}
25% {
stroke: #de3e35;
}
50% {
stroke: #f7c223;
}
75% {
stroke: #1b9a59;
}
100% {
stroke: #4285f4;
}
}
@keyframes dash {
0% {
stroke-dashoffset: $offset;
}
50% {
stroke-dashoffset: $offset/4;
transform: rotate(135deg);
}
100% {
stroke-dashoffset: $offset;
transform: rotate(450deg);
}
}
</style>