vue3 に animate.css を適用しアニメーションさせる
2024/04/29 00:00:00
前提 #
- 動作環境は git-bash とする
構築手順は以下を参考にする
https://blog.oya3.net/posts/2023/10/03/00_git/ - node21 + vite5 + vue3 + bootstrap5 + sass を使用する
構築手順は以下を参考にする
http://blog.oya3.net/posts/2024/04/27/vite-vue-bootstrap-sass/ - animte.css で以下を実現する
- カルーセル時にキャプションを移動させる
- スクロールに合わせてアニメーションさせる
animate.css をインストールする #
$ npm install animate.css
animate.css を vue3 で使えるようにする #
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import './scss/styles.scss'
import 'animate.css/animate.min.css'; // 追加
import * as bootstrap from 'bootstrap'
const app = createApp(App)
app.use(router)
app.mount('#app')
カルーセル時にキャプションを移動させる #
カルーセルのベースソースは以下の公式サイトを参考にする
https://getbootstrap.jp/docs/5.3/components/carousel/
- carousel 機能で3秒後にスライドを実行し続ける
<div id="carouselTop" class="carousel slide" data-bs-ride="carousel" data-bs-interval="3000">
- animate.css でスライドに合わせてキャプションをフェードインさせる
<p class="fs-1 fw-bold animate__animated animate__fadeInDown">Welcome to Mamba</p> <p class="animate__animated animate__fadeInUp animation-delay-04">説明1説明1説明1説明1説明1説明1説明1説明1説明1説明1説明1説明1説明1説明1説明1説明1説明1説明1説明1説明1説明1説明1</p> <button class="btn btn-primary animate__animated animate__fadeInUp animation-delay-08">詳細</button>
- animate__animated animate__fadeInDown
上から下に移動してくるアニメーション - animate__animated animate__fadeInUp
下から上に移動してくるアニメーション - animation-delay-04
animation-delay-08 も同じくアニメーションを遅延させる設定$emacs src/scss/styles.scss
animation-delay: 0.4s; // 0.4秒後にアニメーション animation-delay: 0.8s; // 0.4秒後にアニメーション
- animate__animated animate__fadeInDown
以下、サンプルコードまとめ
- 画像パスは適当に合わせる必要がある
$ emacs src/components/home.vue
...
<div id="carouselTop" class="carousel slide" data-bs-ride="carousel" data-bs-interval="3000">
<div class="carousel-indicators">
<button type="button" data-bs-target="#carouselTop" data-bs-slide-to="0" class="active" aria-current="true" aria-label="Slide 1"></button>
<button type="button" data-bs-target="#carouselTop" data-bs-slide-to="1" aria-label="Slide 2"></button>
<button type="button" data-bs-target="#carouselTop" data-bs-slide-to="2" aria-label="Slide 3"></button>
</div>
<div class="carousel-inner">
<div class="carousel-item active">
<img src="../assets/images/slides/slide-1.jpg" class="d-block w-100">
<div class="carousel-caption ">
<p class="fs-1 fw-bold animate__animated animate__fadeInDown">Welcome to Mamba</p>
<p class="animate__animated animate__fadeInUp animation-delay-04">説明1説明1説明1説明1説明1説明1説明1説明1説明1説明1説明1説明1説明1説明1説明1説明1説明1説明1説明1説明1説明1説明1</p>
<button class="btn btn-primary animate__animated animate__fadeInUp animation-delay-08">詳細</button>
</div>
</div>
<div class="carousel-item">
<img src="../assets/images/slides/slide-2.jpg" class="d-block w-100">
<div class="carousel-caption ">
<p class="fs-1 fw-bold animate__animated animate__fadeInDown">Lorem Ipsum Dolor</p>
<p class="animate__animated animate__fadeInUp animation-delay-04">説明2説明2説明2説明2説明2説明2説明2説明2説明2説明2説明2説明2説明2説明2説明2説明2説明2説明2説明2説明2説明2説明2</p>
<button class="btn btn-primary animate__animated animate__fadeInUp animation-delay-08">詳細</button>
</div>
</div>
<div class="carousel-item">
<img src="../assets/images/slides/slide-3.jpg" class="d-block w-100">
<div class="carousel-caption ">
<p class="fs-1 fw-bold animate__animated animate__fadeInDown">Sequi ea ut et est quaerat</p>
<p class="animate__animated animate__fadeInUp animation-delay-04">説明3説明3説明3説明3説明3説明3説明3説明3説明3説明3説明3説明3説明3説明3説明3説明3説明3説明3説明3説明3説明3説明3</p>
<button class="btn btn-primary animate__animated animate__fadeInUp animation-delay-08">詳細</button>
</div>
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carouselTop" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#carouselTop" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
...
$ emacs src/scss/styles.scss
...
.animation-delay-04{
animation-delay: 0.4s;
}
.animation-delay-08{
animation-delay: 0.8s;
}
...
スクロールに合わせてアニメーションさせる #
bootstrapのカードをスクロールで画面内に入ってきた時にフェードインしてくるアニメーションを作成する
カードのベースソースは以下の公式サイトを参考にする
https://getbootstrap.jp/docs/5.3/components/card/
- 指定したカードが画面内に入ってきた時にフェードインする設定
独自に作成した scrollFadeIn クラスを指定<div class="container animate__animated scrollFadeIn">
- 独自に作成した scrollFadeIn クラスを作成
.scrollFadeIn{ animation-delay: 0.2s; // 0.2秒後に発火 }
- scrollFadeIn クラスが画面内に入った場合、フェードインアニメーション発火
const animation = 'animate__fadeInUp'; // 実行するアニメーション名 const animateClass = '.scrollFadeIn'; // 複数の要素を選択するセレクター const elements = ref([]); // Intersection Observer のコールバック関数 const handleIntersection = (entries, observer) => { entries.forEach((entry) => { if (entry.isIntersecting) { // 要素が画面内に入ったら fadeinup アニメーションを追加 entry.target.classList.add(animation); // Intersection Observer を解除 observer.unobserve(entry.target); } }); }; // Intersection Observer の作成 const observer = new IntersectionObserver(handleIntersection); // 要素を監視 onMounted(() => { elements.value = document.querySelectorAll(animateClass); elements.value.forEach((el) => observer.observe(el)); }); // アニメーションが終了したらクラスを削除 elements.value.forEach((el) => { el.addEventListener('animationend', () => { el.classList.remove(animation); }); });
以下、サンプルコードまとめ
$ emacs src/components/home.vue
<template>
...
<hr>
<br>
<div class="container animate__animated scrollFadeIn">
<div class="card" style="width: 18rem;">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
<a href="#" class="btn btn-primary">Go somewhere</a>
</div>
</div>
</div>
...
</template>
<script setup>
import { ref, onMounted } from 'vue';
const animation = 'animate__fadeInUp'; // 実行するアニメーション名
const animateClass = '.scrollFadeIn'; // 複数の要素を選択するセレクター
const elements = ref([]);
// Intersection Observer のコールバック関数
const handleIntersection = (entries, observer) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
// 要素が画面内に入ったら fadeinup アニメーションを追加
entry.target.classList.add(animation);
// Intersection Observer を解除
observer.unobserve(entry.target);
}
});
};
// Intersection Observer の作成
const observer = new IntersectionObserver(handleIntersection);
// 要素を監視
onMounted(() => {
elements.value = document.querySelectorAll(animateClass);
elements.value.forEach((el) => observer.observe(el));
});
// アニメーションが終了したらクラスを削除
elements.value.forEach((el) => {
el.addEventListener('animationend', () => {
el.classList.remove(animation);
});
});
</script>
$ emacs src/scss/styles.scss
...
.scrollFadeIn{
animation-delay: 0.2s; // 0.2秒後に発火
}
...
参考URL #
- Animate.css
https://animate.style/#javascript - bootstrap carousel
https://getbootstrap.jp/docs/5.3/components/carousel/ - bootstrap card
https://getbootstrap.jp/docs/5.3/components/card/