<section class="mission-statement">
<p class="sub-title">The Animal mission</p>
<h1 class="title">A simple global currency and financial infrastructure that empowers billions of animals.</h1>
<p class="description">Reinvent money. Transform the global economy. So animals everywhere can live better lives.</p>
</section>
<section class="image-group">
<div class="overlapping-images">
<div class="image back-image">
<div class="image-wrapper"><img src="https://ucarecdn.com/1f711740-e8e6-44ca-a8f2-c62e8726e7b3/rayhennessy544349unsplash.jpg" /></div>
</div>
<div class="image front-image">
<div class="image-wrapper"><img src="https://ucarecdn.com/42134fe4-b2a7-49a4-a3d1-5c10b75c19d7/wolf.jpeg" /></div>
</div>
</div>
</section>
* {
margin: 0;
padding: 0;
}
@import url('https://fonts.googleapis.com/css?family=Work+Sans:300,400&display=swap');
.mission-statement {
margin: 100px 0;
padding: 0 30px;
@media screen and (min-width: 768px) {
padding: 0 90px;
}
.sub-title {
font-family: 'Work Sans', sans-serif;
font-size: 18px;
font-weight: 300;
opacity: 0;
transition: opacity .83s cubic-bezier(.17,.17,.05,1);
}
.title {
font-family: 'Work Sans', sans-serif;
font-size: 46px;
letter-spacing: 1px;
color: #706aaf;
margin-top: 24px;
line-height: 1.25;
opacity: 0;
transform: translateY(20px);
transition: opacity .83s cubic-bezier(.17,.17,.05,1),transform .83s cubic-bezier(.17,.17,.05,1),-webkit-transform .83s cubic-bezier(.17,.17,.05,1);
transition-delay: .13s;
@media screen and (min-width: 1024px) {
font-size: 62px;
letter-spacing: - .5px;
}
}
.description {
max-width: 336px;
font-family: 'Work Sans', sans-serif;
font-size: 18px;
font-weight: 300;
margin-top: 24px;
line-height: 1.56;
opacity: 0;
transition: opacity .83s cubic-bezier(.17,.17,.05,1);
transition-delay: .26s;
@media screen and (min-width: 1024px) {
font-size: 22px;
letter-spacing: -.5px;
}
}
}
.mission-statement.visible {
.sub-title {
opacity: 1;
}
.title {
opacity: 1;
transform: translateY(0);
}
.description {
opacity: 1;
}
}
.image-group {
margin: 100px 0;
margin-bottom: 100vh;
padding: 0 30px;
@media screen and (min-width: 768px) {
padding: 0 90px;
}
}
.overlapping-images {
padding-top: 91.746%;
position: relative;
@media screen and (min-width: 768px) {
padding-top: 46.03%;
}
}
.image {
width: 78.73%;
overflow: hidden;
position: absolute;
@media screen and (min-width: 768px) {
width: 50%;
}
img {
width: 100%;
display: block;
}
&.back-image {
left: 0;
bottom: 0;
transform: translate(0, -17.5%);
}
&.front-image {
right: 0;
top: 0;
transform: translate(0, 20%);
@media screen and (min-width: 768px) {
width: 57.14%;
}
}
}
.image-wrapper {
transform: scale(1.2);
}
View Compiled
const frontImage = document.querySelector('.front-image .image-wrapper');
const backImage = document.querySelector('.back-image .image-wrapper');
const frontImageContainer = document.querySelector('.front-image');
const backImageContainer = document.querySelector('.back-image');
const overlappingImages = document.querySelector('.overlapping-images');
const missionStatement = document.querySelector('.mission-statement');
let frontImagePosition = 0;
let backImagePosition = 0;
let currentFrontImagePosition = 0;
let currentBackImagePosition = 0;
let currentFrontImageContainerPosition = 20;
let currentBackImageContainerPosition = -17.5;
let isSeeFrontAndBackImage = false;
const createScaleY = (x1, y1, x2, y2) => {
const slope = (y2 - y1) / (x2 - x1);
return (y3) => {
if (slope === 0) {
return null;
}
return ((y3 - y1) / slope) + x1;
}
}
const getSlideImagePosition = (element) => {
const imageWrapperBounding = element.getBoundingClientRect();
const imageWrapperHeight = imageWrapperBounding.bottom - imageWrapperBounding.top;
const scaleY = createScaleY(-10, imageWrapperHeight * -1, 10, window.innerHeight);
const imagePosition = scaleY(imageWrapperBounding.top);
return imagePosition;
};
const updateImagePosition = (element, position) => {
if (typeof position === 'number') {
element.style.transform = `translate(0px, ${position}%) scale(1.2)`;
}
}
const updateImageWrapperPositionBaseOnScroll = () => {
frontImagePosition = getSlideImagePosition(frontImage);
backImagePosition = getSlideImagePosition(backImage);
}
const playFrontAndBackImageContainer = () => {
currentFrontImageContainerPosition += (0 - currentFrontImageContainerPosition) * 0.05;
if (currentFrontImageContainerPosition > 0.005) {
frontImageContainer.style.transform = `translate(0, ${currentFrontImageContainerPosition}%)`;
}
currentBackImageContainerPosition += (0 - currentBackImageContainerPosition) * 0.05;
if (currentBackImageContainerPosition < -0.005) {
backImageContainer.style.transform = `translate(0, ${currentBackImageContainerPosition}%)`;
}
requestAnimationFrame(playFrontAndBackImageContainer);
};
const playOverlappingImagesWhenSee = () => {
const overlappingImagesBounding = overlappingImages.getBoundingClientRect();
console.log('overlappingImagesBounding', overlappingImagesBounding.top)
if (overlappingImagesBounding.top <= window.innerHeight - 80) {
playFrontAndBackImageContainer();
isSeeFrontAndBackImage = true;
}
};
const playMissionStatementWhenSee = () => {
if (!missionStatement.classList.contains('visible') && missionStatement.getBoundingClientRect().top <= window.innerHeight - 20) {
missionStatement.classList.add('visible');
}
}
window.addEventListener('scroll', () => {
requestAnimationFrame(() => {
updateImageWrapperPositionBaseOnScroll();
if (!isSeeFrontAndBackImage) {
playOverlappingImagesWhenSee();
}
playMissionStatementWhenSee();
});
});
playMissionStatementWhenSee();
const loop = () => {
currentFrontImagePosition += (frontImagePosition - currentFrontImagePosition) * 0.1;
currentBackImagePosition += (backImagePosition - currentBackImagePosition) * 0.1;
updateImagePosition(frontImage, currentFrontImagePosition);
updateImagePosition(backImage, currentBackImagePosition * -1);
requestAnimationFrame(loop)
}
playOverlappingImagesWhenSee();
loop();
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.