🌊 PERFECT: Динамическое позиционирование маркеров с постоянными интервалами
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
@@ -725,6 +725,8 @@
|
||||
padding: 0;
|
||||
transition: all 0.4s cubic-bezier(0.23, 1, 0.32, 1);
|
||||
height: 32px;
|
||||
position: relative;
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
.pill-indicator {
|
||||
@@ -734,12 +736,12 @@
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
padding: 0;
|
||||
margin: 0 2px;
|
||||
margin: 0;
|
||||
color: transparent;
|
||||
font-size: 0;
|
||||
cursor: pointer;
|
||||
transition: all 0.4s cubic-bezier(0.23, 1, 0.32, 1);
|
||||
position: relative;
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
backdrop-filter: blur(5px);
|
||||
display: flex;
|
||||
@@ -747,6 +749,9 @@
|
||||
justify-content: center;
|
||||
box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.3);
|
||||
flex-shrink: 0;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.pill-indicator::before {
|
||||
@@ -767,12 +772,15 @@
|
||||
font-weight: 600;
|
||||
padding: 0 16px;
|
||||
border-radius: 16px;
|
||||
width: auto;
|
||||
width: 80px;
|
||||
height: 32px;
|
||||
min-width: 80px;
|
||||
box-shadow: 0 5px 15px rgba(255, 255, 255, 0.3);
|
||||
backdrop-filter: blur(10px);
|
||||
margin: 0 4px;
|
||||
position: relative;
|
||||
top: auto;
|
||||
left: auto;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.pill-indicator.active::before {
|
||||
@@ -931,16 +939,15 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
}
|
||||
});
|
||||
|
||||
// Анимация внешней pill (растягивается под активный элемент)
|
||||
// Анимация внешней pill и позиционирование маркеров
|
||||
setTimeout(() => {
|
||||
if (outerPill) {
|
||||
const activeIndicator = indicators[index];
|
||||
const inactiveCount = indicators.length - 1;
|
||||
|
||||
if (activeIndicator) {
|
||||
// Даем время для применения стилей активного элемента
|
||||
setTimeout(() => {
|
||||
// Вычисляем ширину на основе текста активного элемента
|
||||
// Вычисляем ширину активной пилюли на основе текста
|
||||
const titleElement = activeIndicator.querySelector('.pill-indicator-title');
|
||||
let activePillWidth = 80; // минимальная ширина активного элемента
|
||||
|
||||
@@ -950,13 +957,50 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
activePillWidth = Math.max(textLength * 7 + 32, 80);
|
||||
}
|
||||
|
||||
// Ширина неактивных элементов: 32px каждый + margin 4px между ними
|
||||
const inactiveWidth = inactiveCount * 32 + (inactiveCount - 1) * 4;
|
||||
// Устанавливаем ширину активного элемента для точного расчета
|
||||
activeIndicator.style.width = activePillWidth + 'px';
|
||||
|
||||
// Общая ширина: активный + неактивные + отступы + margin между активным и неактивными
|
||||
const totalWidth = activePillWidth + inactiveWidth + 32 + (inactiveCount > 0 ? 8 : 0);
|
||||
// Рассчитываем позиции для каждого неактивного маркера
|
||||
const fixedGap = 8; // фиксированный интервал между элементами
|
||||
const markerSize = 32; // размер неактивного маркера
|
||||
|
||||
console.log('Calculated widths - Active:', activePillWidth, 'Inactive total:', inactiveWidth, 'Total:', totalWidth);
|
||||
indicators.forEach((indicator, i) => {
|
||||
if (i !== index) { // для неактивных маркеров
|
||||
let translateX = 0;
|
||||
|
||||
if (i < index) { // маркеры слева от активного
|
||||
// Смещаем влево от центра на половину ширины активной пилюли + gap + позиция
|
||||
const leftOffset = (activePillWidth / 2) + fixedGap + ((index - i - 1) * (markerSize + 4)) + markerSize;
|
||||
translateX = -leftOffset;
|
||||
} else { // маркеры справа от активного
|
||||
// Смещаем вправо от центра на половину ширины активной пилюли + gap + позиция
|
||||
const rightOffset = (activePillWidth / 2) + fixedGap + ((i - index - 1) * (markerSize + 4));
|
||||
translateX = rightOffset;
|
||||
}
|
||||
|
||||
indicator.style.transform = `translateX(${translateX}px)`;
|
||||
indicator.style.transition = 'all 0.4s cubic-bezier(0.23, 1, 0.32, 1)';
|
||||
} else {
|
||||
// Активный элемент остается в центре
|
||||
indicator.style.transform = 'translateX(0)';
|
||||
}
|
||||
});
|
||||
|
||||
// Обновляем ширину внешней пилюли
|
||||
const totalMarkers = indicators.length;
|
||||
const inactiveCount = totalMarkers - 1;
|
||||
|
||||
// Вычисляем максимальное смещение для определения общей ширины
|
||||
let maxOffset = 0;
|
||||
if (inactiveCount > 0) {
|
||||
const maxLeftOffset = (activePillWidth / 2) + fixedGap + ((index) * (markerSize + 4));
|
||||
const maxRightOffset = (activePillWidth / 2) + fixedGap + ((totalMarkers - index - 1) * (markerSize + 4));
|
||||
maxOffset = Math.max(maxLeftOffset, maxRightOffset);
|
||||
}
|
||||
|
||||
const totalWidth = Math.max(activePillWidth + (maxOffset * 2) + 32, activePillWidth + 32);
|
||||
|
||||
console.log('Active pill width:', activePillWidth, 'Total width:', totalWidth);
|
||||
|
||||
outerPill.style.width = totalWidth + 'px';
|
||||
outerPill.style.transition = 'all 0.4s cubic-bezier(0.23, 1, 0.32, 1)';
|
||||
@@ -988,14 +1032,22 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
// Hover эффекты для неактивных элементов
|
||||
indicator.addEventListener('mouseenter', function() {
|
||||
if (!this.classList.contains('active')) {
|
||||
this.style.transform = 'scale(1.1)';
|
||||
// Сохраняем текущий transform и добавляем scale
|
||||
const currentTransform = this.style.transform;
|
||||
const scaleTransform = currentTransform.includes('translateX')
|
||||
? currentTransform.replace(')', ' scale(1.1))')
|
||||
: 'translate(-50%, -50%) scale(1.1)';
|
||||
this.style.transform = scaleTransform;
|
||||
this.style.background = 'rgba(255, 255, 255, 0.6)';
|
||||
}
|
||||
});
|
||||
|
||||
indicator.addEventListener('mouseleave', function() {
|
||||
if (!this.classList.contains('active')) {
|
||||
this.style.transform = 'scale(1)';
|
||||
// Восстанавливаем transform без scale
|
||||
const currentTransform = this.style.transform;
|
||||
const cleanTransform = currentTransform.replace(' scale(1.1)', '');
|
||||
this.style.transform = cleanTransform;
|
||||
this.style.background = 'rgba(255, 255, 255, 0.4)';
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user