【スワイパー】画像ズームインアニメーション
【Swiper 使用手順】
◎参考URL
公式のここを見る
◎レイアウトデモ
参考URL:https://lightning-g3.hp1.work/full-screen-zoom-in-fade-slider/
◆まとめ◆
JavaScriptは、スライドが切り替わる前後のズームインの動きを調整し、スムーズな動きを作り出します。
CSS は、フェードイン・アウトのタイミングとズームインの速度を調整し、画像が自然にズームイン・アウトするように制御しています。
ドンっと切り替わる問題の解消:
前のスライドのアニメーションをリセットせず、ズームインを継続させることで、スライド切り替え時に画像が急に縮小する現象を防ぎました。
なぜスライド切り替え時に画像が「ドン」となるのか
原因:
アニメーションのリセット: スライドが切り替わる際、以前のコードでは前のスライドのアニメーションをリセットしていました。これにより、次のスライドに移行したとき、画像のスケールが初期状態に戻ってしまい、画面上で画像が急に縮小されるように見えていました。
対処法:
アニメーションをリセットしない: JavaScriptのslideChangeTransitionStartイベントで、前のスライドのアニメーションをリセットする処理を削除しました。これにより、ズームインアニメーションが継続し、スライドが切り替わっても画像が急に縮小することなく、スムーズに表示されます。
ーーーーーーーーーーーーーーーーー
画角の統一:
全ての画像の初期スケールをscale(1)に統一し、ズームインの範囲もscale(1)からscale(1.2)に統一することで、ズームイン開始前と完了後の画角の差異を解消しました。
スムーズな切り替えの実現:
アニメーション時間を12秒、スライドの切り替えを4秒に設定し、ズームインアニメーションがスライドをまたいで継続するようにしました。
アニメーションの開始タイミングを調整し、スライドが切り替わってすぐにズームインが始まるようにしました。
問題:
画角の不一致: 画像の初期スケールとズームイン後のスケールが異なるため、ズームインの開始時と終了時で画角が変わり、違和感が生じていました。
対処法:
画像の初期スケールを統一: CSSで全ての画像にtransform: scale(1);を設定し、画像の初期状態を等倍(スケール1)に統一しました。
ズームインの範囲を明確に設定:
@keyframes zoom-inで、アニメーションの開始と終了のスケールをscale(1)からscale(1.2)に設定しました。これにより、全ての画像が同じ範囲でズームインし、画角の不一致が解消されました。
ーーーーーーーーーーーーーーーーーーーーーーー
3. 理想URLのようにスムーズに切り替わるように調整した箇所
問題:
アニメーションのタイミングのずれ: スライドが切り替わった後、アニメーションが始まるまでに一呼吸置くような間があり、スムーズな切り替えになっていませんでした。
対処法:
アニメーションの開始タイミングを調整:
・JavaScriptのslideChangeTransitionEndイベントで、新しいスライドのアニメーションを即座に開始するようにしました。
・前のスライドのアニメーションをリセットせず、ズームインを継続させることで、スライド切り替え時の違和感を解消しました。
アニメーション時間の調整:
アニメーションの時間を12秒、スライドの切り替えを4秒に設定しました。これにより、ズームインアニメーションがスライドの切り替えをまたいで継続し、全体として滑らかな動きを実現しました。
ベースHTML
構造説明:
- hero-section: 全体を包むセクション。
- wrapper: コンテンツを包むラッパー。
- hero-content: ロゴやテキストを含む部分。
- swiper-container-4: スライダーのコンテナ。
- swiper-slide: 各スライドを表す。
<!-- ヒーローセクション -->
<section class="hero-section">
<div class="wrapper">
<div class="hero-content">
<div class="hero-inner-content">
<img class="hero-logo" src="https://recure.life/wp-content/uploads/2022/08/gen_logo-1.png">
</div>
<div class="hero-inner-content">
<h2>美と健康</h2>
<p class="left">テキストテキストテキスト</p>
</div>
</div>
<div class="swiper-wrap">
<div class="swiper-container-4">
<div class="swiper-wrapper">
<div class="swiper-slide">
<div class="slide-img">
<img src="https://recure.life/wp-content/uploads/2024/09/A7301016.jpg">
</div>
<div class="slide-text">テスト1</div>
</div>
<div class="swiper-slide">
<div class="slide-img">
<img src="https://recure.life/wp-content/uploads/2024/09/A7300539.jpg">
</div>
<div class="slide-text">テスト2</div>
</div>
</div>
</div>
</div>
</div>
</section>
1. WPで読み込む場合、functions.phpに下記を入れる
function enqueue_swiper_resources() {
// SwiperのCSSファイルを読み込む
wp_enqueue_style( 'swiper-css', 'https://unpkg.com/swiper@9/swiper-bundle.min.css', array(), null );
// SwiperのJavaScriptファイルを読み込む
wp_enqueue_script( 'swiper-js', 'https://unpkg.com/swiper@9/swiper-bundle.min.js', array(), null, true );
// 子テーマのJavaScriptファイルを読み込む
wp_enqueue_script( 'child-custom-js', get_stylesheet_directory_uri() . '/js/javascript.js', array('swiper-js'), null, true );
}
add_action( 'wp_enqueue_scripts', 'enqueue_swiper_resources' );
ーーーーーーーーーーーーーーーーーーーーーーーーー
2. JSファイルに下記記述を追加
JS説明
slideChangeTransitionStart:スライドが切り替わる前に、ズーム状態をリセットします。
つまり、スライドの画像を元の大きさに戻します。これにより、次のスライドで「急にズームが戻る」という不自然な動きが防げます。
slideChangeTransitionEnd:スライドが切り替わった後に、ズームインを少し遅れて開始します。
0.1秒遅らせてからズームインを開始することで、スライドが切り替わってから自然な形でズームが始まります。
・loop: true: スライダーを無限ループさせる。
・effect: 'fade': スライド切り替え時にフェード効果を適用。
・autoplay:
・delay: 4000: 4秒ごとにスライドを自動的に切り替える。
・disableOnInteraction: false: ユーザーが操作しても自動再生を停止しない。
・speed: 1200: スライドの切り替えに1.2秒かける。
・イベントハンドラon:
・initイベント:
スライダーが初期化されたときに、最初のスライドの画像にズームインアニメーションを適用。
・slideChangeTransitionStartイベント:
ここでは特に処理を行わない。前のスライドのアニメーションをリセットしないため、ズームインが継続する。
・slideChangeTransitionEndイベント:
新しいスライドの画像にズームインアニメーションを再度適用。
let swiperOption = {
loop: true,
effect: 'fade',
autoplay: {
delay: 4000, // スライドの切り替えは4秒ごと
disableOnInteraction: false,
},
speed: 1200, // スライド切り替え速度
pagination: {
el: '.swiper-pagination',
clickable: true,
},
on: {
init: function() {
// 初期スライドのアニメーションを開始
$('.swiper-slide-active img').css('animation', 'zoom-in 12s linear forwards');
},
slideChangeTransitionStart: function() {
// 前のスライドのアニメーションをリセットせず、ズームインを継続。(!!ドンってなるのここ!!)
},
slideChangeTransitionEnd: function() {
// 新しいスライドのアニメーションを開始
$('.swiper-slide-active img').css('animation', 'zoom-in 12s linear forwards');
}
}
}
new Swiper('.swiper-container-4', swiperOption);
ーーーーーーーーーーーーーーーーーーーーーーーー
3. CSSにてアニメーションを追加
詳細説明:
.swiper-slideと.swiper-slide-activeでスライドのフェード効果を設定。非アクティブなスライドは透明(opacity: 0)、アクティブなスライドは不透明(opacity: 1)。
画像の初期設定:
width: 100%;とheight: 100%;で画像がコンテナ全体を覆うように設定。
object-fit: cover;で画像が縦横比を維持しながらコンテナを埋める。
object-position: center center;で画像の中央を表示。
transform: scale(1);で画像の初期スケールを1に設定。
ズームインアニメーションの適用:
アクティブなスライドの画像に対して、animation: zoom-in 12s linear forwards;を適用。
zoom-inというキーフレームを12秒間かけて実行し、線形(一定速度)でアニメーションを進行。
ズームインのキーフレーム定義:
from(0%)でtransform: scale(1);、to(100%)でtransform: scale(1.2);。
画像がスケール1から1.2へ12秒かけてゆっくり拡大。
非アクティブなスライドの画像のスケールをリセット:
非アクティブなスライドの画像は常にtransform: scale(1);でスケール1を維持。
/* 新ファーストビュー テスト -----------------------*/
.page-id-15048 .wrapper {
display: flex;
justify-content: space-between;
align-items: center;
}
.page-id-15048 .slide {
max-width: 800px;
width: 100%;
height: auto;
}
.page-id-15048 .metaslider img {
max-width: 700px !important;
height: 580px !important;
object-fit: cover;
width: 100%;
}
.page-id-15048 .hero-logo {
max-width: 400px;
}
.hero-content {
max-width: 400px;
width: 100%;
}
.hero-inner-content {
text-align: center;
}
.hero-section .left {
text-align: left;
}
.swiper-wrap {
margin: 0 calc(52% - 50vw);
max-width: 57vw;
position: relative;
overflow: hidden;
}
.slide-text {
position: absolute;
top: 50%;
left: 50%;
font-size: 3vw;
font-family: serif;
font-weight: bold;
text-shadow: 2px 2px 8px #000;
color: #fff;
transform: translate(-50%, -50%);
}
/* スライド全体にフェード効果を適用 */
.swiper-slide {
opacity: 0;
transition: opacity 1.2s ease-in-out;
}
.swiper-slide-active {
opacity: 1;
}
* 画像の初期設定を統一 */
.swiper-slide img {
width: 100%;
height: 100%;
object-fit: cover;
object-position: center center;
transform: scale(1);
}
/* アクティブなスライドの画像にズームインアニメーションを適用 */
.swiper-slide-active img {
animation: zoom-in 12s linear forwards;
}
/* ズームインのキーフレーム */
@keyframes zoom-in {
0% {
transform: scale(1.1);
}
100% {
transform: scale(1.2);
}
}
/* 非アクティブなスライドの画像のスケールをリセット */
.swiper-slide:not(.swiper-slide-active) img {
transform: scale(1);
}
画像のループ
<div class="scroll-infinity">
<div class="scroll-infinity__wrap">
<ul class="scroll-infinity__list scroll-infinity__list--left">
<li class="scroll-infinity__item"><img src="sample.png" /></li>
<li class="scroll-infinity__item"><img src="sample.png" /></li>
<li class="scroll-infinity__item"><img src="sample.png" /></li>
<li class="scroll-infinity__item"><img src="sample.png" /></li>
<li class="scroll-infinity__item"><img src="sample.png" /></li>
<li class="scroll-infinity__item"><img src="sample.png" /></li>
</ul>
<ul class="scroll-infinity__list scroll-infinity__list--left">
<li class="scroll-infinity__item"><img src="sample.png" /></li>
<li class="scroll-infinity__item"><img src="sample.png" /></li>
<li class="scroll-infinity__item"><img src="sample.png" /></li>
<li class="scroll-infinity__item"><img src="sample.png" /></li>
<li class="scroll-infinity__item"><img src="sample.png" /></li>
<li class="scroll-infinity__item"><img src="sample.png" /></li>
</ul>
</div>
</div>
@keyframes infinity-scroll-left {
from {
transform: translateX(0);
}
to {
transform: translateX(-100%);
}
}
.scroll-infinity__wrap {
display: flex;
overflow: hidden;
}
.scroll-infinity__list {
display: flex;
list-style: none;
margin: 0;
padding: 0;
animation: infinity-scroll-left 15s infinite linear;
/* リスト全体の幅を確保するため、リスト1と2の内容を連続で移動 */
width: calc(100vw * 2);
}
.scroll-infinity__item {
flex-shrink: 0;
width: calc(100vw / 4); /* 各アイテムの幅 */
}
.scroll-infinity__item img {
width: 80%;
padding: 3rem ;
}
スワイパー 両端が映らない
おそらくV9以降のバグなので、以下のページを参考にswiperのバージョンをV8に変更する。
◎loop指定時に余白ができてしまう(コピーが追い付かない)問題は
以下の回答にあるように、Swiperの仕様っぽいです。