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変数をそれぞれ要素に適用。


いいなと思ったら応援しよう!