iPhone 16 Pro Max 256GB White Titanium – купить за 103 900 ₽ | CristalApple
Гарантия лучшей цены!

Гарантия лучшей цены!

Беcпроцентная рассрочка!

Беcпроцентная рассрочка!

Эксклюзивные предложения!

Эксклюзивные предложения!

(0)
Exclamation Icon НАЛИЧИЕ ТОВАРА УТОЧНЯЕТСЯ ПОСЛЕ ОФОРМЛЕНИЯ ЗАКАЗА

iPhone 16 Pro Max 256GB White Titanium

Важное примечание
iPhone продается без предустановки приложения RuStore. Это обусловлено техническими ограничениями производителя Apple, которые не предоставляют возможность предустановки приложений из неизвестных источников на территории РФ. Приобретая данное устройство, вы соглашаетесь с тем, что уведомлены о наличии указанного ограничения. *Согласно ст. 4, 10 Закона РФ "О защите прав потребителей" №2300-1 от 07.02.1992г.
Apple Logo
Только оригинальные,
не восстановленные iPhone

Нет в наличии
Описание

Больше. Лучше. Профессиональнее

Самый большой, мощный и функциональный – Apple iPhone 16 Pro Max предлагает всё, за что пользователи любят данную линейку, вместе с улучшениями в каждом аспекте. Больше производительности, больше времени работы, больше творческих возможностей как для любителей, так и для создателей контента. Кроме того, смартфон стал выглядеть ещё эффектнее за счёт минимально тонких рамок по периметру экрана, сохранив привычные очертания, а прочное стекло Ceramic Shield и титановая рамка не только делают его впечатляюще надёжным, но и ощущаются приятно и премиально.

Впечатляющий дизайн

Дизайн iPhone 16 Pro и iPhone 16 Pro Max не претерпел значительных изменений, но с первого взгляда в глаза бросаются рамки вокруг дисплея, а точнее их почти полное отсутствие. Это всё тот же лёгкий и прочный титановый корпус с уже ставшими привычными очертаниями и матовым стеклом сзади. За счёт увеличения размеров экрана смартфон стал больше примерно на полмиллиметра с каждой стороны, но толщина осталась прежней, а вот палитра доступных расцветок слегка изменилась.

Самый большой экран iPhone

6,9 дюйма – да, это ещё один момент, когда Pro Max снова бъёт рекорды, при этом экран занимает каждый миллиметр лицевой части – лишь динамический остров напоминает, что вы держите в руках устройство, а не дисплей. Технически это всё тот же OLED-экран Super Retina XDR с Always-on display, динамической частотой обновления от 1 до 120 Гц, True Tone и другими привычными фишками iPhone, а его пиковая яркость на солнце составляет 2000 нит, поэтому комфортно пользоваться и снимать можно в любых условиях.

Новый уровень мобильного гейминга

Процессор A18 Pro – это не только новые возможности для съёмки и творчества и прорыв в области ИИ на мобильных устройствах и 17-процентный прирост общей производительности, но и настоящий праздник для геймеров. Мощная 6-ядерная графика обеспечивает почти двукратный прирост скорости аппаратной трассировки лучей в некоторых играх, в сравнении с A17 Pro, а библиотека ААА-тайтлов для iPhone регулярно расширяется.

Звезда на съёмочной площадке

Далеко не каждая профессиональная беззеркальная камера способна снимать видео в 4K с частотой 120 кадров в секунду в формате ProRes, но для iPhone 16 Pro и Pro Max это посильная задача, а режимы Action Mode, киноэффект с HDR и поддержка LOG-профиля позволят реализовать любые творческие идеи: от эффектных художественных роликов до головокружительных экшн-видео. И, конечно же, вы можете снимать на внешние диски, подключив их к любому высокоскоростному накопителю со скоростью до 10 Гбит/с.

Ближе и дальше, чётче и креативнее

Улучшенный сверхширокоугольный модуль с поддержкой макросъёмки обеспечивает больше деталей, а его разрешение стало идентичным основной камере и составляет 48 Мегапикселей. Более того, iPhone 16 Pro и 16 Pro Max получили 5-кратный оптический зум и 25-кратный цифровой, а возможности камер обоих смартфонов стали идентичными. Любителей фотографии порадуют и новые творческие стили, а также улучшенные алгоритмы Smart HDR и портретного режима.

