Объёмная галерея
Фото стоят по дуге с перспективой: центральное крупное и повёрнуто к зрителю, боковые уходят вглубь — эффектная витрина лучших работ.
Промпт
Вы можете скопировать промпт и вставить его в вайб блок в поле ввода. Подробнее в инструкции.
Сделай 3D-галерею, где фото стоят по дуге с перспективой.

Учитывай следующий контекст: это витрина [что показываем] для сайта [тип компании]. Используй прикреплённые фото — их [количество]. У каждого фото название и короткое описание: [названия и описания].

Галерея предназначена для [кто посетители], которые оценивают уровень работ по первому впечатлению.

Представь её так: в центре крупное фото, повёрнутое прямо к зрителю. По бокам — по два фото с каждой стороны: они меньше, повёрнуты внутрь и приглушены, словно уходят вглубь. При нажатии на боковое фото, стрелку или свайпе вся дуга плавно поворачивается, и выбранное фото выходит в центр. Под дугой — название и описание центрального фото, они меняются вместе с ним. Дуга замкнута: после последнего фото идёт первое. На телефоне видно центральное фото и края соседних, листается свайпом.

Соблюдай ограничения: шрифты и цвета из стилей проекта. Все фото одной пропорции, в пределах блока и не заходят за края экрана. Блок не создаёт горизонтальную прокрутку страницы. Описание занимает одинаковую высоту для всех фото, поэтому блок не прыгает при смене. Если в системе включено уменьшение движения, показывай обычный плоский слайдер без поворота.

Контент должен легко редактироваться в Тильде: все карточки, фото и тексты сразу в HTML, без генерации через JS, массивы, innerHTML или canvas. Фото — img с data-tilda-img="y", тексты — с data-tilda-edit="y". JS только для анимации и синхронизации декоративных фрагментов с главным img. В редакторе покажи главное фото и все обороты статично для выбора и замены контента; не перехватывай клики.

Хороший результат: ощущение объёма и глубины, поворот плавный и без проседаний, центральное фото всегда чёткое и главное.
Скопировать промпт
Код
Вы можете скопировать код и вставить его в вайб блок в раздел код. Подробнее в инструкции.
<section id="vb-r7m-gallery" class="vb-r7m-gallery" data-section-name="Галерея интерьеров" aria-labelledby="vb-r7m-gallery-title" data-vibeblock-unique-section="yes">
<style>
.vb-r7m-gallery,
.vb-r7m-gallery * { box-sizing: border-box; }
.vb-r7m-gallery input,
.vb-r7m-gallery textarea,
.vb-r7m-gallery select { font: inherit; }
.vb-r7m-gallery { --vb-r7m-ink: var(--t-text-color, #1b1b1b); --vb-r7m-muted: color-mix(in srgb, var(--vb-r7m-ink) 64%, transparent); --vb-r7m-line: color-mix(in srgb, var(--vb-r7m-ink) 18%, transparent); width: 100%; overflow: hidden; color: var(--vb-r7m-ink); font-family: var(--t-text-font); padding: clamp(52px, 7vw, 108px) 0 clamp(46px, 6vw, 86px); }
.vb-r7m-gallery__top { width: min(1180px, calc(100% - 40px)); margin: 0 auto clamp(28px, 4.4vw, 54px); display: flex; align-items: end; justify-content: space-between; gap: 24px; }
.vb-r7m-gallery__title { max-width: 720px; margin: 0; font-family: var(--t-headline-font); font-size: clamp(32px, 4.5vw, 62px); line-height: .98; letter-spacing: -.035em; font-weight: 500; text-wrap: balance; }
.vb-r7m-gallery__count { margin: 0 0 5px; color: var(--vb-r7m-muted); font-family: var(--t-text-font); font-size: 14px; line-height: 1.2; white-space: nowrap; }
.vb-r7m-gallery__stage { position: relative; width: 100%; height: clamp(245px, 42vw, 520px); overflow: hidden; perspective: 1400px; touch-action: pan-y; user-select: none; cursor: grab; }
.vb-r7m-gallery__stage:active { cursor: grabbing; }
.vb-r7m-gallery__rail { position: absolute; left: 50%; top: 0; width: min(62vw, 760px); height: 100%; transform-style: preserve-3d; }
.vb-r7m-gallery__item { position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: 0; padding: 0; background: transparent; appearance: none; cursor: pointer; transform-origin: 50% 50%; transition: transform 720ms cubic-bezier(.16,1,.3,1), opacity 620ms ease, filter 620ms ease; will-change: transform, opacity, filter; }
.vb-r7m-gallery__image { display: block; width: 100%; height: 100%; object-fit: cover; border-radius: 2px; box-shadow: 0 22px 45px color-mix(in srgb, var(--vb-r7m-ink) 20%, transparent); }
.vb-r7m-gallery__item:focus-visible { outline: 2px solid var(--vb-r7m-ink); outline-offset: 5px; }
.vb-r7m-gallery__bottom { width: min(940px, calc(100% - 40px)); margin: clamp(24px, 3.5vw, 42px) auto 0; display: grid; grid-template-columns: minmax(0,1fr) auto; gap: 20px 36px; align-items: end; }
.vb-r7m-gallery__copy { min-height: 94px; }
.vb-r7m-gallery__name { margin: 0 0 9px; font-family: var(--t-headline-font); font-size: clamp(21px, 2.35vw, 32px); line-height: 1.08; letter-spacing: -.025em; font-weight: 500; text-wrap: balance; }
.vb-r7m-gallery__description { max-width: 600px; min-height: 44px; margin: 0; color: var(--vb-r7m-muted); font-family: var(--t-text-font); font-size: clamp(14px, 1.2vw, 16px); line-height: 1.42; text-wrap: pretty; }
.vb-r7m-gallery__controls { display: flex; gap: 8px; padding-bottom: 2px; }
.vb-r7m-gallery__button.t-btnflex { width: 46px; height: 46px; min-width: 46px; border: 1px solid var(--vb-r7m-line); border-radius: 50%; background: transparent; color: var(--vb-r7m-ink); display: inline-flex; align-items: center; justify-content: center; padding: 0; transition: background-color 220ms ease, color 220ms ease, border-color 220ms ease; }
.vb-r7m-gallery__button.t-btnflex:hover { background: var(--vb-r7m-ink); color: var(--t-bg-color, #fff); border-color: var(--vb-r7m-ink); }
.vb-r7m-gallery__button.t-btnflex:focus-visible { outline: 2px solid var(--vb-r7m-ink); outline-offset: 3px; }
.vb-r7m-gallery__arrow { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.7; }
@media (max-width: 640px) {
.vb-r7m-gallery { padding-top: 48px; }
.vb-r7m-gallery__top { width: min(100% - 32px, 1180px); margin-bottom: 25px; }
.vb-r7m-gallery__count { display: none; }
.vb-r7m-gallery__stage { height: 68vw; min-height: 242px; max-height: 370px; }
.vb-r7m-gallery__rail { width: 80vw; max-width: 420px; }
.vb-r7m-gallery__bottom { width: min(100% - 32px, 940px); grid-template-columns: 1fr; gap: 18px; }
.vb-r7m-gallery__copy { min-height: 112px; }
.vb-r7m-gallery__description { min-height: 60px; }
.vb-r7m-gallery__controls { justify-content: flex-start; }
}
@media (prefers-reduced-motion: reduce) {
.vb-r7m-gallery__stage { perspective: none; }
.vb-r7m-gallery__item { transition: opacity 160ms linear; }
}
</style>
<div class="vb-r7m-gallery__top">
<h2 id="vb-r7m-gallery-title" class="vb-r7m-gallery__title">Реализованные интерьеры</h2>
<p class="vb-r7m-gallery__count" aria-live="polite"><span data-vb-r7m-current>01</span> / 08</p>
</div>
<div class="vb-r7m-gallery__stage" aria-label="Галерея реализованных интерьеров">
<div class="vb-r7m-gallery__rail" data-vb-r7m-rail></div>
</div>
<div class="vb-r7m-gallery__bottom">
<div class="vb-r7m-gallery__copy" aria-live="polite">
<h3 class="vb-r7m-gallery__name" data-vb-r7m-name></h3>
<p class="vb-r7m-gallery__description" data-vb-r7m-description></p>
</div>
<div class="vb-r7m-gallery__controls" aria-label="Управление галереей">
<button class="vb-r7m-gallery__button t-btnflex t-btnflex_md" type="button" data-vb-r7m-prev aria-label="Предыдущий интерьер"><span class="t-btnflex__icon"><svg class="vb-r7m-gallery__arrow" viewBox="0 0 24 24" aria-hidden="true"><path d="m14.5 5-7 7 7 7"/></svg></span><span class="t-btnflex__text" hidden>Назад</span></button>
<button class="vb-r7m-gallery__button t-btnflex t-btnflex_md" type="button" data-vb-r7m-next aria-label="Следующий интерьер"><span class="t-btnflex__icon"><svg class="vb-r7m-gallery__arrow" viewBox="0 0 24 24" aria-hidden="true"><path d="m9.5 5 7 7-7 7"/></svg></span><span class="t-btnflex__text" hidden>Вперёд</span></button>
</div>
</div>
<script>
(function () {
var root = document.getElementById('vb-r7m-gallery');
if (!root) return;
var projects = [
{ image: 'https://static.tildacdn.com/tild6430-3732-4033-b831-376164666433/photo-1721613883523-.jpg', title: 'Квартира на Патриарших', description: '120 м², скандинавский минимализм' },
{ image: 'https://static.tildacdn.com/tild6531-3934-4136-b666-383062633630/photo-1484154218962-.jpg', title: 'Квартира в Хамовниках', description: '98 м², светлая кухня-гостиная для семьи' },
{ image: 'https://static.tildacdn.com/tild3939-6437-4332-a137-323233333035/photo-1720420021124-.jpg', title: 'Пентхаус на Пресне', description: '156 м², мягкий минимализм и натуральное дерево' },
{ image: 'https://static.tildacdn.com/tild3738-3965-4365-b434-353433363737/photo-1763485955497-.jpg', title: 'Резиденция у парка', description: '134 м², тактильные фактуры и природный камень' },
{ image: 'https://static.tildacdn.com/tild3631-6166-4665-b433-653461313365/photo-1593136596203-.jpg', title: 'Квартира на Остоженке', description: '112 м², современная классика без лишнего декора' },
{ image: 'https://static.tildacdn.com/tild6133-3862-4133-b439-336234323764/photo-1595846723416-.jpg', title: 'Квартира на Саввинской', description: '86 м², продуманное пространство для работы и жизни' },
{ image: 'https://static.tildacdn.com/tild6133-3138-4262-a334-613766613939/photo-1613685301918-.jpg', title: 'Семейная квартира в Раменках', description: '142 м², спокойная палитра и сценарии для каждого' },
{ image: 'https://static.tildacdn.com/tild3530-3161-4637-b866-663133653234/photo-1781249144315-.jpg', title: 'Квартира в центре Москвы', description: '105 м², графичный интерьер с выразительной перспективой' }
];
var rail = root.querySelector('[data-vb-r7m-rail]');
var name = root.querySelector('[data-vb-r7m-name]');
var description = root.querySelector('[data-vb-r7m-description]');
var counter = root.querySelector('[data-vb-r7m-current]');
var stage = root.querySelector('.vb-r7m-gallery__stage');
var reduced = window.matchMedia('(prefers-reduced-motion: reduce)');
var active = 0;
var startX = null;
projects.forEach(function (project, index) {
var item = document.createElement('button');
var image = document.createElement('img');
item.type = 'button';
item.className = 'vb-r7m-gallery__item';
item.setAttribute('aria-label', 'Показать проект: ' + project.title);
image.className = 'vb-r7m-gallery__image';
image.src = project.image;
image.alt = project.title + ', ' + project.description;
image.loading = index < 3 ? 'eager' : 'lazy';
item.appendChild(image);
item.addEventListener('click', function () { setActive(index); });
rail.appendChild(item);
});
var items = Array.prototype.slice.call(rail.children);
function offsetFor(index) { var diff = index - active; if (diff > 4) diff -= projects.length; if (diff < -4) diff += projects.length; return diff; }
function setActive(index) {
active = (index + projects.length) % projects.length;
items.forEach(function (item, index) {
var offset = offsetFor(index);
var abs = Math.abs(offset);
if (reduced.matches) {
item.style.transform = 'translateX(-50%)';
item.style.opacity = offset === 0 ? '1' : '0';
item.style.filter = 'none';
item.style.pointerEvents = offset === 0 ? 'auto' : 'none';
item.style.zIndex = offset === 0 ? '2' : '1';
} else {
var translate = offset * 57;
var rotate = offset * -17;
var depth = -abs * 150;
var scale = 1 - abs * .105;
item.style.transform = 'translateX(calc(-50% + ' + translate + '%)) translateZ(' + depth + 'px) rotateY(' + rotate + 'deg) scale(' + Math.max(scale, .55) + ')';
item.style.opacity = abs > 2 ? '0' : String(1 - abs * .29);
item.style.filter = abs === 0 ? 'none' : 'saturate(.68) brightness(.76)';
item.style.pointerEvents = abs <= 2 ? 'auto' : 'none';
item.style.zIndex = String(10 - abs);
}
item.setAttribute('aria-current', offset === 0 ? 'true' : 'false');
});
name.textContent = projects[active].title;
description.textContent = projects[active].description;
counter.textContent = String(active + 1).padStart(2, '0');
}
root.querySelector('[data-vb-r7m-prev]').addEventListener('click', function () { setActive(active - 1); });
root.querySelector('[data-vb-r7m-next]').addEventListener('click', function () { setActive(active + 1); });
stage.addEventListener('pointerdown', function (event) { startX = event.clientX; });
stage.addEventListener('pointerup', function (event) { if (startX === null) return; var delta = event.clientX - startX; if (Math.abs(delta) > 38) setActive(active + (delta < 0 ? 1 : -1)); startX = null; });
stage.addEventListener('pointercancel', function () { startX = null; });
reduced.addEventListener('change', function () { setActive(active); });
setActive(0);
}());
</script>
</section>
Скопировать код
Что выбрать, промпт или код?
Копируйте промпт, если хотите получить похожий результат, но ввести информацию о своём бизнесе и задать свои требования. Например, изменить кнопки, тексты, цвета, фотографии или другие элементы.
Копируйте код, если хотите получить точно такой же блок. Чтобы его изменить, придётся отредактировать html-код.
Начните создание сайта на Тильде с простой регистрации на платформе
Made on
Tilda