Splideでcoverflowするメモ
Swiperのエフェクト使いたいけどSplideの方がスライダーとして安心感があるのよね。Splide.jsでSwiperの「Effect coverflow」をやる時のためのメモ。
class PhotoGallery {
constructor(el) {
const slides = el.querySelectorAll('.splide__slide');
this.splide = new Splide(el, {
type: 'slide',
focus: 'center',
trimSpace: false,
arrows: false,
pagination: false,
flickPower: 80,
fixedWidth: 320,
audoWidth: true,
});
this.slideData = {};
window.addEventListener('resize', () => {
if (this.timer !== false) clearTimeout(this.timer);
this.timer = setTimeout(() => {
this.init();
}, 200);
});
this.splide.mount();
this.init();
this.tick();
}
init() {
// スライドひとつひとつのX位置を保持
const slides = this.splide.Components.Slides.get();
slides.forEach((slide, index) => {
const rect = slide.slide.getBoundingClientRect();
const slidePosition = rect.left - (window.innerWidth - slide.slide.clientWidth) / 2;
this.slideData[index] = {
position: slidePosition,
};
});
// スライダーの基準位置を保持
this.basisPos = this.splide.Components.Move.getPosition();
this.moving();
}
tick() {
if ( !this.splide.state.is( Splide.STATES.IDLE ) ) {
// Splideが動いてる時だけ実行
this.moving();
}
this.ticker = requestAnimationFrame(() => { this.tick(); });
}
moving() {
// 基準位置と現在位置との差分
const diffPos = Math.round( this.basisPos - this.splide.Components.Move.getPosition() );
const slides = this.splide.Components.Slides.get();
slides.forEach((slide, index) => {
const diff = diffPos - this.slideData[index].position;
// 差分を角度に利用
const rotate = diff * .08;
slide.slide.style.setProperty('--rotate', rotate + 'deg');
// スライドの中の画像をパララックス的にズラす
const shift = diff * -.08;
slide.slide.style.setProperty('--shift', shift);
});
}
}
`loop`だとループするところでちょっと誤差が出るので`slide`にした方が良い(改良の余地)。
.splide__track {
padding-block: 24px;
}
.splide__slide {
display: grid;
place-content: center;
aspect-ratio: 1 / 1;
overflow: hidden;
transform: perspective(1000px) rotate3d(0, 1, 0, var(--rotate, 0deg));
will-change: transform;
}
.splide__slide img {
width: auto;
height: 320px;
object-fit: cover;
transform: translate3d(calc(var(--shift, 0px) * 1px), 0, 0);
}
スライドが横回転して手前に飛び出す分、トラック上下にパディングして見切れを回避。JavaScriptで更新するCSS変数をそれぞれ要素に適用。