Совсем как фотоаппарат

Сенсорная область для управления камерой – это не просто ещё одна кнопка. Это мини-трекпад, с которого можно легко и быстро настраивать параметры в процессе съёмки, за счёт чего iPhone ещё сильнее ощущается именно как камера. Ну а поскольку любители снимать могут больше не занимать кнопку Action Button камерой – её теперь можно назначить на другие действия и приложения.

Заряжается быстрее – работает дольше

Оптимизация и увеличение ёмкости аккумулятора позволили добиться дополнительных 4-х часов экранного времени, но куда значительнее другая особенность – скорость зарядки. При использовании модуля MagSafe (необходима версия 2024 года и новее) поддерживается мощность до 25 Ватт, а быстрая проводная зарядка позволяет зарядить смартфон всего за 30 минут до 50% через USB-C.

Больше кастомизаци

Любой iPhone невозможно рассматривать отдельно от iOS, ведь именно в ней кроется та самая магия Apple, и возможности iOS 18 делают смартфон ещё функциональнее и удобнее. Так, например, теперь есть возможность записывать телефонные разговоры, настраивать внешний вид и расположение значков приложений, кнопки быстрого доступа на экране блокировки и добавлять больше разных элементов в пункт управления, а также ограничивать доступ к приложениям по Face ID.

Новые возможности экосистемы Apple

Пожалуй, вряд ли необходимо в очередной раз рассказывать обо всех преимуществах iCloud, Apple Watch, AirPods и других фирменных гаджетов в связке с iPhone, стоит только в очередной раз сказать очевидное: это настоящая магия. А вот пользователи macOS Sequoia вместе с iOS 18 получили новый приятный бонус: теперь можно управлять смартфоном прямо с компьютера без проводов и необходимости разблокировать свой iPhone, где бы он не лежал. Вы даже можете с лёгкостью копировать текст, изображения и видео, а для просмотра уведомлений теперь не нужно каждый раз доставать айфон из кармана или сумки.

