اسلایدر/دماوندپلیمر - فراغیب
بدون خلاصۀ ویرایش |
بدون خلاصۀ ویرایش |
||
| خط ۱۱۸: | خط ۱۱۸: | ||
<style> | <style> | ||
.fgwiki-gallery, | .fgwiki-gallery, | ||
.fgwiki-gallery *{ | .fgwiki-gallery * { | ||
box-sizing:border-box; | box-sizing: border-box; | ||
} | } | ||
.fgwiki-gallery{ | |||
.fgwiki-gallery { | |||
--fg-items: | --fg-items: 3; | ||
--fg-gap: | --fg-gap: 18px; | ||
--fg-radius:18px; | --fg-radius: 18px; | ||
--fg-image-height: | --fg-image-height: 300px; | ||
--fg-side-blur: | --fg-side-blur: 2px; | ||
--fg-side-opacity: | --fg-side-opacity: 0.55; | ||
--fg-accent:# | --fg-accent: #1473e6; | ||
--fg-card-bg:# | --fg-card-bg: #ffffff; | ||
--fg-image-bg:# | --fg-image-bg: #f5f7fa; | ||
--fg-caption-bg:# | --fg-caption-bg: #ffffff; | ||
--fg-caption-color:# | --fg-caption-color: #1f2937; | ||
position:relative; | |||
width:100% | position: relative; | ||
width: min(100%, 1240px); | |||
margin:28px auto; | margin: 28px auto; | ||
padding:0 | padding: 0 56px 42px; | ||
direction:rtl; | direction: rtl; | ||
font-family:iransans,Arial,sans-serif; | font-family: iransans, Arial, sans-serif; | ||
} | |||
.fgwiki-gallery__viewport{ | .fgwiki-gallery__viewport { | ||
width:100%; | width: 100%; | ||
overflow:hidden; | overflow: hidden; | ||
border-radius:var(--fg-radius); | border-radius: var(--fg-radius); | ||
touch-action:pan-y; | touch-action: pan-y; | ||
} | } | ||
.fgwiki-gallery__track{ | |||
display:flex; | .fgwiki-gallery__track { | ||
gap:var(--fg-gap); | display: flex; | ||
width:100% | flex-direction: row; | ||
gap: var(--fg-gap); | |||
transform:translate3d(0,0,0); | width: 100%; | ||
transition:transform | transform: translate3d(0, 0, 0); | ||
} | transition: transform 650ms cubic-bezier(0.22, 1, 0.36, 1); | ||
.fgwiki-gallery__slide{ | will-change: transform; | ||
flex:0 0 calc( | } | ||
.fgwiki-gallery__slide { | |||
flex: 0 0 calc( | |||
(100% - (var(--fg-items) - 1) * var(--fg-gap)) / var(--fg-items) | |||
); | ); | ||
min-width:0; | min-width: 0; | ||
margin:0; | margin: 0; | ||
overflow:hidden; | overflow: hidden; | ||
background:var(--fg-card-bg); | background: var(--fg-card-bg); | ||
border-radius:var(--fg-radius) | border: 1px solid rgba(0, 0, 0, 0.08); | ||
border-radius: var(--fg-radius); | |||
box-shadow:0 | box-shadow: 0 10px 28px rgba(0, 0, 0, 0.10); | ||
transition: | transition: | ||
transform 450ms ease, | |||
filter 450ms ease, | |||
opacity 450ms ease, | |||
box-shadow 450ms ease; | |||
} | } | ||
.fgwiki-gallery__slide img{ | |||
display:block; | .fgwiki-gallery__slide img { | ||
width:100%; | display: block; | ||
height:var(--fg-image-height); | width: 100%; | ||
padding:10px; | height: var(--fg-image-height); | ||
object-fit:contain; | padding: 10px; | ||
object-position:center | background: var(--fg-image-bg); | ||
object-fit: contain; | |||
border:0; | object-position: center; | ||
} | border: 0; | ||
.fgwiki-gallery__caption{ | } | ||
min-height: | |||
padding: | .fgwiki-gallery__caption { | ||
min-height: 72px; | |||
padding: 14px 16px 16px; | |||
font-size: | color: var(--fg-caption-color); | ||
font-weight:700; | background: var(--fg-caption-bg); | ||
line-height:1. | font-size: 14px; | ||
text-align:right; | font-weight: 700; | ||
} | line-height: 1.9; | ||
text-align: right; | |||
} | |||
.fgwiki-gallery__slide.is-center | |||
.fgwiki-gallery__slide | .fgwiki-gallery__slide:not(.is-center) { | ||
opacity:1; | filter: blur(var(--fg-side-blur)); | ||
opacity: var(--fg-side-opacity); | |||
transform: scale(0.94); | |||
} | } | ||
.fgwiki-gallery__button{ | .fgwiki-gallery__slide.is-center { | ||
position:absolute; | filter: none; | ||
top:50%; | opacity: 1; | ||
z-index:15 | transform: scale(1.03); | ||
box-shadow: 0 16px 36px rgba(20, 115, 230, 0.18); | |||
border-color: rgba(20, 115, 230, 0.18); | |||
display:flex; | } | ||
align-items:center; | |||
justify-content:center; | .fgwiki-gallery__button { | ||
padding:0; | position: absolute; | ||
border:0; | top: calc(50% - 24px); | ||
border-radius:50%; | z-index: 15; | ||
display: flex; | |||
align-items: center; | |||
font-size: | justify-content: center; | ||
width: 44px; | |||
height: 44px; | |||
transform:translateY(-50%); | padding: 0; | ||
transition: | color: #ffffff; | ||
} | background: rgba(17, 24, 39, 0.78); | ||
.fgwiki-gallery__button:hover{ | border: 0; | ||
background:var(--fg-accent); | border-radius: 50%; | ||
transform:translateY(-50%) scale(1.08); | box-shadow: 0 6px 18px rgba(0, 0, 0, 0.24); | ||
} | font-family: Arial, sans-serif; | ||
.fgwiki-gallery__button:focus-visible{ | font-size: 24px; | ||
outline:3px solid rgba( | line-height: 1; | ||
outline-offset:3px; | cursor: pointer; | ||
} | transform: translateY(-50%); | ||
.fgwiki-gallery__button--right{ | transition: | ||
right:0; | background-color 200ms ease, | ||
} | transform 200ms ease; | ||
.fgwiki-gallery__button--left{ | } | ||
left:0; | |||
} | .fgwiki-gallery__button:hover { | ||
background: var(--fg-accent); | |||
.fgwiki-gallery__dots{ | transform: translateY(-50%) scale(1.08); | ||
position:absolute; | } | ||
bottom:6px; | |||
.fgwiki-gallery__button:focus-visible { | |||
outline: 3px solid rgba(20, 115, 230, 0.30); | |||
gap:7px; | outline-offset: 3px; | ||
transform:translateX( | } | ||
} | |||
.fgwiki-gallery__dot{ | .fgwiki-gallery__button--right { | ||
width:9px; | right: 0; | ||
height:9px; | } | ||
padding:0; | |||
border:0; | .fgwiki-gallery__button--left { | ||
border-radius: | left: 0; | ||
} | |||
cursor:pointer; | |||
transition: | .fgwiki-gallery__dots { | ||
} | position: absolute; | ||
.fgwiki-gallery__dot.is-active{ | right: 50%; | ||
width:24px; | bottom: 6px; | ||
background:var(--fg-accent); | display: flex; | ||
} | align-items: center; | ||
.fgwiki-gallery__dot:focus-visible{ | justify-content: center; | ||
outline:2px solid var(--fg-accent); | gap: 7px; | ||
outline-offset:2px; | transform: translateX(50%); | ||
} | } | ||
@media ( | .fgwiki-gallery__dot { | ||
.fgwiki-gallery{ | width: 9px; | ||
height: 9px; | |||
padding: 0; | |||
background: #c7ced8; | |||
border: 0; | |||
border-radius: 50%; | |||
cursor: pointer; | |||
} | transition: | ||
width 250ms ease, | |||
background-color 250ms ease, | |||
opacity 250ms ease; | |||
} | |||
.fgwiki- | .fgwiki-gallery__dot.is-active { | ||
width: 24px; | |||
background: var(--fg-accent); | |||
border-radius: 999px; | |||
} | |||
} | .fgwiki-gallery__dot:focus-visible { | ||
outline: 2px solid var(--fg-accent); | |||
outline-offset: 2px; | |||
} | |||
.fgwiki-gallery__button{ | |||
@media (max-width: 900px) { | |||
.fgwiki-gallery { | |||
--fg-items: 2; | |||
} | --fg-image-height: 280px; | ||
} | --fg-side-blur: 1.5px; | ||
padding-right: 46px; | |||
@media ( | padding-left: 46px; | ||
.fgwiki-gallery{ | } | ||
.fgwiki-gallery__caption { | |||
min-height: 68px; | |||
font-size: 13px; | |||
} | |||
} | .fgwiki-gallery__button { | ||
.fgwiki-gallery__slide:not(.is-center){ | width: 40px; | ||
height: 40px; | |||
font-size: 21px; | |||
} | } | ||
.fgwiki- | } | ||
@media (max-width: 600px) { | |||
.fgwiki-gallery { | |||
} | --fg-items: 1; | ||
.fgwiki- | --fg-gap: 12px; | ||
--fg-image-height: 260px; | |||
--fg-side-blur: 0; | |||
} | --fg-side-opacity: 1; | ||
} | width: 100%; | ||
padding-right: 36px; | |||
@media (prefers-reduced-motion:reduce){ | padding-left: 36px; | ||
.fgwiki-gallery__track, | } | ||
.fgwiki-gallery__slide, | |||
.fgwiki-gallery__button, | .fgwiki-gallery__slide, | ||
.fgwiki-gallery__dot{ | .fgwiki-gallery__slide.is-center, | ||
.fgwiki-gallery__slide:not(.is-center) { | |||
} | filter: none; | ||
} | opacity: 1; | ||
transform: none; | |||
} | |||
.fgwiki-gallery__caption { | |||
min-height: 62px; | |||
padding: 12px 14px; | |||
font-size: 13px; | |||
line-height: 1.8; | |||
} | |||
.fgwiki-gallery__button { | |||
width: 34px; | |||
height: 34px; | |||
font-size: 18px; | |||
} | |||
} | |||
@media (prefers-reduced-motion: reduce) { | |||
.fgwiki-gallery__track, | |||
.fgwiki-gallery__slide, | |||
.fgwiki-gallery__button, | |||
.fgwiki-gallery__dot { | |||
transition: none; | |||
} | |||
} | |||
</style> | </style> | ||
<script> | <script> | ||
(function () { | (function () { | ||
"use strict"; | "use strict"; | ||
document.querySelectorAll(".fgwiki-gallery").forEach(function (slider) { | |||
const track = slider.querySelector(".fgwiki-gallery__track"); | document.querySelectorAll(".fgwiki-gallery").forEach(function (slider) { | ||
const track = slider.querySelector(".fgwiki-gallery__track"); | |||
const originalSlides = Array.from( | const originalSlides = Array.from( | ||
slider.querySelectorAll(".fgwiki-gallery__slide") | slider.querySelectorAll(".fgwiki-gallery__slide") | ||
); | ); | ||
const rightButton = slider.querySelector(".fgwiki-gallery__button--right"); | const rightButton = slider.querySelector(".fgwiki-gallery__button--right"); | ||
const leftButton = slider.querySelector(".fgwiki-gallery__button--left"); | const leftButton = slider.querySelector(".fgwiki-gallery__button--left"); | ||
const dotsContainer = slider.querySelector(".fgwiki-gallery__dots"); | const dotsContainer = slider.querySelector(".fgwiki-gallery__dots"); | ||
if ( | |||
!track || | if (!track || originalSlides.length === 0) { | ||
return; | |||
originalSlides.length === 0 | } | ||
){ | |||
return; | let currentIndex = 0; | ||
} | let autoPlayTimer = null; | ||
let touchStartX = 0; | |||
let touchEndX = 0; | |||
let isAnimating = false; | |||
const autoPlayDelay = 3500; | |||
let | |||
let | function getVisibleItems() { | ||
const value = getComputedStyle(slider) | |||
.getPropertyValue("--fg-items") | |||
.trim(); | |||
return Math.max(1, parseInt(value, 10) || 1); | |||
} | |||
function cleanupClones() { | |||
Array.from(track.querySelectorAll(".is-clone")).forEach(function (node) { | |||
node.remove(); | |||
}); | |||
} | |||
const | function buildInfiniteTrack() { | ||
cleanupClones(); | |||
. | |||
const visibleItems = getVisibleItems(); | |||
); | const slides = Array.from(track.children).filter(function (slide) { | ||
return !slide.classList.contains("is-clone"); | |||
}); | |||
const prependClones = slides.slice(-visibleItems).map(function (slide) { | |||
const clone = slide.cloneNode(true); | |||
. | clone.classList.add("is-clone"); | ||
clone.setAttribute("aria-hidden", "true"); | |||
return clone; | |||
}); | |||
const appendClones = slides.slice(0, visibleItems).map(function (slide) { | |||
function | const clone = slide.cloneNode(true); | ||
clone.classList.add("is-clone"); | |||
clone.setAttribute("aria-hidden", "true"); | |||
return clone; | |||
}); | |||
}); | prependClones.forEach(function (clone) { | ||
track.insertBefore(clone, track.firstChild); | |||
}); | |||
appendClones.forEach(function (clone) { | |||
track.appendChild(clone); | |||
}); | |||
return | |||
}) | currentIndex = visibleItems; | ||
const | updateSlider(false); | ||
} | |||
. | |||
function getAllSlides() { | |||
return Array.from(track.querySelectorAll(".fgwiki-gallery__slide")); | |||
} | |||
function getRealSlidesCount() { | |||
return originalSlides.length; | |||
} | |||
function getSlideStep() { | |||
const slides = getAllSlides(); | |||
if (slides.length < 2) { | |||
return slides[0] ? slides[0].getBoundingClientRect().width : 0; | |||
} | |||
function | |||
const firstSlide = slides[0].getBoundingClientRect(); | |||
const secondSlide = slides[1].getBoundingClientRect(); | |||
); | |||
return Math.abs(secondSlide.left - firstSlide.left); | |||
} | |||
function | |||
const | function updateDots() { | ||
const visibleItems = getVisibleItems(); | |||
const realSlidesCount = getRealSlidesCount(); | |||
const maxDotIndex = Math.max(0, realSlidesCount - visibleItems); | |||
const realIndex = ((currentIndex - visibleItems) % realSlidesCount + realSlidesCount) % realSlidesCount; | |||
const | const activeDotIndex = Math.min(realIndex, maxDotIndex); | ||
const dots = dotsContainer.querySelectorAll(".fgwiki-gallery__dot"); | |||
); | dots.forEach(function (dot, index) { | ||
const isActive = index === activeDotIndex; | |||
dot.classList.toggle("is-active", isActive); | |||
dot.setAttribute("aria-current", isActive ? "true" : "false"); | |||
}); | |||
} | |||
function updateCenterState() { | |||
}else{ | const visibleItems = getVisibleItems(); | ||
track.style.transition=""; | const centerOffset = Math.floor(visibleItems / 2); | ||
} | const centerIndex = currentIndex + centerOffset; | ||
const slides = getAllSlides(); | |||
track.style.transform = | |||
"translate3d("+offset+"px,0,0)"; | slides.forEach(function (slide, index) { | ||
if( | slide.classList.toggle("is-center", index === centerIndex); | ||
requestAnimationFrame(function(){ | }); | ||
} | |||
}); | |||
} | function updateSlider(animate) { | ||
} | const step = getSlideStep(); | ||
const offset = currentIndex * step; | |||
const | if (!animate) { | ||
track.style.transition = "none"; | |||
} else { | |||
}) | track.style.transition = ""; | ||
} | |||
track.style.transform = "translate3d(" + offset + "px, 0, 0)"; | |||
updateDots(); | |||
updateCenterState(); | |||
} | |||
if (!animate) { | |||
requestAnimationFrame(function () { | |||
requestAnimationFrame(function () { | |||
track.style.transition = ""; | |||
}); | |||
}); | |||
} | |||
} | |||
( | |||
( | function jumpIfNeeded() { | ||
const visibleItems = getVisibleItems(); | |||
) | const realSlidesCount = getRealSlidesCount(); | ||
) | if (currentIndex >= realSlidesCount + visibleItems) { | ||
currentIndex = visibleItems; | |||
updateSlider(false); | |||
} else if (currentIndex < visibleItems) { | |||
currentIndex = realSlidesCount + visibleItems - 1; | |||
); | updateSlider(false); | ||
} | |||
const | |||
updateCenterState(); | |||
updateDots(); | |||
} | |||
); | |||
function goToSlide(index) { | |||
" | if (isAnimating) { | ||
return; | |||
} | |||
isAnimating = true; | |||
currentIndex = index; | |||
updateSlider(true); | |||
window.setTimeout(function () { | |||
jumpIfNeeded(); | |||
isAnimating = false; | |||
}, 680); | |||
} | |||
function moveRight() { | |||
goToSlide(currentIndex + 1); | |||
} | |||
} | |||
function moveLeft() { | |||
goToSlide(currentIndex - 1); | |||
} | |||
function createDots() { | |||
( | const visibleItems = getVisibleItems(); | ||
( | const dotsCount = Math.max(1, getRealSlidesCount() - visibleItems + 1); | ||
) | dotsContainer.innerHTML = ""; | ||
for (let index = 0; index < dotsCount; index += 1) { | |||
const dot = document.createElement("button"); | |||
dot.type = "button"; | |||
dot.className = "fgwiki-gallery__dot"; | |||
dot.setAttribute("aria-label", "نمایش اسلاید شماره " + (index + 1)); | |||
} | |||
} | dot.addEventListener("click", function () { | ||
currentIndex = getVisibleItems() + index; | |||
updateSlider(true); | |||
restartAutoPlay(); | |||
}); | |||
dotsContainer.appendChild(dot); | |||
} | |||
updateDots(); | |||
} | } | ||
function startAutoPlay() { | |||
stopAutoPlay(); | |||
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) { | |||
return; | |||
} | |||
autoPlayTimer = window.setInterval(function () { | |||
function | moveRight(); | ||
if( | }, autoPlayDelay); | ||
} | |||
} | |||
function stopAutoPlay() { | |||
if (autoPlayTimer !== null) { | |||
window.clearInterval(autoPlayTimer); | |||
} | autoPlayTimer = null; | ||
} | |||
} | |||
} | function restartAutoPlay() { | ||
stopAutoPlay(); | |||
startAutoPlay(); | |||
} | |||
rightButton.addEventListener("click", function () { | |||
moveRight(); | |||
restartAutoPlay(); | |||
}); | |||
leftButton.addEventListener("click", function () { | |||
moveLeft(); | |||
restartAutoPlay(); | |||
} | }); | ||
slider.addEventListener("mouseenter", stopAutoPlay); | |||
} | slider.addEventListener("mouseleave", startAutoPlay); | ||
slider.addEventListener("focusin", stopAutoPlay); | |||
}); | slider.addEventListener("focusout", function (event) { | ||
if (!slider.contains(event.relatedTarget)) { | |||
startAutoPlay(); | |||
} | |||
}); | |||
slider.addEventListener( | |||
} | "touchstart", | ||
function (event) { | |||
touchStartX = event.changedTouches[0].clientX; | |||
touchEndX = touchStartX; | |||
stopAutoPlay(); | |||
); | }, | ||
{ passive: true } | |||
); | |||
slider.addEventListener( | |||
"touchmove", | |||
function (event) { | |||
touchEndX = event.changedTouches[0].clientX; | |||
}, | |||
{ passive: true } | |||
); | |||
slider.addEventListener( | |||
"touchend", | |||
function () { | |||
const swipeDistance = touchEndX - touchStartX; | |||
if (Math.abs(swipeDistance) > 45) { | |||
if (swipeDistance > 0) { | |||
moveRight(); | |||
} else { | |||
moveLeft(); | |||
} | |||
} | |||
startAutoPlay(); | |||
}, | |||
{ passive: true } | |||
); | |||
window.addEventListener("resize", function () { | |||
buildInfiniteTrack(); | |||
createDots(); | |||
}); | |||
if ("IntersectionObserver" in window) { | |||
const observer = new IntersectionObserver( | |||
function (entries) { | |||
entries.forEach(function (entry) { | |||
if (entry.isIntersecting) { | |||
startAutoPlay(); | |||
} else { | |||
stopAutoPlay(); | |||
} | |||
}); | |||
}, | |||
{ | |||
threshold: 0.2 | |||
} | |||
); | |||
observer.observe(slider); | |||
} else { | |||
startAutoPlay(); | |||
} | |||
buildInfiniteTrack(); | |||
createDots(); | |||
}); | |||
})(); | |||
}); | |||
})(); | |||
</script> | </script> | ||
</html> | </html> | ||
نسخهٔ ۶ اوت ۲۰۲۶، ساعت ۰۸:۲۹