console
class CardAnimation {
options = {
visible: 3,
infinite: true,
};
constructor({ containner, options }) {
this.containner = containner;
this.options = Object.assign({}, this.options);
Object.assign(this.options, options);
this.items = [].slice.call(this.containner.children);
this.itemsTotal = this.items.length;
if (
(this.options.infinite && this.options.visible >= this.itemsTotal) ||
(!this.options.infinite && this.options.visible > this.itemsTotal) ||
this.options.visible <= 0
) {
this.options.visible = 1;
}
this.current = 0;
this.isAnimating = false;
this._init();
}
_init() {
for (let i = 0; i < this.items.length; i++) {
const element = this.items[i];
if (i < this.options.visible) {
element.style.transform = `rotateZ(${i * 5}deg)`;
element.style.zIndex = i === 0 ? i + 1 : i - 1;
element.style.opacity = 1;
} else {
element.style.transform = `rotateZ(${this.options.visible * 5}deg)`;
}
}
this.addClass(this.items[this.current], "current-card");
this.containner.onclick = this.clickHandler.bind(this);
}
addClass(node, className) {
node.classList.add(className);
}
removeClass(node, className) {
node.classList.remove(className);
}
clickHandler(event) {
if (this.isAnimating) return;
this.isAnimating = true;
const currentItem = this.items[this.current];
this.removeClass(currentItem, "current-card");
this.addClass(currentItem, "card-out");
const dealTransitionEnd = () => {
currentItem.style.opacity = 0;
currentItem.style.zIndex = -1;
currentItem.style.WebkitTransform =
currentItem.style.transform = `rotateZ( ${parseInt(
this.options.visible * 5
)}deg)`;
this.removeClass(currentItem, "card-out");
this.isAnimating = false;
};
for (let i = 0; i < this.items.length; i++) {
if (i >= this.options.visible) break;
const pos =
this.current + i < this.itemsTotal - 1
? this.current + i + 1
: i - (this.itemsTotal - this.current - 1);
const item = this.items[pos];
setTimeout(
((item, index) => () => {
item.style.pointerEvents = "auto";
item.style.opacity = 1;
item.style.zIndex = parseInt(this.options.visible - index);
item.style.transform = `rotateZ(${index * 5}deg)`;
})(item, i),
500 * i
);
}
currentItem.onanimationend = dealTransitionEnd.bind(this);
this.current = this.current < this.itemsTotal - 1 ? this.current + 1 : 0;
this.addClass(this.items[this.current], "current-card");
}
}
new CardAnimation({
containner: document.querySelector(".introCards"),
options: {
visible: 2,
infinite: true,
},
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="introCards">
<div class="introCard"></div>
<div class="introCard"></div>
<div class="introCard"></div>
<div class="introCard"></div>
</div>
</body>
<script src="script.js"></script>
</html>
html,
body {
height: 100%;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.introCards {
height: 600px;
width: 500px;
position: relative;
}
.introCard {
top: 30px;
height: 300px;
width: 400px;
position: absolute;
transform-origin: bottom right;
opacity: 0;
box-shadow: 4px 4px 20px 5px rgb(0 0 0 / 30%);
transition: all 0.5s ease-in-out;
border-radius: 10px;
}
.introCard:nth-child(1) {
background-color: #0984e3;
}
.introCard:nth-child(2) {
background-color: #6c5ce7;
}
.introCard:nth-child(3) {
background-color: #ff7675;
}
.introCard:nth-child(4) {
background-color: #ffeaa7;
}
@keyframes cardOutKf {
to {
opacity: 0;
-webkit-transform: rotateZ(90deg);
transform: rotateZ(-90deg);
}
}
.card-out {
-webkit-animation: cardOutKf 0.5s forwards;
animation: cardOutKf 0.5s forwards;
-webkit-transform-origin: right bottom;
transform-origin: right bottom;
}
.current-card {
cursor:pointer;
}