LOGO+MENU SLIDEIN AND SLIDEOUT
by davidxmartins
HTML
<body class="body">
<header class="header">
<!-- replace content -->
<div class="header__logo js-replace">
<!-- item to replace -->
<div class="js-replace__item js-replace__item--active">
<div class="js-replace__content">
<div class="logo">
<div class="object-left slide"></div>
<div class="object-right slide"></div>
</div>
</div>
</div>
<!-- end item to replace -->
<!-- item to replace with -->
<div class="js-replace__item">
<div class="js-replace__content">
<div class="logo logo--invert">
<div class="object-left-b"></div>
<div class="object-right-b"></div>
</div>
</div>
</div>
<!-- end item to replace with -->
</div>
<!-- end replace content -->
</header>
<main class="main">
<section class="section--1 section"></section>
<section class="section--2 section section--bg1"></section>
<section class="section--3 section"></section>
<section class="section--4 section section--bg2"></section>
<section class="section--5 section"></section>
<section class="section--4 section section--bg3"></section>
<section class="section--5 section"></section>
</main>
</body>
CSS
/* variables */
:root {
/* this value is going to be changed by javascript */
--replace-offset: 50%;
--replace-offset-2: calc((100% - var(--replace-offset)) * -1)
}
/* set image position */
img {
vertical-align: bottom;
}
/* Sticky Footer */
.body {
min-height: 100vh;
margin: 0;
}
/* without fixed header this makes no sense */
.header {
position: fixed;
width: 100%;
height: 105px;
overflow: hidden;
}
.logo {
display: inline-block;
}
.object-left {
width: 100px;
height: 100px;
border-radius: 50px;
background-color: green;
}
.object-left-b {
width: 100px;
height: 100px;
border-radius: 50px;
background-color: white;
}
.object-right {
width: 100px;
height: 100px;
border-radius: 50px;
background-color: green;
position: absolute;
right: 30px;
top: 0;
}
.object-right-b {
width: 100px;
height: 100px;
border-radius: 50px;
background-color: white;
position: absolute;
right: 30px;
top: 0;
}
.object-left, .object-left-b {
opacity: 0;
transform: translateX(-150px);
transition: opacity 2s, transform 2s;
}
.object-right, .object-right-b {
opacity: 0;
transform: translateX(150px);
transition: opacity 2s, transform 2s;
}
.logo--invert {
background-color: transparent;
}
.section {
min-height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
}
.section--bg1 {
background-color: green;
}
.section--bg2 {
background-color: red;
}
.section--bg3 {
background-color: blue;
}
/**
This is the interesting part
**/
/* align content above each other without absolute */
.js-replace {
display: grid;
}
.js-replace__item {
grid-row: -1 / 1;
grid-column: -1 / 1;
overflow: hidden;
will-change: transform;
}
/* item to replace with */
.js-replace__item {
transform: translateY(calc(var(--replace-offset) * 1));
}
.js-replace__content {
/* fixes problem with calculating correct height in js */
border: 1px solid transparent;
...
JavaScript
var objectLeft = document.querySelector('.object-left');
var objectRight = document.querySelector('.object-right');
var objectLeftB = document.querySelector('.object-left-b');
var objectRightB = document.querySelector('.object-right-b');
function showObjects() {
if(window.scrollY > 800) {
objectLeft.style.opacity = '1';
objectLeft.style.transform = 'translateX(0px)';
objectRight.style.opacity = '1';
objectRight.style.transform = 'translateX(0px)';
objectLeftB.style.opacity = '1';
objectLeftB.style.transform = 'translateX(0px)';
objectRightB.style.opacity = '1';
objectRightB.style.transform = 'translateX(0px)';
} else {
objectLeft.style.opacity = '0';
objectLeft.style.transform = 'translateX(-150px)';
objectRight.style.opacity = '0';
objectRight.style.transform = 'translateX(150px)';
objectLeftB.style.opacity = '0';
objectLeftB.style.transform = 'translateX(-150px)';
objectRightB.style.opacity = '0';
objectRightB.style.transform = 'translateX(150px)';
}
}
window.addEventListener("scroll", showObjects);
// Detect request animation frame
var scroll = window.requestAnimationFrame
|| window.webkitRequestAnimationFrame
|| window.mozRequestAnimationFrame
|| window.msRequestAnimationFrame
|| window.oRequestAnimationFrame
// IE Fallback, you can even fallback to onscroll
|| function(callback){ window.setTimeout(callback, 1000/60) };
var lastPosition = -1;
// my Variables
var lastSection = false;
var replaceItemTop = -1;
var replaceItemBottom = -1;
var replaceItemHeight = -1;
// The Scroll Function
function loop(){
var top = window.pageYOffset;
// my variables
// my sections to calculate stuff
var sections = document.querySelectorAll('.section');
var replaceContainer = document.querySelectorAll('.js-replace');
var replaceItem = document.querySelectorAll('.js-replace__item');
if (replaceItem.length > 0) {
// get top position of item from container, because...