Перейти к содержимому

Before & After Slider

Динамический слайдер картинок до и после

Component

src/components/BeforeAfter.astro
<div class="relative mx-auto w-full max-w-2xl">
<div class="relative overflow-hidden rounded-2xl">
<slot name="before" />
<slot name="after" />
<div
class="absolute top-0 left-1/2 h-full w-0.5 cursor-ew-resize bg-white"
id="sliderHandle"
style="transform: translateX(-50%);">
<div
class="absolute top-1/2 left-1/2 h-6 w-6 -translate-x-1/2 -translate-y-1/2 transform rounded-full bg-white shadow-lg">
</div>
</div>
<input
type="range"
min="0"
max="100"
value="50"
class="absolute top-0 left-0 h-full w-full cursor-ew-resize opacity-0"
id="slider"
aria-label="Слайдер управления До и После"
/>
<div
class="absolute bottom-4 left-4 z-50 rounded-full bg-white px-2 py-0.5 text-sm font-medium">
До
</div>
<div
class="absolute right-4 bottom-4 z-50 rounded-full bg-white px-2 py-0.5 text-sm font-medium">
После
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
const slider = document.getElementById('slider')
const afterImage = document.getElementById('afterImage')
const sliderHandle = document.getElementById('sliderHandle')
if (slider && afterImage && sliderHandle) {
slider.addEventListener('input', (e) => {
// Приводим тип e.target к HTMLInputElement
const target = e.target as HTMLInputElement
if (target) {
// Преобразуем значение в число
const value = Number(target.value) // или +target.value
afterImage.style.clipPath = `inset(0 ${100 - value}% 0 0)`
sliderHandle.style.left = `${value}%`
}
})
} else {
console.error('Элементы не найдены!')
}
})
</script>

MDX Post

src/content/post.mdx
---
title: "Title"
description: "Description"
---
import BeforeAfter from "../../components/content/BeforeAfter.astro";
import { Picture } from "astro:assets";
import before from './before.png';
import after from './after.png';
<BeforeAfter>
<Picture
slot="before"
src={before}
alt="Before"
width={1024}
height={1024}
formats={["avif", "webp", "jpg"]}
fallbackFormat="jpg"
loading="eager"
class="block h-auto w-full"
id="beforeImage"
/>
<Picture
slot="after"
src={after}
alt="After"
width={1024}
height={1024}
formats={["avif", "webp", "jpg"]}
fallbackFormat="jpg"
loading="eager"
class="absolute top-0 left-0 block h-auto w-full"
style="clip-path: inset(0 50% 0 0);"
id="afterImage"
/>
</BeforeAfter>