Показать полностью Свернуть
Характеристики
Бренд
Apple
Модель
iPhone 16 Pro Max
Память
256ГБ
Цвет
Белый титан
Отзывы
Отзывов еще никто не оставлял
Написать отзыв Отмена
Оставить отзыв
Ранее просмотренные
Почему Cristal Apple
Более 12 лет                                                                               на рынке
Более 12 лет на рынке
Гарантия на каждый товар
Гарантия на каждый товар
3 физические точки продаж
3 физические точки продаж
Почему Cristal Apple
Возможность покупки в кредит
Возможность покупки в кредит
Бесплатная доставка по региону
Бесплатная доставка по региону
Самовывоз через 15 минут
Самовывоз через 15 минут
Гарантия лучшей цены
Гарантия лучшей цены
Опыт работы более 10 лет
Опыт работы более 10 лет
0
Navigation
Обратный звонок
Запрос успешно отправлен!
Имя *
Телефон *
Предзаказ
Предзаказ успешно отправлен!
Имя *
Телефон *
Добавить в корзину
Название товара
100 ₽
1 шт.
Перейти в корзину
$(function() { var isTouch = !!('ontouchstart' in window || navigator.msMaxTouchPoints); var mobile_point = 767; const isMobile = () => $(window).width() <= mobile_point; const isIOS = /iPhone|iPad|iPod/.test(navigator.userAgent); // ✅ ИСПРАВЛЕНИЕ: Определяем $widget в начале const $widget = $('.wt-widget-v4-collections-on-index'); if (isTouch) { $widget.find(".collection-preview").addClass("is-touch"); } $widget.each(function(index, el) { new LazyLoad({ container: $(el).get(0), elements_selector: '.lazyload', use_native: 'loading' in document.createElement('img') }); }); // ========== LIQUID GLASS DROP ========== function smoothStep(a, b, t) { t = Math.max(0, Math.min(1, (t - a) / (b - a))); return t * t * (3 - 2 * t); } function length(x, y) { return Math.sqrt(x * x + y * y); } function roundedRectSDF(x, y, width, height, radius) { const qx = Math.abs(x) - width + radius; const qy = Math.abs(y) - height + radius; return Math.min(Math.max(qx, qy), 0) + length(Math.max(qx, 0), Math.max(qy, 0)) - radius; } function texture(x, y) { return { x, y }; } class LiquidGlassDrop { constructor(container, sliderElement, splideInstance) { this.containerElement = container; this.sliderElement = sliderElement; this.splideInstance = splideInstance; this.splideTrack = sliderElement.querySelector('.splide__track'); this.splideList = sliderElement.querySelector('.splide__list'); this.canvasDPI = 1; this.id = 'liquid-glass-' + Math.random().toString(36).substr(2, 9); this.dragVelocity = 0; this.scaleMultiplier = 1; this.isIOS = isIOS; this.resizeObserver = null; this.currentVisibleSlide = null; this.listPadding = 16; // ✅ ИСПРАВЛЕНИЕ: Пиксельный буфер для SVG-фильтра (критично для iOS) this.filterBuffer = 20; this.container = this.containerElement.querySelector('.glass-drop'); this.dropContainer = this.containerElement.querySelector('.glass-drop-container'); // ✅ Проверка поддержки backdrop-filter const testElement = document.createElement('div'); testElement.style.backdropFilter = 'blur(1px)'; testElement.style.webkitBackdropFilter = 'blur(1px)'; this.supportsBackdropFilter = testElement.style.backdropFilter !== '' || testElement.style.webkitBackdropFilter !== ''; this.init(); } init() { // ✅ Показываем контейнер, если все готово this.dropContainer.style.display = 'block'; this.updateDimensions(); this.createElement(); this.updateShader(); this.setupResizeObserver(); this.startRenderLoop(); this.addClickHint(); this.setupDragHandler(); // Перенесли в init } updateDimensions() { // ✅ Ищем именно активный видимый слайд const activeSlide = this.sliderElement.querySelector('.splide__slide.is-active.is-visible'); const targetSlide = activeSlide || this.sliderElement.querySelector('.splide__slide.is-visible') || this.sliderElement.querySelector('.splide__slide'); if (targetSlide) { const slideRect = targetSlide.getBoundingClientRect(); // ✅ Капля должна быть чуть выше слайда const newWidth = Math.round(slideRect.width); const newHeight = Math.round(slideRect.height) + 35; // Добавляем 35px к высоте (больше снизу) const dimensionsChanged = this.width !== newWidth || this.height !== newHeight; this.width = newWidth; this.height = newHeight; this.currentVisibleSlide = targetSlide; this.radius = 37 / Math.max(this.width, this.height); document.documentElement.style.setProperty('--drop-width', `${this.width}px`); document.documentElement.style.setProperty('--drop-height', `${this.height}px`); // Обновляем размеры капли (самого div) this.dropContainer.style.width = `${this.width}px`; this.dropContainer.style.height = `${this.height}px`; if (dimensionsChanged && this.feImage) { this.updateSVGFilterDimensions(); } return dimensionsChanged; } else { // Fallback: используем размеры по умолчанию this.width = 140; this.height = 215; // 180 + 35 this.radius = 37 / Math.max(this.width, this.height); document.documentElement.style.setProperty('--drop-width', `${this.width}px`); document.documentElement.style.setProperty('--drop-height', `${this.height}px`); this.dropContainer.style.width = `${this.width}px`; this.dropContainer.style.height = `${this.height}px`; return false; } } // ✅ НОВЫЙ МЕТОД: Обновление размеров SVG фильтра с буфером для iOS updateSVGFilterDimensions() { const buffer = this.filterBuffer; const filter = this.svg.querySelector(`#${this.id}_filter`); if (filter) { // 1. Расширяем область фильтра на 2*buffer, чтобы избежать обрезки при трансформациях filter.setAttribute('width', (this.width + 2 * buffer).toString()); filter.setAttribute('height', (this.height + 2 * buffer).toString()); // 2. Сдвигаем область фильтра на -buffer, чтобы она была центрирована filter.setAttribute('x', `-${buffer}`); filter.setAttribute('y', `-${buffer}`); filter.setAttribute('primitiveUnits', 'userSpaceOnUse'); } if (this.feImage) { // feImage должен быть того же размера, что и элемент (без буфера) this.feImage.setAttribute('width', this.width.toString()); this.feImage.setAttribute('height', this.height.toString()); // 3. Сдвигаем feImage на +buffer, чтобы компенсировать сдвиг фильтра this.feImage.setAttribute('x', buffer.toString()); this.feImage.setAttribute('y', buffer.toString()); } this.canvas.width = this.width * this.canvasDPI; this.canvas.height = this.height * this.canvasDPI; this.updateShader(); } setupResizeObserver() { if ('ResizeObserver' in window) { this.resizeObserver = new ResizeObserver((entries) => { for (const entry of entries) { if (entry.target.classList.contains('splide__slide') || entry.target.classList.contains('splide__track')) { this.updateDimensions(); } } }); this.resizeObserver.observe(this.splideTrack); const slides = this.sliderElement.querySelectorAll('.splide__slide'); slides.forEach(slide => { this.resizeObserver.observe(slide); }); } } observeVisibleSlide() { // Отслеживаем именно активный видимый слайд const activeSlide = this.sliderElement.querySelector('.splide__slide.is-active.is-visible'); const visibleSlide = activeSlide || this.sliderElement.querySelector('.splide__slide.is-visible'); if (visibleSlide && visibleSlide !== this.currentVisibleSlide) { this.resize(); // Вызываем полную перерисовку/обновление размеров } } // ✅ Функция для определения активного слайда под каплей getActiveSlideUnderDrop() { if (!this.dropContainer) return null; const dropX = parseFloat(this.dropContainer.style.getPropertyValue('--drop-pos-x')) || 0; const dropWidth = parseFloat(this.dropContainer.style.getPropertyValue('--drop-width')) || 140; const dropCenter = dropX + dropWidth / 2; const slides = this.sliderElement.querySelectorAll('.splide__slide'); const trackRect = this.sliderElement.querySelector('.splide__track').getBoundingClientRect(); let closestSlide = null; let minDistance = Infinity; slides.forEach((slide) => { const slideRect = slide.getBoundingClientRect(); // slideCenter относительно trackRect.left const slideCenter = slideRect.left - trackRect.left + slideRect.width / 2; const distance = Math.abs(slideCenter - dropCenter); if (distance < minDistance) { minDistance = distance; closestSlide = slide; } }); return closestSlide; } // ✅ Функция для добавления подсказки о клике addClickHint() { if (!this.container) return; this.container.classList.add('show-click-hint'); const removeHint = () => { this.container.classList.remove('show-click-hint'); this.container.removeEventListener('click', removeHint); this.container.removeEventListener('touchstart', removeHint); }; this.container.addEventListener('click', removeHint); this.container.addEventListener('touchstart', removeHint); setTimeout(() => { this.container.classList.remove('show-click-hint'); }, 3000); } createElement() { // ✅ 1. Create SVG filter this.svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); this.svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); this.svg.setAttribute('width', '0'); this.svg.setAttribute('height', '0'); this.svg.style.cssText = 'position:fixed;top:0;left:0;pointer-events:none;z-index:9998;'; const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs'); const filter = document.createElementNS('http://www.w3.org/2000/svg', 'filter'); filter.setAttribute('id', `${this.id}_filter`); filter.setAttribute('filterUnits', 'userSpaceOnUse'); filter.setAttribute('colorInterpolationFilters', 'sRGB'); // ✅ Инициализируем фильтр с буфером для iOS const buffer = this.filterBuffer; filter.setAttribute('x', `-${buffer}`); filter.setAttribute('y', `-${buffer}`); filter.setAttribute('width', (this.width + 2 * buffer).toString()); filter.setAttribute('height', (this.height + 2 * buffer).toString()); filter.setAttribute('primitiveUnits', 'userSpaceOnUse'); this.feImage = document.createElementNS('http://www.w3.org/2000/svg', 'feImage'); this.feImage.setAttribute('id', `${this.id}_map`); this.feImage.setAttribute('width', this.width.toString()); this.feImage.setAttribute('height', this.height.toString()); this.feImage.setAttribute('x', buffer.toString()); // Сдвигаем feImage this.feImage.setAttribute('y', buffer.toString()); // Сдвигаем feImage this.feImage.setAttribute('result', 'map'); this.feDisplacementMap = document.createElementNS('http://www.w3.org/2000/svg', 'feDisplacementMap'); this.feDisplacementMap.setAttribute('in', 'SourceGraphic'); this.feDisplacementMap.setAttribute('in2', 'map'); this.feDisplacementMap.setAttribute('xChannelSelector', 'R'); this.feDisplacementMap.setAttribute('yChannelSelector', 'G'); this.feDisplacementMap.setAttribute('scale', '0'); filter.appendChild(this.feImage); filter.appendChild(this.feDisplacementMap); defs.appendChild(filter); this.svg.appendChild(defs); // ✅ 2. Create canvas this.canvas = document.createElement('canvas'); this.canvas.width = this.width * this.canvasDPI; this.canvas.height = this.height * this.canvasDPI; this.canvas.style.display = 'none'; this.context = this.canvas.getContext('2d'); // ✅ 3. Apply filter to glass-drop element if (this.container) { const filterURL = `url(#${this.id}_filter)`; this.container.style.webkitBackdropFilter = filterURL; this.container.style.backdropFilter = filterURL; this.container.style.isolation = 'isolate'; this.container.style.webkitTransform = 'translateZ(0)'; this.container.style.transform = 'translateZ(0)'; this.container.style.willChange = 'backdrop-filter, transform'; this.container.style.webkitBackfaceVisibility = 'hidden'; this.container.style.backfaceVisibility = 'hidden'; this.container.style.webkitPerspective = '1000'; this.container.style.perspective = '1000'; // ✅ Обработчик клика const clickHandler = (e) => { if (e.type.startsWith('touch') && this.dragVelocity > 5) return; e.preventDefault(); e.stopPropagation(); const activeSlide = this.getActiveSlideUnderDrop(); if (activeSlide) { const link = activeSlide.querySelector('.collection-link'); if (link) { this.container.classList.add('is-clicked'); setTimeout(() => { this.container.classList.remove('is-clicked'); window.location.href = link.getAttribute('href'); }, 150); } } }; this.container.addEventListener('click', clickHandler); this.container.addEventListener('touchend', clickHandler); } // ✅ 4. Append SVG и Canvas document.body.appendChild(this.svg); document.body.appendChild(this.canvas); } fragment(pos) { const { x, y } = pos; const normX = (x * 2 - 1) / this.scaleMultiplier; const normY = (y * 2 - 1) / this.scaleMultiplier; const normWidth = (this.width * this.scaleMultiplier) / Math.max(this.width, this.height) * this.radius; const normHeight = (this.height * this.scaleMultiplier) / Math.max(this.width, this.height) * this.radius; const normRadius = this.radius; const distanceToEdge = roundedRectSDF( normX, normY, normWidth * this.scaleMultiplier, normHeight * this.scaleMultiplier, normRadius ); const displacement = smoothStep(0.8, 0, distanceToEdge - 0.15); const scaled = smoothStep(0, 1, displacement); return texture(x * scaled + 0.5, y * scaled + 0.5); } updateShader() { const w = this.width * this.canvasDPI; const h = this.height * this.canvasDPI; const data = new Uint8ClampedArray(w * h * 4); let maxScale = 0; const rawValues = []; for (let i = 0; i < data.length; i += 4) { const x = (i / 4) % w; const y = Math.floor(i / 4 / w); const pos = this.fragment({ x: x / w, y: y / h }); const dx = pos.x * w - x; const dy = pos.y * h - y; maxScale = Math.max(maxScale, Math.abs(dx), Math.abs(dy)); rawValues.push(dx, dy); } maxScale *= 0.5; let index = 0; for (let i = 0; i < data.length; i += 4) { const r = rawValues[index++] / maxScale + 0.5; const g = rawValues[index++] / maxScale + 0.5; data[i] = r * 255; data[i + 1] = g * 255; data[i + 2] = 0; data[i + 3] = 255; } try { this.context.putImageData(new ImageData(data, w, h), 0, 0); this.feImage.setAttributeNS('http://www.w3.org/1999/xlink', 'href', this.canvas.toDataURL()); const baseScale = maxScale / this.canvasDPI; const velocityMultiplier = 0.05; const finalScale = baseScale * (1 + this.dragVelocity * velocityMultiplier); this.feDisplacementMap.setAttribute('scale', isNaN(finalScale) ? '0' : finalScale.toString()); } catch (error) { console.error('Shader update error:', error); } } updateDragState(velocity) { this.dragVelocity = Math.min(Math.abs(velocity), 50); this.scaleMultiplier = 1 + (this.dragVelocity * 0.005); if (this.container) { const scaleX = 1 + (this.dragVelocity * 0.01); const scaleY = 1 - (this.dragVelocity * 0.005); this.container.style.setProperty('--scale-x', scaleX); this.container.style.setProperty('--scale-y', scaleY); if (velocity !== 0) { this.container.classList.add('is-dragging'); } else { this.container.classList.remove('is-dragging'); } } this.updateShader(); } startRenderLoop() { const render = () => { this.observeVisibleSlide(); if (this.dragVelocity > 0.1) { this.dragVelocity *= 0.92; this.updateDragState(this.dragVelocity); } else if (this.dragVelocity > 0) { this.dragVelocity = 0; this.updateDragState(0); } requestAnimationFrame(render); }; requestAnimationFrame(render); } resize() { const changed = this.updateDimensions(); if (changed) { // SVG/Canvas удаляются/создаются заново только при изменении размеров слайда if (this.svg && this.svg.parentNode) { this.svg.remove(); } if (this.canvas && this.canvas.parentNode) { this.canvas.remove(); } this.createElement(); this.updateShader(); // Обновляем точки привязки после ресайза this.calculateSnapPoints(); this.updateDropPosition(this.splideInstance.index); } } // ============= DRAG LOGIC REFACTOR ============= calculateSnapPoints() { this.snapPoints = []; const track = this.sliderElement.querySelector('.splide__track'); if (!track) return; const trackRect = track.getBoundingClientRect(); const slides = this.sliderElement.querySelectorAll('.splide__slide'); slides.forEach((slide) => { const slideRect = slide.getBoundingClientRect(); // Позиция капли = (Центр слайда - Левый край трека) - (Ширина капли / 2) const dropX = (slideRect.left + slideRect.width / 2) - trackRect.left - (this.width / 2); this.snapPoints.push(dropX); }); // Устанавливаем ширину контейнера капли this.dropContainer.style.width = `${this.width}px`; } updateDropPosition(index) { if (this.snapPoints && this.snapPoints[index] !== undefined) { this.currentDropX = this.snapPoints[index]; this.dropContainer.style.setProperty('--drop-pos-x', `${this.currentDropX}px`); } } setupDragHandler() { const dropContainer = this.dropContainer; const splide = this.splideInstance; let isDragging = false; let startX = 0; let startDropX = 0; let lastTime = 0; let lastX = 0; let animationFrameId = null; let isSettling = false; let dragVelocity = 0; this.currentDropX = 0; this.calculateSnapPoints(); this.updateDropPosition(splide.index); // Начальная позиция const animateDrag = () => { if (!isDragging && !isSettling) { cancelAnimationFrame(animationFrameId); animationFrameId = null; return; } if (isDragging) { const currentTime = performance.now(); const deltaTime = currentTime - lastTime; if (deltaTime > 0) { dragVelocity = (this.currentDropX - lastX) / deltaTime * 100; // px/ms -> px/s } lastTime = currentTime; lastX = this.currentDropX; this.updateDragState(dragVelocity); } else if (isSettling) { dragVelocity *= 0.85; if (Math.abs(dragVelocity) < 0.5) { dragVelocity = 0; isSettling = false; } this.updateDragState(dragVelocity); } animationFrameId = requestAnimationFrame(animateDrag); } // DRAG START const startDrag = (e) => { if (isMobile() && e.type === 'mousedown') return; if (!isMobile() && e.type.startsWith('touch')) return; if (e.touches) { if (e.touches.length > 1) return; e.preventDefault(); } e.stopPropagation(); isDragging = true; isSettling = false; const clientX = e.touches ? e.touches[0].clientX : e.clientX; startX = clientX; startDropX = this.currentDropX; lastX = this.currentDropX; lastTime = performance.now(); this.container.style.transition = 'none'; dropContainer.style.transition = 'none'; if (!animationFrameId) { animateDrag(); } } // DRAG MOVE const drag = (e) => { if (!isDragging) return; const clientX = e.touches ? e.touches[0].clientX : e.clientX; const dx = clientX - startX; this.currentDropX = startDropX + dx; dropContainer.style.setProperty('--drop-pos-x', `${this.currentDropX}px`); // СИНХРОНИЗАЦИЯ СЛАЙДЕРА const dropCenter = this.currentDropX + (this.width / 2); let minDistance = Infinity; let closestIndex = -1; this.snapPoints.forEach((snapX, index) => { const snapCenter = snapX + (this.width / 2); const distance = Math.abs(dropCenter - snapCenter); if (distance < minDistance) { minDistance = distance; closestIndex = index; } }); // Двигаем слайдер, если капля сместилась к другому слайду if (closestIndex !== -1 && splide.index !== closestIndex) { splide.go(closestIndex); } if (e.type.startsWith('touch') && Math.abs(dx) > 10) { e.preventDefault(); } } // DRAG END const endDrag = (e) => { if (!isDragging) return; isDragging = false; isSettling = true; this.container.style.transition = ''; dropContainer.style.transition = ''; // Находим ближайшую точку для привязки капли let closestIndex = splide.index; // Анимируем каплю к точке привязки if (this.snapPoints[closestIndex] !== undefined) { this.currentDropX = this.snapPoints[closestIndex]; dropContainer.style.setProperty('--drop-pos-x', `${this.currentDropX}px`); } } // Инициализация событий dropContainer.addEventListener('mousedown', startDrag); window.addEventListener('mousemove', drag); window.addEventListener('mouseup', endDrag); window.addEventListener('mouseleave', endDrag); dropContainer.addEventListener('touchstart', startDrag, { passive: false }); window.addEventListener('touchmove', drag, { passive: false }); window.addEventListener('touchend', endDrag); // Обновление позиции капли при переключении слайдера splide.on('move', (newIndex) => { if (!isDragging) { this.updateDropPosition(newIndex); } }); // Пересчет точек при изменении размера window.addEventListener('resize', () => { setTimeout(() => { this.calculateSnapPoints(); this.updateDropPosition(splide.index); }, 100); this.resize(); }); } // ============= END DRAG LOGIC REFACTOR ============= } // ========== SLIDER INITIALIZATION (unchanged) ========== if (isMobile()) { let specialCollections = $widget.find(".js-collections"); let slider_mobile_right_padding; let slide_width_mobile; let slide_gap_mobile = specialCollections.find(".js-collections-slider").attr("data-slide-gap-mobile") / 2; $(window).on("resize", function() { slide_width_mobile = specialCollections.find(".splide__slide").width(); slider_mobile_right_padding = slide_width_mobile * 0.5 + slide_gap_mobile; specialCollections.find(".js-collections-slider").attr("data-mobile-right-padding", slider_mobile_right_padding); }); specialCollections.each(function() { let collections_block = $(this); let slider_block = collections_block.find(".js-collections-slider"); let slide_min_width = 160; let slide_min_width_mobile = 130; let slide_gap = 30; let slide_gap_mobile = 15; if (slider_block.is("[data-slide-min-width]")) { slide_min_width = parseInt(slider_block.attr("data-slide-min-width")); } else { slider_block.attr("data-slide-min-width", slide_min_width); } if (slider_block.is("[data-slide-min-width-mobile]")) { slide_min_width_mobile = parseInt(slider_block.attr("data-slide-min-width-mobile")); } else { slider_block.attr("data-slide-min-width-mobile", slide_min_width_mobile); } if (slider_block.is("[data-slide-gap]")) { slide_gap = parseInt(slider_block.attr("data-slide-gap")); } else { slider_block.attr("data-slide-gap", slide_gap); } if (slider_block.is("[data-slide-gap-mobile]")) { slide_gap_mobile = parseInt(slider_block.attr("data-slide-gap-mobile")); } else { slider_block.attr("data-slide-gap-mobile", slide_gap_mobile); } slide_width_mobile = slider_block.find(".splide__slide").width(); slider_mobile_right_padding = slide_width_mobile * 0.5 + slide_gap_mobile; slider_block.attr("data-mobile-right-padding", slider_mobile_right_padding); let slider = slider_block.splide({ type: "slide", drag: "free", snap: true, arrows: false, pagination: false, gap: slide_gap_mobile, padding: { right: slider_mobile_right_padding }, breakpoints: { 767: { arrows: false, gap: slide_gap_mobile, padding: { right: slider_mobile_right_padding }, }, }, }); configureSlider(slider, slider_block, slide_min_width, slide_min_width_mobile, slide_gap, slide_gap_mobile); // ✅ Инициализация Liquid Glass Drop только после монтирования Splide slider[0].splide.on('mounted', function() { if (isMobile()) { const dropInstance = new LiquidGlassDrop(collections_block[0], slider_block[0], slider[0].splide); slider_block.data('liquidGlassDrop', dropInstance); } }); // На случай, если Splide уже смонтирован if (slider[0].splide.root.classList.contains('is-initialized') && !slider_block.data('liquidGlassDrop')) { if (isMobile()) { const dropInstance = new LiquidGlassDrop(collections_block[0], slider_block[0], slider[0].splide); slider_block.data('liquidGlassDrop', dropInstance); } } }); } else { // Desktop initialization logic (без изменений) $widget.find(".js-collections-slider").each(function() { let slider_block = $(this); let slide_min_width = 160; let slide_min_width_mobile = 130; let slide_gap = 30; let slide_gap_mobile = 15; if (slider_block.is("[data-slide-min-width]")) { slide_min_width = parseInt(slider_block.attr("data-slide-min-width")); } if (slider_block.is("[data-slide-min-width-mobile]")) { slide_min_width_mobile = parseInt(slider_block.attr("data-slide-min-width-mobile")); } if (slider_block.is("[data-slide-gap]")) { slide_gap = parseInt(slider_block.attr("data-slide-gap")); } if (slider_block.is("[data-slide-gap-mobile]")) { slide_gap_mobile = parseInt(slider_block.attr("data-slide-gap-mobile")); } let slider = slider_block.splide({ type: "slide", arrows: true, pagination: false, gap: slide_gap, breakpoints: { 767: { arrows: false, gap: slide_gap_mobile, }, }, }); configureSlider(slider, slider_block, slide_min_width, slide_min_width_mobile, slide_gap, slide_gap_mobile); }); } function isMobileWidth() { return $(window).width() <= mobile_point; } function configureSlider(slider, sliderBlock, slide_min_width, slide_min_width_mobile, slide_gap, slide_gap_mobile) { let sliderInst = slider[0].splide; sliderInst.on("mounted", function() { sliderInst.go(0); recalcSlidesPerView(); displaySliderControls(slider); }); sliderInst.on("refresh", function() { recalcSlidesPerView(); displaySliderControls(slider); }); $(window).on("resize", function() { setTimeout(function() { if (sliderInst) { sliderInst.refresh(); // При ресайзе уведомляем каплю о необходимости обновления const dropInstance = sliderBlock.data('liquidGlassDrop'); if (dropInstance) { dropInstance.resize(); } } }, 0); }); function recalcSlidesPerView() { setTimeout(() => { let init_slide_min_width = isMobileWidth() ? slide_min_width_mobile : slide_min_width; let init_slide_gap = isMobileWidth() ? slide_gap_mobile : slide_gap; let new_per_page = getSlidesPerView(sliderBlock, init_slide_min_width, init_slide_gap); sliderInst.options = { perPage: new_per_page }; }, 0); } configureDragOption(slider); } function getSlidesPerView(sliderBlock, slideMinWidth, slideGap) { let right_padding = 0; if (sliderBlock.is("[data-mobile-right-padding]") && isMobileWidth()) { right_padding = parseInt(sliderBlock.data("mobileRightPadding")) + slideGap; } return Math.floor((sliderBlock.width() + slideGap - right_padding) / (slideMinWidth + slideGap)); } function displaySliderControls(slider) { let sliderInst = slider[0].splide; let collections = slider.parents(".js-collections"); let slider_arrow = collections.find(".collections__slider-arrow"); if (sliderInst.length <= sliderInst.options.perPage) { slider_arrow.addClass("is-hide"); slider.addClass("is-hide-paging"); } else { slider_arrow.removeClass("is-hide"); slider.removeClass("is-hide-paging"); } } function configureDragOption(slider) { if (slider[0].splide.length <= slider[0].splide.options.perPage) { slider.splide().options = { drag: false }; } } });
Заявка

Я ознакомлен и согласен с условиями оферты и политики конфиденциальности.

Заказ в один клик

Я ознакомлен и согласен с условиями оферты и политики конфиденциальности.