<body>
<div class="indicator"></div>
<div id="demo"></div>
<div class="details" id="details-even">
<div class="place-box">
<div class="text">О нас</div>
</div>
<div class="title-box-1"><div class="title-1">MOST BUSINESS</div></div>
<div class="title-box-2"><div class="title-2">INTELLIGENCE</div></div>
<div class="desc">
Первый бизнес-инкубатор в Центральной Азии, создающий экосистему для предпринимателей и инвесторов.
</div>
</div>
<div class="details" id="details-odd">
<div class="place-box">
<div class="text">О нас</div>
</div>
<div class="title-box-1"><div class="title-1">MOST BUSINESS </div></div>
<div class="title-box-2"><div class="title-2">INTELLIGENCE</div></div>
<div class="desc">
Первый бизнес-инкубатор в Центральной Азии, создающий экосистему для предпринимателей и инвесторов.
</div>
</div>
<div class="pagination" id="pagination">
<div class="arrow arrow-prev" id="prev">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-left" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M15 8a.5.5 0 0 0-.5-.5H2.707l3.147-3.146a.5.5 0 1 0-.708-.708l-4 4a.5.5 0 0 0 0 .708l4 4a.5.5 0 0 0 .708-.708L2.707 8.5H14.5A.5.5 0 0 0 15 8z"/>
</svg>
</div>
<div class="progress-sub-container">
<div class="progress-sub-background">
<div class="progress-sub-foreground"></div>
</div>
</div>
<div class="slide-numbers" id="slide-numbers"></div>
<div class="arrow arrow-next" id="next">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-right" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M1 8a.5.5 0 0 1 .5-.5h11.793l-3.147-3.146a.5.5 0 0 1 .708-.708l4 4a.5.5 0 0 1 0 .708l-4 4a.5.5 0 0 1-.708-.708L13.293 8.5H1.5A.5.5 0 0 1 1 8z"/>
</svg>
</div>
</div>
<div class="cover" ></div>
</body>
@import url('https://fonts.cdnfonts.com/css/gilroy-bold');
$primary-color: #CD0404;
$text-color: #FFFFFFDD;
body {
margin: 0;
background-color: #1a1a1a;
color: $text-color;
position: relative;
overflow: hidden;
font-family: 'Gilroy-Bold', sans-serif;
}
.card {
position: absolute;
left: 0;
top: 0;
background-position: center;
background-size: cover;
box-shadow: 6px 6px 10px 2px rgba(0, 0, 0, 0.6);
}
#btn {
position: absolute;
top: 690px;
left: 16px;
z-index: 99;
}
.card-content {
position: absolute;
left: 0;
top: 0;
color: $text-color;
padding-left: 16px;
}
.content-place {
margin-top: 6px;
font-size: 13px;
font-weight: 500;
}
.content-place {
font-weight: 500;
}
.content-title-1,
.content-title-2 {
font-weight: 600;
font-size: 20px;
font-family: 'Gilroy-Bold', sans-serif;
}
.content-start {
width: 30px;
height: 5px;
border-radius: 99px;
background-color: $text-color;
}
.details {
z-index: 22;
position: absolute;
top: 240px;
left: 60px;
.place-box {
height: 46px;
overflow: hidden;
.text {
padding-top: 16px;
font-size: 20px;
&:before {
top: 0;
left: 0;
position: absolute;
content: "";
width: 30px;
height: 4px;
border-radius: 99px;
background-color: white;
}
}
}
.title-1,
.title-2 {
font-weight: 600;
font-size: 72px;
font-family: 'Gilroy-Bold', sans-serif;
}
.title-box-1,
.title-box-2 {
margin-top: 2px;
height: 100px;
overflow: hidden;
// background-color: blue;
}
> .desc {
margin-top: 16px;
width: 500px;
}
> .cta {
width: 500px;
margin-top: 24px;
display: flex;
align-items: center;
> .bookmark {
border: none;
background-color: $primary-color;
width: 36px;
height: 36px;
border-radius: 99px;
color: white;
display: grid;
place-items: center;
svg {
width: 20px;
height: 20px;
}
}
> .discover {
border: 1px solid #ffffff;
background-color: transparent;
height: 36px;
border-radius: 99px;
color: #ffffff;
padding: 4px 24px;
font-size: 12px;
margin-left: 16px;
text-transform: uppercase;
}
}
}
nav {
position: fixed;
left: 0;
top: 0;
right: 0;
z-index: 50;
display: flex;
align-items: center;
justify-content: space-between;
padding: 20px 36px;
font-weight: 500;
svg {
width: 20px;
height: 20px;
}
.svg-container {
width: 20px;
height: 20px;
}
> div {
display: inline-flex;
align-items: center;
text-transform: uppercase;
font-size: 14px;
&:first-child {
gap: 10px;
}
&:last-child {
gap: 24px;
> .active {
position: relative;
&:after {
bottom: -8px;
left: 0;
right: 0;
position: absolute;
content: "";
height: 3px;
border-radius: 99px;
background-color: $primary-color;
}
}
}
}
}
.indicator {
position: fixed;
left: 0;
right: 0;
top: 0;
height: 5px;
z-index: 60;
background-color: $primary-color;
}
.pagination {
position: absolute;
left: 0px;
top: 0px;
display: inline-flex;
> .arrow {
z-index: 60;
width: 50px;
height: 50px;
border-radius: 999px;
border: 2px solid #ffffff55;
display: grid;
cursor: pointer;
place-items: center;
&:nth-child(2){
margin-left: 20px;
}
svg {
width: 24px;
height: 24px;
stroke-width: 2;
color: #ffffff99;
}
}
.progress-sub-container{
margin-left: 24px;
z-index: 60;
width: 500px;
height: 50px;
display: flex;
align-items: center;
.progress-sub-background{
width: 500px;
height: 3px;
background-color: #ffffff33;
.progress-sub-foreground{
height: 3px;
background-color: $primary-color;
}
}
}
.slide-numbers{
width: 50px;
height: 50px;
overflow: hidden;
// background-color: #111111;
z-index: 60;
position: relative;
.item{
width: 50px;
height: 50px;
position: absolute;
// background: rgb(31, 31, 41);
color: white;
top: 0;
left: 0;
display: grid;
place-items: center;
font-size: 32px;
font-weight: bold;
}
}
}
.cover{
position: absolute;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
background-color: #fff;
z-index: 100;
}
@media (max-width: 768px) {
.details,
.pagination,
nav {
left: 20px; /* Уменьшить отступ слева */
right: 20px; /* Добавить отступ справа для центрирования элементов */
}
.card-content {
padding-left: 20px; /* Уменьшить отступ слева для контента карточки */
}
.title-1,
.title-2 {
font-size: 36px; /* Уменьшить размер заголовков */
}
.desc {
width: auto; /* Позволить блоку описания занимать доступную ширину */
font-size: 14px; /* Уменьшить размер текста описания */
}
.pagination {
top: auto; /* Удалить абсолютное позиционирование сверху */
bottom: 20px; /* Переместить пагинацию вниз страницы */
width: calc(100% - 40px); /* Уменьшить ширину контейнера пагинации */
justify-content: center; /* Центрировать элементы пагинации */
}
.progress-sub-container {
width: 100%; /* Растянуть фон прогресса на всю доступную ширину */
}
.progress-sub-background,
.progress-sub-foreground {
width: 100%; /* Растянуть прогресс на всю ширину контейнера */
}
.arrow {
display: none; /* Скрыть стрелки навигации на мобильных устройствах */
}
.card {
width: 10px; /* Карточки теперь будут занимать всю ширину экрана */
right: 0; /* Добавить небольшой отступ сверху для каждой карточки */
}
.content-place,
.content-title-1,
.content-title-2 {
font-size: 16px; /* Уменьшить размер текста для мобильных */
}
.pagination {
bottom: 10px; /* Уменьшить отступ снизу для пагинации */
}
/* Поскольку карточки теперь будут иметь меньшую высоту, можно уменьшить размер шрифта описания и заголовков */
.desc {
font-size: 14px; /* Меньший размер шрифта для описания */
padding: 0 10px; /* Добавить небольшой отступ с каждой стороны для текста описания */
}
}
View Compiled
const data = [
{
place:'О нас',
title:'MOST BUSINESS',
title2:'INTELLIGENCE',
description:'Первый бизнес-инкубатор в Центральной Азии, создающий экосистему для предпринимателей и инвесторов.',
image:'https://media.mostbi.com/MOST%20Landing/Slider/mostbi.jpg'
},
{
place:'Scale Up',
title:'SELECT USA',
title2:'USA TOUR',
description:'ПРИГЛАШАЕМ ВАС ПРИНЯТЬ УЧАСТИЕ В ЕЖЕГОДНОЙ SCALE UP ПРОГРАММЕ В США вместе с MOST BI в июне 2024. Если вы интересуетесь инвестициями на международном уровне, хотите масштабировать бизнес в США и расширить свой глобальный нетворк, то этот тур для вас!',
image:'https://media.mostbi.com/MOST%20Landing/Slider/usa_tour.png'
},
{
place:'Акселерация',
title:'',
title2:'IRA',
description:'IRA (Investment Readiness Accelerator) – это программа акселерации от фонда MOST Ventures, направленная на упаковку стартапов к инвестициям.',
image:'https://media.mostbi.com/MOST%20Landing/Slider/ira.jpg'
},
{
place:'Акселерация',
title:'SMART CITY',
title2:'ACCELERATOR',
description:'Программа акселерации от MOST Business Intelligence, направленная на упаковку и внедрение продуктов в индустрию умного города.',
image:'https://media.mostbi.com/MOST%20Landing/Slider/innovate_for_impact.jpg'
},
]
const _ = (id)=>document.getElementById(id)
const cards = data.map((i, index)=>`<div class="card" id="card${index}" style="background-image:url(${i.image})" ></div>`).join('')
const cardContents = data.map((i, index)=>`<div class="card-content" id="card-content-${index}">
<div class="content-start"></div>
<div class="content-place">${i.place}</div>
<div class="content-title-1">${i.title}</div>
<div class="content-title-2">${i.title2}</div>
</div>`).join('')
const sildeNumbers = data.map((_, index)=>`<div class="item" id="slide-item-${index}" >${index+1}</div>`).join('')
_('demo').innerHTML = cards + cardContents
_('slide-numbers').innerHTML = sildeNumbers
const range = (n) =>
Array(n)
.fill(0)
.map((i, j) => i + j);
const set = gsap.set;
function getCard(index) {
return `#card${index}`;
}
function getCardContent(index) {
return `#card-content-${index}`;
}
function getSliderItem(index) {
return `#slide-item-${index}`;
}
function animate(target, duration, properties) {
return new Promise((resolve) => {
gsap.to(target, {
...properties,
duration: duration,
onComplete: resolve,
});
});
}
let order = [0, 1, 2, 3];
let detailsEven = true;
let offsetTop = 200;
let offsetLeft = 700;
let cardWidth = 200;
let cardHeight = 300;
let gap = 40;
let numberSize = 50;
const ease = "sine.inOut";
function init() {
const [active, ...rest] = order;
const detailsActive = detailsEven ? "#details-even" : "#details-odd";
const detailsInactive = detailsEven ? "#details-odd" : "#details-even";
const { innerHeight: height, innerWidth: width } = window;
offsetTop = height - 430;
offsetLeft = width - 830;
gsap.set("#pagination", {
top: offsetTop + 330,
left: offsetLeft,
y: 200,
opacity: 0,
zIndex: 60,
});
gsap.set("nav", { y: -200, opacity: 0 });
gsap.set(getCard(active), {
x: 0,
y: 0,
width: window.innerWidth,
height: window.innerHeight,
});
gsap.set(getCardContent(active), { x: 0, y: 0, opacity: 0 });
gsap.set(detailsActive, { opacity: 0, zIndex: 22, x: -200 });
gsap.set(detailsInactive, { opacity: 0, zIndex: 12 });
gsap.set(`${detailsInactive} .text`, { y: 100 });
gsap.set(`${detailsInactive} .title-1`, { y: 100 });
gsap.set(`${detailsInactive} .title-2`, { y: 100 });
gsap.set(`${detailsInactive} .desc`, { y: 50 });
gsap.set(`${detailsInactive} .cta`, { y: 60 });
gsap.set(".progress-sub-foreground", {
width: 500 * (1 / order.length) * (active + 1),
});
rest.forEach((i, index) => {
gsap.set(getCard(i), {
x: offsetLeft + 400 + index * (cardWidth + gap),
y: offsetTop,
width: cardWidth,
height: cardHeight,
zIndex: 30,
borderRadius: 10,
});
gsap.set(getCardContent(i), {
x: offsetLeft + 400 + index * (cardWidth + gap),
zIndex: 40,
y: offsetTop + cardHeight - 100,
});
gsap.set(getSliderItem(i), { x: (index + 1) * numberSize });
});
gsap.set(".indicator", { x: -window.innerWidth });
const startDelay = 0.6;
gsap.to(".cover", {
x: width + 400,
delay: 0.5,
ease,
onComplete: () => {
setTimeout(() => {
}, 500);
},
});
rest.forEach((i, index) => {
gsap.to(getCard(i), {
x: offsetLeft + index * (cardWidth + gap),
zIndex: 30,
delay: 0.05 * index,
ease,
delay: startDelay,
});
gsap.to(getCardContent(i), {
x: offsetLeft + index * (cardWidth + gap),
zIndex: 40,
delay: 0.05 * index,
ease,
delay: startDelay,
});
});
gsap.to("#pagination", { y: 0, opacity: 1, ease, delay: startDelay });
gsap.to("nav", { y: 0, opacity: 1, ease, delay: startDelay });
gsap.to(detailsActive, { opacity: 1, x: 0, ease, delay: startDelay });
}
let clicks = 0;
function step(direction = 1) { // Add a 'direction' parameter with default of 1
return new Promise((resolve) => {
detailsEven = !detailsEven;
if (direction === -1) { // Handle the 'prev' direction
order.unshift(order.pop()); // Shift the last element to the front
} else {
order.push(order.shift()); // Default forward behavior
}
detailsEven = !detailsEven;
const detailsActive = detailsEven ? "#details-even" : "#details-odd";
const detailsInactive = detailsEven ? "#details-odd" : "#details-even";
document.querySelector(`${detailsActive} .place-box .text`).textContent =
data[order[0]].place;
document.querySelector(`${detailsActive} .title-1`).textContent =
data[order[0]].title;
document.querySelector(`${detailsActive} .title-2`).textContent =
data[order[0]].title2;
document.querySelector(`${detailsActive} .desc`).textContent =
data[order[0]].description;
gsap.set(detailsActive, { zIndex: 22 });
gsap.to(detailsActive, { opacity: 1, delay: 0.4, ease });
gsap.to(`${detailsActive} .text`, {
y: 0,
delay: 0.1,
duration: 0.7,
ease,
});
gsap.to(`${detailsActive} .title-1`, {
y: 0,
delay: 0.15,
duration: 0.7,
ease,
});
gsap.to(`${detailsActive} .title-2`, {
y: 0,
delay: 0.15,
duration: 0.7,
ease,
});
gsap.to(`${detailsActive} .desc`, {
y: 0,
delay: 0.3,
duration: 0.4,
ease,
});
gsap.to(`${detailsActive} .cta`, {
y: 0,
delay: 0.35,
duration: 0.4,
onComplete: resolve,
ease,
});
gsap.set(detailsInactive, { zIndex: 12 });
const [active, ...rest] = order;
const prv = rest[rest.length - 1];
gsap.set(getCard(prv), { zIndex: 10 });
gsap.set(getCard(active), { zIndex: 20 });
gsap.to(getCard(prv), { scale: 1.5, ease });
gsap.to(getCardContent(active), {
y: offsetTop + cardHeight - 10,
opacity: 0,
duration: 0.3,
ease,
});
gsap.to(getSliderItem(active), { x: 0, ease });
gsap.to(getSliderItem(prv), { x: -numberSize, ease });
gsap.to(".progress-sub-foreground", {
width: 500 * (1 / order.length) * (active + 1),
ease,
});
gsap.to(getCard(active), {
x: 0,
y: 0,
ease,
width: window.innerWidth,
height: window.innerHeight,
borderRadius: 0,
onComplete: () => {
const xNew = offsetLeft + (rest.length - 1) * (cardWidth + gap);
gsap.set(getCard(prv), {
x: xNew,
y: offsetTop,
width: cardWidth,
height: cardHeight,
zIndex: 30,
borderRadius: 10,
scale: 1,
});
gsap.set(getCardContent(prv), {
x: xNew,
y: offsetTop + cardHeight - 100,
opacity: 1,
zIndex: 40,
});
gsap.set(getSliderItem(prv), { x: rest.length * numberSize });
gsap.set(detailsInactive, { opacity: 0 });
gsap.set(`${detailsInactive} .text`, { y: 100 });
gsap.set(`${detailsInactive} .title-1`, { y: 100 });
gsap.set(`${detailsInactive} .title-2`, { y: 100 });
gsap.set(`${detailsInactive} .desc`, { y: 50 });
gsap.set(`${detailsInactive} .cta`, { y: 60 });
clicks -= 1;
if (clicks > 0) {
step();
}
},
});
rest.forEach((i, index) => {
if (i !== prv) {
const xNew = offsetLeft + index * (cardWidth + gap);
gsap.set(getCard(i), { zIndex: 30 });
gsap.to(getCard(i), {
x: xNew,
y: offsetTop,
width: cardWidth,
height: cardHeight,
ease,
delay: 0.1 * (index + 1),
});
gsap.to(getCardContent(i), {
x: xNew,
y: offsetTop + cardHeight - 100,
opacity: 1,
zIndex: 40,
ease,
delay: 0.1 * (index + 1),
});
gsap.to(getSliderItem(i), { x: (index + 1) * numberSize, ease });
}
});
});
}
async function loop() {
await animate(".indicator", 2, { x: 0 });
await animate(".indicator", 0.8, { x: window.innerWidth, delay: 0.3 });
set(".indicator", { x: -window.innerWidth });
await step();
loop();
}
async function loadImage(src) {
return new Promise((resolve, reject) => {
let img = new Image();
img.onload = () => resolve(img);
img.onerror = reject;
img.src = src;
});
}
async function loadImages() {
const promises = data.map(({ image }) => loadImage(image));
return Promise.all(promises);
}
async function start() {
try {
await loadImages();
init();
} catch (error) {
console.error("One or more images failed to load", error);
}
}
_('prev').addEventListener('click', () => {
if (clicks === 0) {
clicks += 1;
step(-1); // Call 'step' with direction = -1 for backwards
}
});
_('next').addEventListener('click', () => {
if (clicks === 0) {
clicks += 1;
step(); // Call 'step' with default direction for forwards
}
});
start()
This Pen doesn't use any external CSS resources.