Skip to content

Instantly share code, notes, and snippets.

@Danushka181
Created February 24, 2023 19:37
Show Gist options
  • Save Danushka181/83641e409380074c62f12318048a6f4b to your computer and use it in GitHub Desktop.
Save Danushka181/83641e409380074c62f12318048a6f4b to your computer and use it in GitHub Desktop.
overlap cards expanding on scroll
// getting all the cards
const allCards = document.querySelectorAll(".cards-scroll .card");
let containerHeight = document.querySelector(".card-row").getBoundingClientRect().top + window.pageYOffset;
const headerHeight = 70;
const baseWidth = 60;
const cardsClickHandler = (e, index) => {
let topScrollValue = 0;
let headersHeight = 0;
let lastMargin = 0;
allCards.forEach((element, i) => {
if (i <= index) {
const styles = window.getComputedStyle(element);
const marginBottom = parseInt(styles.marginBottom);
const marginTop = parseInt(styles.marginTop);
headersHeight = headerHeight * i === 0 ? headerHeight * -1 : headerHeight * i;
topScrollValue += element.clientHeight - marginBottom + headersHeight;
lastMargin = marginTop;
}
});
let finalOffset = 0;
if (index === allCards.length - 1) {
const allHeadersHeight = headerHeight * index;
lastMargin = allHeadersHeight + lastMargin + 10;
finalOffset = topScrollValue + containerHeight - lastMargin;
} else {
finalOffset = topScrollValue + containerHeight - 10;
}
const duration = 800;
const startingY = window.pageYOffset;
const diff = finalOffset - startingY;
let start;
const easeInOutQuad = (t) => {
return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
};
const step = (timestamp) => {
if (!start) start = timestamp;
const time = timestamp - start;
const percent = easeInOutQuad(Math.min(time / duration, 1)); // apply easing function
window.scrollTo(0, startingY + diff * percent);
if (time < duration) {
window.requestAnimationFrame(step);
}
};
window.requestAnimationFrame(step);
};
if (allCards.length) {
allCards.forEach((card, i) => {
const incValue = i * headerHeight;
const decValue = (allCards.length - i - 1) * headerHeight;
const widthValue = (allCards.length - i) * baseWidth;
const heightValue = allCards.length * headerHeight - headerHeight;
let bottomValue = self.innerHeight - headerHeight * (allCards.length - i) - incValue;
bottomValue = bottomValue - headerHeight * (allCards.length - i) + 1;
bottomValue = bottomValue + headerHeight;
const fontSize = 20 + 4 * i;
card.style.fontSize = `${fontSize}px`;
// we can optimize like this for
card.style.marginTop = `${incValue}px`;
card.style.marginBottom = `${decValue}px`;
card.style.top = `${incValue}px`;
card.style.bottom = `-${bottomValue}px`;
card.style.maxWidth = `calc(100% - ${widthValue}px)`;
card.style.maxHeight = `calc(100vh - ${heightValue - 3}px)`;
card.addEventListener("click", (e) => {
cardsClickHandler(e, i);
});
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment