Новые правки страницы - Возврат прав

This commit is contained in:
Web-serfer 2026-04-12 19:21:14 +05:00
parent f5669e196f
commit 24be657ac6
20 changed files with 3219 additions and 45 deletions

View file

@ -45,7 +45,7 @@ const lawyerImageUrl = "/images/home/avtourist-surgut.avif";
<img src={lawyerImageUrl} alt="Юрист" class="main-image" />
<div class="experience-badge animate-load" data-delay="1100">
<span class="exp-number">20+</span>
<span class="exp-text">ЛЕТ ОПЫТА В ХМАО</span>
<span class="exp-text">ЛЕТ ОПЫТА В СУДАХ</span>
</div>
</div>
</div>

View file

@ -75,6 +75,15 @@ const displayReviews = [...latestReviews, ...latestReviews, ...latestReviews];
display: flex;
}
/* Центрирование карточки на мобильном */
#sliderContainer {
scroll-snap-type: x mandatory;
}
#sliderTrack {
scroll-snap-align: center;
}
/* Убедимся, что карточка растягивается на всю ширину слайда */
.card-item :global(.review-card) {
width: 100%;

View file

@ -93,19 +93,19 @@ const {
</div>
<!-- Статистика -->
<div class="stats-bar animate-on-scroll" data-animation="fade-up" data-delay="700">
<div class="stats-bar animate-on-scroll" data-animation="fade-up" data-delay="700" id="stats-bar">
<div class="stat-item">
<div class="stat-number">98%</div>
<div class="stat-number" data-target="98" data-suffix="%">0%</div>
<div class="stat-label">успешных дел</div>
</div>
<div class="stat-divider"></div>
<div class="stat-item">
<div class="stat-number">500+</div>
<div class="stat-number" data-target="500" data-suffix="+">0+</div>
<div class="stat-label">довольных клиентов</div>
</div>
<div class="stat-divider"></div>
<div class="stat-item">
<div class="stat-number">15 лет</div>
<div class="stat-number" data-target="15" data-suffix=" лет">0 лет</div>
<div class="stat-label">опыта</div>
</div>
</div>
@ -644,6 +644,32 @@ const {
threshold: 0.15
};
// Анимация счётчиков
function animateCounter(el: HTMLElement) {
const target = parseInt(el.dataset.target || '0');
const suffix = el.dataset.suffix || '';
const duration = 1500;
const startTime = performance.now();
// Easing функция (ease-out cubic)
const easeOutCubic = (t: number) => 1 - Math.pow(1 - t, 3);
function update(currentTime: number) {
const elapsed = currentTime - startTime;
const progress = Math.min(elapsed / duration, 1);
const easedProgress = easeOutCubic(progress);
const currentValue = Math.round(easedProgress * target);
el.textContent = `${currentValue}${suffix}`;
if (progress < 1) {
requestAnimationFrame(update);
}
}
requestAnimationFrame(update);
}
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
@ -652,6 +678,17 @@ const {
setTimeout(() => {
el.classList.add('is-visible');
// Если это stats-bar, запускаем анимацию счётчиков
if (el.id === 'stats-bar') {
const counters = el.querySelectorAll('.stat-number');
counters.forEach((counter, index) => {
// Небольшая задержка между счётчиками для каскадного эффекта
setTimeout(() => {
animateCounter(counter as HTMLElement);
}, index * 150);
});
}
}, delay);
observer.unobserve(el);