Skip to content

Instantly share code, notes, and snippets.

@vaniadimova
Created January 25, 2020 21:38
Show Gist options
  • Save vaniadimova/03163df262da7cb3d7ca66b313f74a10 to your computer and use it in GitHub Desktop.
Save vaniadimova/03163df262da7cb3d7ca66b313f74a10 to your computer and use it in GitHub Desktop.
Vanilla JS w/ CSS Transition
<div class="content-width">
<div class="slideshow">
<!-- Slideshow Items -->
<div class="slideshow-items">
<div class="item">
<div class="item-image-container">
<img class="item-image" src="https://images.unsplash.com/photo-1578822043018-0fd3a0293a5b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjE2ODQ0fQ&auto=format&fit=crop&w=500&q=60" />
</div>
<!-- Staggered Header Elements -->
<div class="item-header">
<span class="vertical-part"><b>D</b></span>
<span class="vertical-part"><b>o</b></span>
<span class="vertical-part"><b>U</b></span>
<span class="vertical-part"><b>?</b></span>
</div>
<!-- Staggered Description Elements -->
<div class="item-description">
<span class="vertical-part">
<b>I am</b>
</span>
<span class="vertical-part">
<b>the ocean.</b>
</span>
<span class="vertical-part">
<b>My tears</b>
</span>
<span class="vertical-part">
<b>are</b>
</span>
<span class="vertical-part">
<b>a strong</b>
</span>
<span class="vertical-part">
<b>current</b>
</span>
<span class="vertical-part">
<b>pulling</b>
</span>
<span class="vertical-part">
<b>me</b>
</span>
<span class="vertical-part">
<b>to</b>
</span>
<span class="vertical-part">
<b>you</b>
</span>
<span class="vertical-part">
<b>.......</b>
</span>
<span class="vertical-part">
<b>She</b>
</span>
<span class="vertical-part">
<b>said</b>
</span>
<span class="vertical-part">
<b>she was</b>
</span>
<span class="vertical-part">
<b>a hurricane,</b>
</span>
<span class="vertical-part">
<b>but</b>
</span>
<span class="vertical-part">
<b>oh</b>
</span>
<span class="vertical-part">
<b>how</b>
</span>
<span class="vertical-part">
<b>I</b>
</span>
<span class="vertical-part">
<b>LOVE</b>
</span>
<span class="vertical-part">
<b>the</b>
</span>
<span class="vertical-part">
<b>smell</b>
</span>
<span class="vertical-part">
<b>of</b>
</span>
<span class="vertical-part">
<b>the</b>
</span>
<span class="vertical-part">
<b>rain</b>
</span>
</div>
</div>
<div class="item">
<div class="item-image-container">
<img class="item-image" src="https://images.unsplash.com/photo-1578815722759-276152ed9afb?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjExMDk0fQ&auto=format&fit=crop&w=500&q=60" />
</div>
<!-- Staggered Header Elements -->
<div class="item-header">
<span class="vertical-part"><b>S</b></span>
<span class="vertical-part"><b>e</b></span>
<span class="vertical-part"><b>e</b></span>
<span class="vertical-part"><b>L</b></span>
<span class="vertical-part"><b>o</b></span>
<span class="vertical-part"><b>v</b></span>
<span class="vertical-part"><b>e</b></span>
</div>
<!-- Staggered Description Elements -->
<div class="item-description">
<span class="vertical-part">
<b>SeeLove</b>
</span>
<span class="vertical-part">
<b>If he</b>
</span>
<span class="vertical-part">
<b>trully</b>
</span>
<span class="vertical-part">
<b>loves you,</b>
</span>
<span class="vertical-part">
<b>he will</b>
</span>
<span class="vertical-part">
<b>love you</b>
</span>
<span class="vertical-part">
<b>when you</b>
</span>
<span class="vertical-part">
<b>are an</b>
</span>
<span class="vertical-part">
<b>ocean breeze,</b>
</span>
<span class="vertical-part">
<b>but also</b>
</span>
<span class="vertical-part">
<b>when you</b>
</span>
<span class="vertical-part">
<b>you are</b>
</span>
<span class="vertical-part">
<b>a</b>
</span>
<span class="vertical-part">
<b>summer</b>
</span>
<span class="vertical-part">
<b>storm.</b>
</span>
<span class="vertical-part">
<b>You are not</b>
</span>
<span class="vertical-part">
<b>made to be</b>
</span>
<span class="vertical-part">
<b>loved</b>
</span>
<span class="vertical-part">
<b>in parts,</b>
</span>
<span class="vertical-part">
<b>You were</b>
</span>
<span class="vertical-part">
<b>meant</b>
</span>
<span class="vertical-part">
<b>to be</b>
</span>
<span class="vertical-part">
<b>loved</b>
</span>
<span class="vertical-part">
<b>as a</b>
</span>
<span class="vertical-part">
<b>whole.</b>
</span>
</div>
</div>
<div class="item">
<div class="item-image-container">
<img class="item-image" src="https://images.unsplash.com/photo-1518568814500-bf0f8d125f46?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=60" />
</div>
<!-- Staggered Header Elements -->
<div class="item-header">
<span class="vertical-part"><b>B</b></span>
<span class="vertical-part"><b>e</b></span>
<span class="vertical-part"><b>l</b></span>
<span class="vertical-part"><b>i</b></span>
<span class="vertical-part"><b>e</b></span>
<span class="vertical-part"><b>v</b></span>
</div>
<!-- Staggered Description Elements -->
<div class="item-description">
<span class="vertical-part">
<b>Believe</b>
</span>
<span class="vertical-part">
<b>You are filled</b>
</span>
<span class="vertical-part">
<b>with doubt of the</b>
</span>
<span class="vertical-part">
<b>magic</b>
</span>
<span class="vertical-part">
<b>inside</b>
</span>
<span class="vertical-part">
<b>you</b>
</span>
<span class="vertical-part">
<b>but</b>
</span>
<span class="vertical-part">
<b>it is</b>
</span>
<span class="vertical-part">
<b>all I see.</b>
</span>
</div>
</div>
</div>
<div class="controls">
<ul>
<li class="control" data-index="0"></li>
<li class="control" data-index="1"></li>
<li class="control" data-index="2"></li>
</ul>
</div>
</div>
</div>
// Master DOManipulator v2 ------------------------------------------------------------
const items = document.querySelectorAll('.item'),
controls = document.querySelectorAll('.control'),
headerItems = document.querySelectorAll('.item-header'),
descriptionItems = document.querySelectorAll('.item-description'),
activeDelay = .76,
interval = 5000;
let current = 0;
const slider = {
init: () => {
controls.forEach(control => control.addEventListener('click', (e) => { slider.clickedControl(e) }));
controls[current].classList.add('active');
items[current].classList.add('active');
},
nextSlide: () => { // Increment current slide and add active class
slider.reset();
if (current === items.length - 1) current = -1; // Check if current slide is last in array
current++;
controls[current].classList.add('active');
items[current].classList.add('active');
slider.transitionDelay(headerItems);
slider.transitionDelay(descriptionItems);
},
clickedControl: (e) => { // Add active class to clicked control and corresponding slide
slider.reset();
clearInterval(intervalF);
const control = e.target,
dataIndex = Number(control.dataset.index);
control.classList.add('active');
items.forEach((item, index) => {
if (index === dataIndex) { // Add active class to corresponding slide
item.classList.add('active');
}
})
current = dataIndex; // Update current slide
slider.transitionDelay(headerItems);
slider.transitionDelay(descriptionItems);
intervalF = setInterval(slider.nextSlide, interval); // Fire that bad boi back up
},
reset: () => { // Remove active classes
items.forEach(item => item.classList.remove('active'));
controls.forEach(control => control.classList.remove('active'));
},
transitionDelay: (items) => { // Set incrementing css transition-delay for .item-header & .item-description, .vertical-part, b elements
let seconds;
items.forEach(item => {
const children = item.childNodes; // .vertical-part(s)
let count = 1,
delay;
item.classList.value === 'item-header' ? seconds = .015 : seconds = .007;
children.forEach(child => { // iterate through .vertical-part(s) and style b element
if (child.classList) {
item.parentNode.classList.contains('active') ? delay = count * seconds + activeDelay : delay = count * seconds;
child.firstElementChild.style.transitionDelay = `${delay}s`; // b element
count++;
}
})
})
},
}
let intervalF = setInterval(slider.nextSlide, interval);
slider.init();
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html, body {
width: 100%;
height: 100vh;
overflow: hidden;
background: #22222A;
font-family: 'Fira Mono', monospace;
-webkit-font-smoothing: antialiased;
font-size: .88rem;
color: #bdbdd5;
}
.content-width {
width: 86%;
height: 100vh;
margin: 0 auto;
}
.slideshow {
position: relative;
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
justify-content: space-around;
}
.slideshow-items {
position: relative;
width: 100%;
height: 300px;
}
.item {
position: absolute;
width: 100%;
height: auto;
}
.item-image-container {
position: relative;
width: 42%;
}
.item-image-container::before {
content: '';
position: absolute;
top: -1px;
left: 0;
width: 101%;
height: 101%;
background: #22222A;
opacity: 0;
z-index: 1;
}
.item-image {
position: relative;
width: 100%;
height: auto;
opacity: 0;
display: block;
/* transition: property name | duration | timing-function | delay */
transition: opacity .3s ease-out .45s;
}
.item.active .item-image {
opacity: 1;
}
.item.active .item-image-container::before {
opacity: .8;
}
.item-description {
position: absolute;
top: 182px;
right: 0;
width: 50%;
padding-right: 4%;
line-height: 1.8;
}
/* Staggered Vertical Items ------------------------------------------------------*/
.item-header {
position: absolute;
top: 150px;
left: -1.8%;
z-index: 100;
}
.item-header .vertical-part {
margin: 0 -4px;
font-family: 'Montserrat', sans-serif;
-webkit-font-smoothing: auto;
font-size: 7vw;
color: #fff;
}
.vertical-part {
overflow: hidden;
display: inline-block;
}
.vertical-part b {
display: inline-block;
transform: translateY(100%);
}
.item-header .vertical-part b {
transition: .5s;
}
.item-description .vertical-part b {
transition: .21s;
}
.item.active .item-header .vertical-part b {
transform: translateY(0);
}
.item.active .item-description .vertical-part b {
transform: translateY(0);
}
/* Controls ----------------------------------------------------------------------*/
.controls {
position: relative;
text-align: right;
z-index: 1000;
}
.controls ul {
list-style: none;
}
.controls ul li {
display: inline-block;
width: 10px;
height: 10px;
margin: 3px;
background:#bdbdd5;;
cursor: pointer;
}
.controls ul li.active {
background:#6a6a77;;
}
<link href="https://fonts.googleapis.com/css?family=Fira+Mono|Montserrat:800" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment