Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save iamchristough/df9d1a38206cc7e1608cc7b01c8ca229 to your computer and use it in GitHub Desktop.
Save iamchristough/df9d1a38206cc7e1608cc7b01c8ca229 to your computer and use it in GitHub Desktop.
Hero Video Shape Timeline Tween
<div id="video-background-container">
<div id="hero-phone-element">
<video playsinline autoplay muted loop poster="placeholder.jpg" id="bgvideo" width="x" height="y">
<source src="https://pbj.live/static/hero-desktop-67879e6b407911a4a9382f39e2ff7ff9.mp4" type="video/mp4">
</video>
</div>
</div>
<div id="hero">
<div class="header-container">
<h1>Your Classes</h1>
</div>
</div>
<section class="section fake-hero"></section>
<section class="section is-empty"></section>
<section class="section is-default">
<div class="section-container">
<h2>An App<br /> built for Live</h2>
<p>Livestream from literally <b>anywhere</b> using one easy-to-use app.</p>
</div>
</section>
<section class="section">
<div class="section-container">
<h2>An End-to-End streaming solution</h2>
<p>Stream to your <b>website</b> or app, then manage your video library with the easiest-to-use video CMS in the business<b>—all using our SDK.</b></p>
</div>
</section>
<section class="section three">
<div class="section-container">
<h2>An App<br /> built for Live</h2>
<p>We built the easiest way to simulcast your content<b>—to any platform.</b></p>
</div>
</section>
<section class="section four">
<div class="section-container">
<h2>Copy about CMS</h2>
<p>Livestream from literally <b>anywhere</b> using one easy-to-use app.</p>
</div>
</section>
<section class="section five">
<div id="section-five-trigger" class="section-container">
<h2>Customized<br/> to your Brand</h2>
<p>Our white-label service allows you to monetize your content any way you choose, and customize a web and app experience specifically to your brand and style.</p>
<p><b>You just focus on the content.</b></p>
</div>
</section>
<section class="section last full-width">
<div class="section-container">
<h4>No Hidden Fees</h4>
<p>Our white-label service allows you to monetize your content any way you choose, and customize a web and app experience specifically to your brand and style.</p>
<p><b>You just focus on the content.</b></p>
</div>
</section>
(function (window) {
console.clear();
const myApp = () => {
init();
}
const init = () => {
// Create a timeline with default parameters
var controller = new ScrollMagic.Controller();
const heroContainer = document.querySelector('.header-container');
const heroPhone = document.querySelector('#hero-phone-element');
const heroHeight = document.querySelector('#hero').offsetHeight;
const section = document.querySelector('.section.is-default');
const sectionHeight = section.offsetHeight;
const sectionWidth = section.offsetWidth;
const duration = (sectionHeight * 2 - (sectionHeight / 6));
const phoneWidth = 304;
const phoneHeight = 607;
const phoneSize = {
width: `${phoneWidth}px`,
height: `${phoneHeight}px`
}
const xPos = (window.innerWidth / 2) + ((window.innerWidth / 4) - (phoneWidth / 2));
const yPos = (window.innerHeight / 2) - (phoneHeight / 2);
const phoneStart = {
scale: 1.3,
transformOrigin: 'center',
}
const phoneMiddle = {
scale: 1,
width: window.innerWidth / 2.25,
height: '110%',
x: window.innerWidth / 2.25,
transformOrigin: 'center'
}
const phoneEnd = {
...phoneSize,
scale: 1,
x: xPos,
y: yPos,
transformOrigin: 'center'
}
const phoneIntroTimeline = new TimelineMax();
phoneIntroTimeline
.from(heroPhone, 1, phoneStart, 0)
.to(heroPhone, 1, phoneMiddle, 0)
.to(heroPhone, 1, phoneEnd, 1)
const phoneIntroScene = new ScrollMagic.Scene({
triggerElement: ".fake-hero",
triggerHook: 0,
duration: duration
})
.addIndicators()
.setTween(phoneIntroTimeline);
const heroTimeline = new TimelineMax();
heroTimeline
.from(heroContainer, 1, { opacity: 1 })
.to(heroContainer, 1, { opacity: 0 }, 1)
const heroScene = new ScrollMagic.Scene({
triggerElement: ".fake-hero",
triggerHook: 0,
duration: heroHeight
})
.addIndicators()
.setTween(heroTimeline);
const exitSectionContainer = document.querySelector('#section-five-trigger');
const exitSection = document.querySelector('.section.five');
const lastSection = document.querySelector('.section.last');
const exitDuraction = window.innerHeight + (sectionHeight - (exitSection.offsetHeight / 2));
const exitPos = {
y: -(window.innerHeight),
ease: Linear.easeNone,
transformOrigin: 'center'
}
const customiseTimeline = new TimelineMax();
customiseTimeline
.to(heroPhone, 1, { y: yPos })
.to(heroPhone, 120, exitPos)
const customiseExitScene = new ScrollMagic.Scene({
triggerElement: lastSection,
triggerHook: 1,
duration: sectionHeight
})
.addIndicators()
.setTween(customiseTimeline);
controller.addScene([
heroScene,
phoneIntroScene,
// parallaxScene,
// cmsIntroScene,
// cmsExitScene,
customiseExitScene,
]);
phoneIntroScene.on("progress", function (event) {
console.log("Scene progress: " + event.progress);
});
}
myApp();
})(window, undefined);
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.1/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.7/ScrollMagic.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.5/plugins/animation.gsap.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.5/plugins/debug.addIndicators.min.js"></script>
body {
margin: 0;
background: white;
font-family: sans-serif;
}
#video-background-container {
height: 100vh;
width: 100%;
position: fixed;
}
#hero-phone-element {
position: relative;
width: 100%;
height: 100%;
border-radius: 30px;
overflow: hidden;
}
video#bgvideo {
position: relative;
width: 100%;
height: 100%;
z-index: -100;
object-fit: cover;
object-position: center;
max-height: 100vh;
max-width: 100%;
}
#hero {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.header-container {
position: relative;
color: white;
font-size: 100px;
}
}
.section {
height: 100vh;
width: 100%;
max-width: 1440px;
margin: 0 auto;
display: flex;
padding: 100px;
box-sizing: border-box;
flex-direction: column;
justify-content: center;
position: relative;
z-index: 1;
&.fake-hero,
&.full-width {
max-width: 100%;
}
&.full-width {
height: auto;
}
&.three {
padding: 50vh 100px;
height: 300vh;
// justify-content: flex-end;
display: block;
}
&.last {
padding-top: 50vh;
padding-bottom: 300vh;
}
}
.section-container {
width: 50%;
max-width: 600px;
h2 {
margin: 0 0 30px;
font-weight: 500;
font-size: 70px;
line-height: 110%;
}
p {
margin-top: 0;
font-weight: 300;
font-size: 24px;
line-height: 140%;
max-width: 520px;
}
.three & {
position: sticky;
top: 40%;
left: 0;
}
.full-width & {
max-width: 1276px;
width: 100%;
text-align: center;
margin: 0 auto;
p {
max-width: 100%;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment