Код:
<!--HTML--> <script> // ДАННЫЕ О ДОМАХ // adress: "адрес дома", // type: "тип недвижимости (аренда/продажа/только аренда)", // price: "цена (может быть договорная или указана в формате $X/месяц или $X,XXX,XXX)", // gif: "ссылка на гифку", // description: "описание дома можно использовать <br/> для переноса строк", // amenities: ["список удобств", "в таком формате", "со всеми запятыми и кавычками"], // neighbors: ["список соседних домов", "в таком формате"], // apartments: [ // { number: "номер квартиры", status: "статус (free/occupied)", residents: "имена жильцов (если есть)" }, // { number: "квартира 2", status: "occupied", residents: "Ande Barckett & Lionell Stewens" } // ] // Чтобы вставить новый дом, просто поставьте запятую после последней } и перед закрывающей ] // скопируйте один из домов от { до }, вставьте после запятой и измените данные // Чтобы удалить дом удалить все его данные от { до } var housesData = [ { address: "изумрудная аллея, 256", type: "аренда/продажа", price: "договорная", gif: "https://upforme.ru/uploads/001c/85/fe/3/779670.gif", description: "трёхэтажный дом на несколько квартир в живописной тампе — редкая находка для ценителей жизни у океана. современное здание с просторными балконами и панорамными окнами открывает потрясающий вид на воду и закаты над заливом. каждая квартира продумана до мелочей: светлые интерьеры, функциональные планировки и стильная отделка.<br/>на территории — частная парковка, зелёная зона для отдыха и прямой выход к пляжу. идеальное место для жизни, отдыха или инвестиций в сердце флориды.", amenities: ["одна спальня", "одна ванная", "гостиная", "кухня", "кладовая", "без лифта"], neighbors: ["солнечная аллея, 12", "океанский бульвар, 89"], apartments: [ { number: "квартира 1", status: "free", residents: null }, { number: "квартира 2", status: "occupied", residents: "Ande Barckett & Lionell Stewens" }, { number: "квартира 3", status: "free", residents: null } ] }, { address: "солнечная аллея, 12", type: "только аренда", price: "$850/месяц", gif: "https://upforme.ru/uploads/001c/85/fe/3/944216.gif", description: "уютный двухэтажный коттедж в тихом районе тампы с собственным садом и террасой. дом полностью меблирован и готов к заселению. просторная гостиная с камином, современная кухня с островом и панорамными окнами, выходящими в сад. на втором этаже две спальни с собственными ванными комнатами. идеально подходит для семьи или пары, ценящей комфорт и уединение.", amenities: [ "две спальни", "две ванные", "гостиная с камином", "кухня с островом", "терраса", "сад", "парковка" ], neighbors: ["изумрудная аллея, 256", "цветочная улица, 45"], apartments: [{ number: "основной дом", status: "occupied", residents: "Sarah & Michael Thompson" }] }, { address: "океанский бульвар, 89", type: "продажа", price: "$1,200,000", gif: "https://upforme.ru/uploads/001c/85/fe/3/150907.gif", description: "роскошный пентхаус на последнем этаже с панорамным видом на океан. эксклюзивная недвижимость с собственным лифтом, просторными террасами и бассейном на крыше. интерьер выполнен в современном стиле с использованием натуральных материалов. три спальни, четыре ванные комнаты, кабинет, винная комната и гардеробная. консьерж-сервис и охрана 24/7.", amenities: [ "три спальни", "четыре ванные", "кабинет", "винная комната", "бассейн на крыше", "консьерж", "охрана 24/7" ], neighbors: ["изумрудная аллея, 256", "мраморная улица, 1"], apartments: [{ number: "пентхаус", status: "free", residents: null }] }, { address: "цветочная улица, 45", type: "аренда/продажа", price: "$650/месяц или $450,000", gif: "https://upforme.ru/uploads/001c/85/fe/3/139031.gif", description: "стильная студия в историческом центре города с высокими потолками и оригинальными кирпичными стенами. недавно отремонтированная квартира сочетает в себе винтажный шарм и современные удобства. большие окна обеспечивают отличное естественное освещение. в шаговой доступности кафе, галереи и бутики. идеально подходит для молодого профессионала или студента.", amenities: ["студия", "высокие потолки", "кирпичные стены", "винтажный стиль", "центр города"], neighbors: ["солнечная аллея, 12", "артистическая улица, 7"], apartments: [{ number: "студия", status: "free", residents: null }] } ]; // Чтобы вставить новый дом, просто поставьте запятую после последней } и перед закрывающей ] // скопируйте один из домов с { }, вставьте после запятой и измените данные // Чтобы удалить дом удалить все его данные от { до } </script> <style> .main-container { width: 940px; margin: 0 auto; padding: 15px; } .carousel-section { position: relative; } .carousel-header { background: rgb(255 255 255 / 35%); padding: 12px 10px 10px; margin-bottom: 15px; position: relative; text-align: center; } .carousel-header::before { content: "доступные дома"; position: absolute; top: -8px; left: 12px; background-color: var(--cl44); color: #fff; font-size: 10px; font-weight: bold; padding: 3px 7px 4px; border-radius: 8px; text-transform: lowercase; } .carousel-container { position: relative; overflow: hidden; background: rgb(255 255 255 / 35%); width: 940px; } .carousel-track { display: flex; transition: transform 0.4s ease; } .house-card { flex: 0 0 940px; width: 940px; padding: 20px; box-sizing: border-box; } .house-header { display: flex; justify-content: space-between; align-items: flex-end; margin-bottom: 15px; } .house-title { font-size: 13px !important; font-weight: 700; color: var(--cl4); background: transparent !important; text-transform: lowercase; margin: 0 !important; padding: 0 !important; } .house-type { font-size: 11px; color: var(--cl44); font-weight: 500; text-transform: uppercase; letter-spacing: 0.3px; } .house-price { background: var(--cl4); color: #fff; padding: 8px 12px; border-radius: 15px; font-weight: 600; font-size: 11px; display: flex; flex-direction: column; align-items: center; gap: 2px; text-align: center; min-width: 120px; } .house-price-amount { display: flex; align-items: center; gap: 4px; } .house-price-type { font-size: 9px; opacity: 0.8; text-transform: uppercase; letter-spacing: 0.3px; } .house-description { font-size: 12px; line-height: 1.5; color: #6f6f6f; margin-bottom: 15px; text-align: justify; } .house-media-content { display: flex; gap: 15px; margin-bottom: 15px; } .house-gif { width: 200px; height: 200px; border-radius: 6px; overflow: hidden; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); flex-shrink: 0; position: relative; } .house-gif::after { content: ""; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: #c0edff; mix-blend-mode: multiply; pointer-events: none; } .house-gif img { width: 100%; height: 100%; object-fit: cover; } .house-content { flex: 1; display: flex; flex-direction: column; } .house-details { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 15px; } .house-address { font-weight: 600; color: var(--cl4); margin-bottom: 6px; font-size: 13px; } .detail-section { background: rgba(255, 255, 255, 0.2); padding: 10px; border-left: 2px solid var(--cl4); } .detail-section.neighbors { border-left-color: var(--cl44); } .detail-title { font-weight: 600; color: var(--cl4); margin-bottom: 6px; font-size: 11px; text-transform: uppercase; letter-spacing: 0.3px; display: flex; align-items: center; gap: 4px; } .detail-title.neighbors-title { color: var(--cl44); } .detail-content { font-size: 11px; color: #6f6f6f; line-height: 1.3; } .amenities-list { display: flex; flex-wrap: wrap; gap: 4px; } .amenity-item { background: rgba(136, 163, 172, 0.1); color: var(--cl4); padding: 2px 6px; border-radius: 8px; font-size: 10px; font-weight: 500; } .neighbors-list { display: flex; flex-wrap: wrap; gap: 4px; } .neighbor-item { background: rgba(187, 171, 181, 0.1); color: var(--cl44); padding: 2px 6px; border-radius: 8px; font-size: 10px; font-weight: 500; } .apartments-section { background: rgba(255, 255, 255, 0.2); padding: 10px; border-left: 2px solid var(--cl4); } .apartments-title { font-weight: 600; color: var(--cl4); margin-bottom: 8px; font-size: 11px; text-transform: uppercase; letter-spacing: 0.3px; display: flex; align-items: center; gap: 4px; } .apartments-grid { display: flex; flex-direction: column; gap: 4px; } .apartment-item { background: rgba(255, 255, 255, 0.05); padding: 6px 8px; border-radius: 4px; display: flex; align-items: center; gap: 8px; transition: all 0.2s ease; } .apartment-item:hover { background: rgba(136, 163, 172, 0.1); transform: translateX(2px); } .apartment-number { font-weight: 600; color: var(--cl4); min-width: 60px; font-size: 10px; } .apartment-status { flex: 1; font-size: 10px; } .apartment-status.free { color: #49925f; font-style: italic; } .apartment-status.occupied { color: #6f6f6f; } .navigation { display: flex; justify-content: center; align-items: center; gap: 15px; margin-top: 15px; } .nav-btn { background: var(--cl4); color: #fff; border: none; width: 30px; height: 30px; border-radius: 50%; cursor: pointer; font-size: 14px; font-weight: bold; transition: all 0.2s ease; display: flex; align-items: center; justify-content: center; } .nav-btn:hover:not(:disabled) { background: var(--cl44); transform: scale(1.05); box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2); } .nav-btn:disabled { background: #ccc; cursor: not-allowed; opacity: 0.5; } .indicators { display: flex; gap: 6px; } .indicator { width: 8px; height: 8px; border-radius: 50%; background: rgba(136, 163, 172, 0.3); cursor: pointer; transition: all 0.2s ease; } .indicator.active { background: var(--cl4); transform: scale(1.2); } .indicator:hover { background: var(--cl44); } .counter { color: #6f6f6f; font-size: 11px; font-weight: 500; } /* Иконки */ .icon { width: 12px; height: 12px; display: inline-block; vertical-align: middle; } .icon-home::before { content: ""; display: inline-block; width: 12px; height: 12px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2388a3ac'%3E%3Cpath d='M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z'/%3E%3C/svg%3E"); background-size: contain; background-repeat: no-repeat; } .icon-neighbors::before { content: ""; display: inline-block; width: 12px; height: 12px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23bbabb5'%3E%3Cpath d='M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z'/%3E%3C/svg%3E"); background-size: contain; background-repeat: no-repeat; } .icon-apartments { margin-bottom: 1px; } .icon-apartments::before { content: ""; display: inline-block; width: 12px; height: 12px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2388a3ac'%3E%3Cpath d='M17 11V3H7v4H3v14h18V11h-4zM7 19H5v-2h2v2zm0-4H5v-2h2v2zm0-4H5V9h2v2zm4 8H9v-2h2v2zm0-4H9v-2h2v2zm0-4H9V9h2v2zm0-4H9V5h2v2zm4 12h-2v-2h2v2zm0-4h-2v-2h2v2zm0-4h-2V9h2v2zm0-4h-2V5h2v2zm4 8h-2v-2h2v2zm0-4h-2v-2h2v2z'/%3E%3C/svg%3E"); background-size: contain; background-repeat: no-repeat; } .icon-coin { margin-bottom: -2px; } .icon-coin::before { content: ""; display: inline-block; width: 12px; height: 12px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23ffffff'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm.31-8.86c-1.77-.45-2.34-.94-2.34-1.67 0-.84.79-1.43 2.1-1.43 1.38 0 1.9.66 1.94 1.64h1.71c-.05-1.34-.87-2.57-2.49-2.97V5H11.5v1.69c-1.51.32-2.72 1.3-2.72 2.81 0 1.79 1.49 2.69 3.66 3.21 1.95.46 2.34 1.15 2.34 1.87 0 .53-.39 1.39-2.1 1.39-1.6 0-2.23-.72-2.32-1.64H8.64c.1 1.7 1.36 2.66 2.86 2.97V19h1.71v-1.68c1.44-.32 2.55-1.35 2.55-2.88 0-2.22-1.78-2.91-3.45-3.3z'/%3E%3C/svg%3E"); background-size: contain; background-repeat: no-repeat; } .icon-amenities::before { content: ""; display: inline-block; width: 12px; height: 12px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2388a3ac'%3E%3Cpath d='M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z'/%3E%3C/svg%3E"); background-size: contain; background-repeat: no-repeat; } </style> <div class="main-container"> <!-- Секция с каруселью --> <div class="carousel-section"> <div class="carousel-header"> <p style="color: #6f6f6f; margin: 0">Описание темы</p> </div> <div class="carousel-container"> <div class="carousel-track" id="carouselTrack"> <!-- Карточки домов будут сгенерированы через JavaScript --> </div> </div> <div class="navigation"> <button class="nav-btn" id="prevBtn">‹</button> <div class="indicators" id="indicators"> <!-- Индикаторы будут сгенерированы через JavaScript --> </div> <button class="nav-btn" id="nextBtn">›</button> </div> <div style="text-align: center; margin-top: 10px"> <span class="counter" id="counter">1 / 1</span> </div> </div> </div> <script> let currentSlide = 0; function generateHouseCards() { const track = document.getElementById("carouselTrack"); track.innerHTML = ""; housesData.forEach((house, index) => { const card = document.createElement("div"); card.className = "house-card"; card.innerHTML = ` <div class="house-header"> <div> <p class="house-title">${house.address}</p> </div> <div class="house-price"> <div class="house-price-amount"> <span class="icon icon-coin"></span> ${house.price} </div> <div class="house-price-type">${house.type}</div> </div> </div> <div class="house-media-content"> <div class="house-gif"> <img src="${house.gif}" alt="${house.address}"> </div> <div class="house-content"> <div class="house-description"> ${house.description} </div> </div> </div> <div class="house-details"> <div class="detail-section"> <div class="detail-title"> <span class="icon icon-amenities"></span> удобства </div> <div class="detail-content"> <div class="amenities-list"> ${house.amenities.map((amenity) => `<span class="amenity-item">${amenity}</span>`).join("")} </div> </div> </div> <div class="detail-section neighbors"> <div class="detail-title neighbors-title"> <span class="icon icon-neighbors"></span> соседи </div> <div class="detail-content"> <div class="neighbors-list"> ${house.neighbors.map((neighbor) => `<span class="neighbor-item">${neighbor}</span>`).join("")} </div> </div> </div> </div> <div class="apartments-section"> <div class="apartments-title"> <span class="icon icon-apartments"></span> квартиры </div> <div class="apartments-grid"> ${house.apartments .map( (apt) => ` <div class="apartment-item"> <div class="apartment-number">♦ ${apt.number}</div> <div class="apartment-status ${apt.status}"> ${apt.status === "free" ? "свободно" : apt.residents} </div> </div> ` ) .join("")} </div> </div> `; track.appendChild(card); }); } function generateIndicators() { const indicatorsContainer = document.getElementById("indicators"); indicatorsContainer.innerHTML = ""; housesData.forEach((_, index) => { const indicator = document.createElement("div"); indicator.className = "indicator"; if (index === 0) indicator.classList.add("active"); indicator.addEventListener("click", () => goToSlide(index)); indicatorsContainer.appendChild(indicator); }); } function goToSlide(slideIndex) { const track = document.getElementById("carouselTrack"); const indicators = document.querySelectorAll(".indicator"); const counter = document.getElementById("counter"); const prevBtn = document.getElementById("prevBtn"); const nextBtn = document.getElementById("nextBtn"); currentSlide = slideIndex; track.style.transform = `translateX(-${currentSlide * 940}px)`; indicators.forEach((indicator, index) => { indicator.classList.toggle("active", index === currentSlide); }); counter.textContent = `${currentSlide + 1} / ${housesData.length}`; prevBtn.disabled = currentSlide === 0; nextBtn.disabled = currentSlide === housesData.length - 1; } function nextSlide() { if (currentSlide < housesData.length - 1) { goToSlide(currentSlide + 1); } } function prevSlide() { if (currentSlide > 0) { goToSlide(currentSlide - 1); } } document.addEventListener("DOMContentLoaded", function () { generateHouseCards(); generateIndicators(); goToSlide(0); document.getElementById("nextBtn").addEventListener("click", nextSlide); document.getElementById("prevBtn").addEventListener("click", prevSlide); document.addEventListener("keydown", function (e) { if (e.key === "ArrowLeft") { prevSlide(); } else if (e.key === "ArrowRight") { nextSlide(); } }); }); </script>
[hideprofile]