Design language
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { onMount, tick } from 'svelte';
|
||||
import { reveal } from '$lib/actions/reveal';
|
||||
import Icon from '$lib/components/Icon.svelte';
|
||||
import { getEnhancedImage } from '$lib/enhanced-images';
|
||||
@@ -52,6 +52,7 @@
|
||||
let inView = false;
|
||||
let prefersReducedMotion = false;
|
||||
let carouselEl: HTMLDivElement | undefined;
|
||||
let stageEl: HTMLDivElement | undefined;
|
||||
let slideSignature = '';
|
||||
|
||||
$: slides = testimonials
|
||||
@@ -89,6 +90,7 @@
|
||||
}
|
||||
|
||||
activeIndex = (activeIndex - 1 + slides.length) % slides.length;
|
||||
syncMobileStage();
|
||||
}
|
||||
|
||||
function showNext() {
|
||||
@@ -97,6 +99,34 @@
|
||||
}
|
||||
|
||||
activeIndex = (activeIndex + 1) % slides.length;
|
||||
syncMobileStage();
|
||||
}
|
||||
|
||||
function isMobileViewport() {
|
||||
return typeof window !== 'undefined' && window.innerWidth <= 767;
|
||||
}
|
||||
|
||||
async function syncMobileStage(behavior: ScrollBehavior = 'smooth') {
|
||||
if (!stageEl || !isMobileViewport()) {
|
||||
return;
|
||||
}
|
||||
|
||||
await tick();
|
||||
stageEl.scrollTo({
|
||||
left: stageEl.clientWidth * activeIndex,
|
||||
behavior
|
||||
});
|
||||
}
|
||||
|
||||
function handleStageScroll() {
|
||||
if (!stageEl || !isMobileViewport()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const nextIndex = Math.round(stageEl.scrollLeft / Math.max(stageEl.clientWidth, 1));
|
||||
if (nextIndex !== activeIndex) {
|
||||
activeIndex = nextIndex;
|
||||
}
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
@@ -120,6 +150,13 @@
|
||||
observer.observe(carouselEl);
|
||||
}
|
||||
|
||||
const handleResize = () => {
|
||||
syncMobileStage('auto');
|
||||
};
|
||||
|
||||
window.addEventListener('resize', handleResize);
|
||||
syncMobileStage('auto');
|
||||
|
||||
const interval = window.setInterval(() => {
|
||||
if (!paused && !prefersReducedMotion && inView && slides.length > 1) {
|
||||
showNext();
|
||||
@@ -128,6 +165,7 @@
|
||||
|
||||
return () => {
|
||||
window.clearInterval(interval);
|
||||
window.removeEventListener('resize', handleResize);
|
||||
motionQuery.removeEventListener('change', onMotionChange);
|
||||
observer?.disconnect();
|
||||
};
|
||||
@@ -162,7 +200,7 @@
|
||||
<Icon name="fas fa-chevron-left" />
|
||||
</button>
|
||||
|
||||
<div class="testimonial-stage">
|
||||
<div bind:this={stageEl} class="testimonial-stage" on:scroll={handleStageScroll}>
|
||||
<div class="testimonial-woof" aria-hidden="true">
|
||||
<span class="testimonial-woof-text">WOOF</span>
|
||||
<span class="testimonial-ray testimonial-ray-1"></span>
|
||||
@@ -640,14 +678,28 @@
|
||||
|
||||
.testimonial-stage {
|
||||
min-height: unset;
|
||||
display: flex;
|
||||
padding-bottom: 0;
|
||||
overflow-x: auto;
|
||||
overscroll-behavior-x: contain;
|
||||
scroll-snap-type: x proximity;
|
||||
scrollbar-width: none;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.testimonial-stage::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.testimonial-slide {
|
||||
position: relative;
|
||||
display: none;
|
||||
display: grid;
|
||||
flex: 0 0 100%;
|
||||
grid-template-columns: 1fr;
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
transform: none;
|
||||
scroll-snap-align: start;
|
||||
}
|
||||
|
||||
.testimonial-slide-active {
|
||||
@@ -689,17 +741,27 @@
|
||||
.testimonial-mobile-controls {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
width: 100%;
|
||||
gap: 12px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.testimonial-arrow-inline {
|
||||
position: static;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
width: 46px;
|
||||
height: 46px;
|
||||
border: none;
|
||||
border-radius: 50%;
|
||||
background: rgba(33, 48, 33, 0.08);
|
||||
color: var(--gw-green);
|
||||
font-size: 18px;
|
||||
transform: none;
|
||||
box-shadow: 0 10px 22px rgba(20, 24, 20, 0.08);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.testimonial-arrow-inline:active {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
.testimonial-google {
|
||||
|
||||
Reference in New Issue
Block a user