:root {
--card-width: 200px;
--card-height: 300px;
--card-transition-duration: 800ms;
--card-transition-easing: ease;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
margin: 0;
margin-top: 40px;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
background: black;
background-size: cover;
}
.grid-container {
position: relative;
z-index: 1;
display: grid;
grid-template-columns: repeat(16, 80px);
grid-template-rows: repeat(7, 80px);
gap: 7px;
}
.grid-item {
width: 100%;
height: 100%;
border: 1px solid #111;
}
button {
border: none;
background: none;
cursor: pointer;
}
button:focus {
outline: none;
border: none;
}
.app {
position: relative;
z-index: 100;
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.cardList {
position: absolute;
z-index: 100;
width: calc(3 * var(--card-width));
height: auto;
}
.cardList__btn {
--btn-size: 35px;
width: var(--btn-size);
height: var(--btn-size);
position: absolute;
top: 50%;
transform: translateY(-50%);
z-index: 100;
}
.cardList__btn.btn--left {
left: -5%;
}
.cardList__btn.btn--right {
right: -5%;
}
.cardList__btn .icon {
width: 100%;
height: 100%;
}
.cardList__btn .icon svg {
width: 100%;
height: 100%;
}
.cardList .cards__wrapper {
position: relative;
width: 100%;
height: 100%;
perspective: 1000px;
}
.card {
--card-translateY-offset: 100vh;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%) translateX(var(--card-translateX-offset)) translateY(var(--card-translateY-offset)) rotateY(var(--card-rotation-offset)) scale(var(--card-scale-offset));
width: var(--card-width);
height: var(--card-height);
transition: transform var(--card-transition-duration) var(--card-transition-easing);
user-select: none;
}
.card::before {
content: "";
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: #000;
z-index: 1;
transition: opacity var(--card-transition-duration) var(--card-transition-easing);
opacity: calc(1 - var(--opacity));
}
.card__image {
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
background: #0077ff;
box-shadow: 1px 1px 80px 4px inset black;
}
.card__image img {
left: 0;
top: 0;
width: 300px;
object-fit: cover;
}
.card.current--card {
--current-card-rotation-offset: 0;
--card-translateX-offset: 0;
--card-rotation-offset: var(--current-card-rotation-offset);
--card-scale-offset: 1.2;
--opacity: 0.8;
}
.card.previous--card {
--card-translateX-offset: calc(-1 * var(--card-width) * 1.1);
--card-rotation-offset: 25deg;
}
.card.next--card {
--card-translateX-offset: calc(var(--card-width) * 1.1);
--card-rotation-offset: -25deg;
}
.card.previous--card, .card.next--card {
--card-scale-offset: 0.9;
--opacity: 0.4;
}
.infoList {
position: absolute;
z-index: 100;
top: 180px;
left: -400px;
right: 0;
bottom: 0;
width: calc(3 * var(--card-width));
height: var(--card-height);
pointer-events: none;
}
.infoList .info__wrapper {
position: relative;
width: 100%;
height: 100%;
display: flex;
justify-content: flex-start;
align-items: flex-end;
perspective: 1000px;
transform-style: preserve-3d;
}
.info {
margin-bottom: calc(var(--card-height) / 8);
margin-left: calc(var(--card-width) / 1.5);
transform: translateZ(2rem);
transition: transform var(--card-transition-duration) var(--card-transition-easing);
}
.info .text {
position: relative;
font-family: "Montserrat";
font-size: calc(var(--card-width) * var(--text-size-offset, 0.2));
white-space: nowrap;
color: #fff;
width: fit-content;
}
.info .name {
text-transform: uppercase;
}
.info .description {
--text-size-offset: 0.065;
font-weight: 500;
}
.info.current--info {
opacity: 1;
}
.info.previous--info, .info.next--info {
opacity: 0;
display: none;
}
.loading__wrapper {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background: #000;
z-index: 200;
}
.loading__wrapper .loader--text {
color: #fff;
font-family: "Montserrat";
font-weight: 500;
margin-bottom: 1.4rem;
}
.loading__wrapper .loader {
position: relative;
width: 200px;
height: 2px;
background: rgba(255, 255, 255, 0.25);
}
.loading__wrapper .loader span {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: red;
transform: scaleX(0);
transform-origin: left;
}
@media only screen and (min-width: 800px) {
:root {
--card-width: 300px;
--card-height: 450px;
}
}
Tetris-toys
Toy
Lorem ipsum dolor сидеть amet consectetur.
Toy
Lorem ipsum dolor сидеть amet consectetur.
Toy
Lorem ipsum dolor сидеть amet consectetur.
Toy
Lorem ipsum dolor сидеть amet consectetur.
Toy
Lorem ipsum dolor сидеть amet consectetur.
Toy
Lorem ipsum dolor сидеть amet consectetur.
Toy
Lorem ipsum dolor сидеть amet consectetur.
Please Wait...
Ապահովում է սլայդների անիմացիան։
// console.clear();
const { gsap, imagesLoaded } = window;
const buttons = {
prev: document.querySelector(".btn--left"),
next: document.querySelector(".btn--right"),
};
const cardsContainerEl = document.querySelector(".cards__wrapper");
// const appBgContainerEl = document.querySelector(".app__bg");
const cardInfosContainerEl = document.querySelector(".info__wrapper");
var slideIndex = 1;
showSlides();
function showSlides() {
var i;
var slides = document.getElementsByClassName("card");
var totalSlides = slides.length;
for (i = 0; i < totalSlides; i++) {
Array.from(slides).forEach(function(cardElement) {
cardElement.classList.remove('current--card', 'next--card', 'previous--card'); });
slides[i].style.display = "none";
}
var prevIndex = (slideIndex - 1 + totalSlides) % totalSlides;
var nextIndex = (slideIndex + 1) % totalSlides;
slides[prevIndex].style.display = "flex";
slides[slideIndex].style.display = "flex";
slides[nextIndex].style.display = "flex";
slides[slideIndex].style.zIndex = "50";
slides[prevIndex].style.zIndex = "20";
slides[nextIndex].style.zIndex = "30";
slides[prevIndex].classList.add("previous--card");
slides[slideIndex].classList.add("current--card");
slides[nextIndex].classList.add("next--card");
}
function changeSlide(n) {
slideIndex = (slideIndex + n + document.getElementsByClassName("card").length) % document.getElementsByClassName("card").length;
showSlides();
}
var slideIndex_info = 1;
showSlides_info();
function showSlides_info() {
var i;
var slides_info = document.getElementsByClassName("info");
var totalSlides = slides_info.length;
for (i = 0; i < totalSlides; i++) {
Array.from(slides_info).forEach(function(cardElement) {
cardElement.classList.remove('current--info', 'next--info', 'previous--info'); });
slides_info[i].style.display = "none";
}
slides_info[slideIndex_info].style.display = "block";
var prevIndex = (slideIndex_info - 1 + totalSlides) % totalSlides;
var nextIndex = (slideIndex_info + 1) % totalSlides;
slides_info[prevIndex].classList.add("previous--info");
slides_info[slideIndex_info].classList.add("current--info");
slides_info[nextIndex].classList.add("next--info");
}
function changeSlide_info(n) {
slideIndex_info = (slideIndex_info + n + document.getElementsByClassName("info").length) % document.getElementsByClassName("info").length;
showSlides_info();
}
buttons.next.addEventListener("click", () => swapCards("right"));
buttons.prev.addEventListener("click", () => swapCards("left"));
function swapCards(direction) {
changeInfo(direction);
swapCardsClass();
removeCardEvents(currentCardEl);
function swapCardsClass() {
if (direction === "right") {
changeSlide(1);
} else if (direction === "left") {
changeSlide(-1);
}
}
}
function changeInfo(direction) {
let currentInfoEl = cardInfosContainerEl.querySelector(".current--info");
let previousInfoEl = cardInfosContainerEl.querySelector(".previous--info");
let nextInfoEl = cardInfosContainerEl.querySelector(".next--info");
gsap.timeline()
.to([buttons.prev, buttons.next], {
duration: 0.2,
opacity: 0.5,
pointerEvents: "none",
})
.to(
currentInfoEl.querySelectorAll(".text"),
{
duration: 0.4,
stagger: 0.1,
translateY: "-120px",
opacity: 0,
},
"-="
)
.call(() => {
swapInfosClass(direction);
})
.call(() => initCardEvents())
.fromTo(
direction === "right"
? nextInfoEl.querySelectorAll(".text")
: previousInfoEl.querySelectorAll(".text"),
{
opacity: 0,
translateY: "40px",
},
{
duration: 0.4,
stagger: 0.1,
translateY: "0px",
opacity: 1,
}
)
.to([buttons.prev, buttons.next], {
duration: 0.2,
opacity: 1,
pointerEvents: "all",
});
function swapInfosClass() {
if (direction === "right") {
changeSlide_info(1);
} else if (direction === "left") {
changeSlide_info(-1);
}
}
}
function updateCard(e) {
const card = e.currentTarget;
const box = card.getBoundingClientRect();
const centerPosition = {
x: box.left + box.width / 2,
y: box.top + box.height / 2,
};
let angle = Math.atan2(e.pageX - centerPosition.x, 0) * (35 / Math.PI);
gsap.set(card, {
"--current-card-rotation-offset": `${angle}deg`,
});
const currentInfoEl = cardInfosContainerEl.querySelector(".current--info");
gsap.set(currentInfoEl, {
rotateY: `${angle}deg`,
});
}
function resetCardTransforms(e) {
const card = e.currentTarget;
const currentInfoEl = cardInfosContainerEl.querySelector(".current--info");
gsap.set(card, {
"--current-card-rotation-offset": 0,
});
gsap.set(currentInfoEl, {
rotateY: 0,
});
}
function initCardEvents() {
const currentCardEl = cardsContainerEl.querySelector(".current--card");
currentCardEl.addEventListener("pointermove", updateCard);
currentCardEl.addEventListener("pointerout", (e) => {
resetCardTransforms(e);
});
}
initCardEvents();
function removeCardEvents(card) {
card.removeEventListener("pointermove", updateCard);
}
function init() {
let tl = gsap.timeline();
tl.to(cardsContainerEl.children, {
delay: 0.15,
duration: 0.5,
stagger: {
ease: "power4.inOut",
from: "right",
amount: 0.1,
},
"--card-translateY-offset": "0%",
})
.to(cardInfosContainerEl.querySelector(".current--info").querySelectorAll(".text"), {
delay: 0.5,
duration: 0.4,
stagger: 0.1,
opacity: 1,
translateY: 0,
})
.to(
[buttons.prev, buttons.next],
{
duration: 0.4,
opacity: 1,
pointerEvents: "all",
},
"-=0.4"
);
}
const waitForImages = () => {
const images = [...document.querySelectorAll("img")];
const totalImages = images.length;
let loadedImages = 0;
const loaderEl = document.querySelector(".loader span");
gsap.set(cardsContainerEl.children, {
"--card-translateY-offset": "100vh",
});
gsap.set(cardInfosContainerEl.querySelector(".current--info").querySelectorAll(".text"), {
translateY: "40px",
opacity: 0,
});
gsap.set([buttons.prev, buttons.next], {
pointerEvents: "none",
opacity: "0",
});
images.forEach((image) => {
imagesLoaded(image, (instance) => {
if (instance.isComplete) {
loadedImages++;
let loadProgress = loadedImages / totalImages;
gsap.to(loaderEl, {
duration: 1,
scaleX: loadProgress,
backgroundColor: `hsl(${loadProgress * 120}, 100%, 50%`,
});
if (totalImages == loadedImages) {
gsap.timeline()
.to(".loading__wrapper", {
duration: 0.8,
opacity: 0,
pointerEvents: "none",
})
.call(() => init());
}
}
});
});
};
waitForImages();
Ապահովում է grid կոնտեյները՝ ֆիգուրների հետևի ֆոնը։
document.addEventListener('DOMContentLoaded', function () {
const gridContainer = document.getElementById('gridContainer');
for (let i = 0; i < 16 * 7; i++) {
const gridItem = document.createElement('div');
gridItem.classList.add('grid-item');
gridItem.style.background = getRandomGradient();
gridContainer.appendChild(gridItem);
}
function getRandomGradient() {
const hue = Math.floor(Math.random() * 360);
const startColor = `hsla(${hue}, 40%, 28%, 0.5)`;
return `linear-gradient(32deg, ${startColor} 5%, transparent 70%)`;
}
});
Ապահովում է ֆիգուրների անիմացիան։
const gridContainer = document.getElementById('grid');
const tetrisPieces = [
[
[1, 1, 1, 1],
],
[
[1, 1, 1],
[1],
],
[
[1, 1],
[1, 1],
],
[
[1, 1, 1],
[0, 1, 0],
],
[
[1, 1, 1],
[0, 0, 1],
],
[
[1, 1],
[0, 1],
[0, 1],
],
[
[1],
[1],
[1],
[1],
],
[
[1, 1, 0],
[0, 1, 1],
],
[
[0, 1, 1],
[1, 1, 0],
],
];
function addTetrisPiece() {
const randomPiece = tetrisPieces[Math.floor(Math.random() * tetrisPieces.length)];
const pieceColor = getRandomColor();
const randomRow = Math.floor(Math.random() * (8 - randomPiece.length));
const randomCol = Math.floor(Math.random() * (17 - randomPiece[0].length));
for (let i = 0; i < randomPiece.length; i++) {
for (let j = 0; j < randomPiece[i].length; j++) {
if (randomPiece[i][j] === 1) {
const cell = document.createElement('div');
var circleDiv = document.createElement('div');
circleDiv.style.width = "67%";
circleDiv.style.height = "67%";
circleDiv.style.backgroundColor = "rgba(255, 255, 255, 0.200)";
circleDiv.style.borderRadius = "50%";
circleDiv.style.boxShadow = '1px 1px 100px 1px black';
cell.style.display = 'flex';
cell.style.justifyContent = 'center';
cell.style.alignItems = 'center';
cell.appendChild(circleDiv);
cell.classList.add('grid-item');
cell.style.background = pieceColor;
cell.style.boxShadow = '2px 2px 2px 2px inset #ffffff80'
gridContainer.appendChild(cell);
cell.style.gridRow = randomRow + i + 1;
cell.style.gridColumn = randomCol + j + 1;
}
}
}
setTimeout(() => {
addTetrisPiece();
}, 800);
}
function getRandomColor() {
const hue = Math.floor(Math.random() * 360);
const startColor = `hsla(${hue}, 100%, 20%, 1)`;
return startColor;
}
addTetrisPiece();
function deleteContent() {
var parentDiv = document.getElementById('grid');
parentDiv.innerHTML = '';
}
setInterval(deleteContent, 60000);