【更新日 : 】
【脱Jquery】javascriptでフェード系アニメーション(fadeIn、fadeOut、fadeToggle)を実装する
Category: JavaScript
Tags: JavaScript, Vanilla JS, アニメーション, フェード, 脱Jquery, 自作関数
Vanilla JSでフェード系アニメーション(fadeIn、fadeOut、fadeToggle)を実装したサンプルです。
イージング編集と、コールバック関数に対応させました。
See the Pen
fadeIn fadeOut fadeToggle Vanilla JS (Easing support) by Kazuma Sakata (@sakata-kazuma)
on CodePen.
JS
/*
■fadeIn・fadeOut・fadeToggleアニメーション処理関数
animeType: 'fadeIn' or 'fadeOut' or 'fadeToggle'
elm: 対象要素
duration: アニメーション時間
[callBack: コールバック関数(任意)]
*/
function fadeAnime(animeType, elm, duration, callBack) {
'use strict';
//fadeToggle分岐
if (animeType === 'fadeToggle') {
animeType = getComputedStyle(elm).display === 'none' ? 'fadeIn' : 'fadeOut';
}
//既に表示されている or 実行中だった場合は処理しない
if (
//fadeIn 既に表示されている or 実行中だった場合は処理しない
(animeType === 'fadeIn' && (getComputedStyle(elm).display !== 'none' || elm.classList.contains('is-fade-busy')))
//fadeOut 既に非表示 or 実行中だった場合は処理しない
|| (animeType === 'fadeOut' && (getComputedStyle(elm).display === 'none' || elm.classList.contains('is-fade-busy')))
//有効なキーワードではない場合も処理しない
|| (animeType !== 'fadeIn' && animeType !== 'fadeOut')
) {
return false;
}
//重複処理対策class追加
elm.classList.add('is-fade-busy');
/*
イージング設定
・参考サイト
https://github.com/danro/jquery-easing/blob/master/jquery.easing.js
https://noze.space/archives/432#index-3
「t:アニメーションの経過時間」「b:始点」「c:変化量」「d:変化にかける時間」
*/
function easing(t, b, c, d) {
return c * (0.5 - Math.cos((t / d) * Math.PI) / 2) + b;
}
//アニメーション分岐
let fadeFunc = null;
if(animeType === 'fadeOut') {
//初期設定
elm.style.opacity = 1;
//アニメーション関数設定
fadeFunc = function(elapsedTime,duration) {
//easing(「アニメーションの経過時間」,「始点」,「変化量」,「変化にかける時間」)
return 1 - easing(elapsedTime, 0, 1, duration);
}
} else if(animeType === 'fadeIn') {
//初期設定
elm.style.display = 'block';
elm.style.opacity = 0;
//アニメーション関数設定
fadeFunc = function(elapsedTime,duration) {
//easing(「アニメーションの経過時間」,「始点」,「変化量」,「変化にかける時間」)
return easing(elapsedTime, 0, 1, duration);
}
}
//アニメーション開始時間
const start = new Date();
function mainAnime() {
//イベント発生後の経過時間
let elapsedTime = new Date() - start;
//アニメーション終了処理
if (elapsedTime > duration) {
//opacity削除
elm.style.removeProperty('opacity');
//実行中class削除
elm.classList.remove('is-fade-busy');
if(animeType === 'fadeOut') {
//要素を非表示
elm.style.display = 'none';
}
//コールバック関数が設定されていたら呼び出す
if(typeof callBack === 'function') {
callBack();
}
//処理を終了
return false;
}
//アニメーション実行処理
elm.style.opacity = fadeFunc(elapsedTime,duration);
requestAnimationFrame(mainAnime);
}
//アニメーション初回呼び出し
requestAnimationFrame(mainAnime, callBack);
}
関数の呼び出し
任意の場所で以下を実行し関数を呼び出してください。
//フェードイン
fadeAnime('fadeIn', 対象要素, アニメーション時間 [, コールバック関数(任意)]);
//フェードアウト
fadeAnime('fadeOut', 対象要素, アニメーション時間 [, コールバック関数(任意)]);
//フェードイン・アウトテスト
fadeAnime('fadeToggle', 対象要素, アニメーション時間 [, コールバック関数(任意)]);
動作サンプル
HTML
<button id="js-fade-in">fadeIn</button>
<div class="js-fade-in-elm">fadeIn要素</div>
<button id="js-fade-out">fadeOut</button>
<div class="js-fade-out-elm">fadeOut要素</div>
<button id="js-fade-toggle">fadeToggle</button>
<div class="js-fade-toggle-elm">fadeToggle要素</div>
CSS
/* fadeIn用設定 */
.js-fade-in-elm {
display: none;
}
JS
//フェードインテスト
const fadeInElm = document.querySelector('.js-fade-in-elm');
document.getElementById('js-fade-in').addEventListener('click', function() {
/*
・フェードイン呼び出し
fadeAnime('fadeIn', 対象要素, アニメーション時間 [, コールバック関数(任意)]);
*/
fadeAnime('fadeIn', fadeInElm, 400, function() {
console.log('fadeIn終了');
});
});
//フェードアウトテスト
const fadeOutElm = document.querySelector('.js-fade-out-elm');
document.getElementById('js-fade-out').addEventListener('click', function() {
/*
・フェードアウト呼び出し
fadeAnime('fadeOut', 対象要素, アニメーション時間 [, コールバック関数(任意)]);
*/
fadeAnime('fadeOut', fadeOutElm, 400, function() {
console.log('fadeOut終了');
});
});
//フェードイン・アウトテスト
const fadeToggleElm = document.querySelector('.js-fade-toggle-elm');
document.getElementById('js-fade-toggle').addEventListener('click', function() {
/*
・フェードイン・アウト呼び出し
fadeAnime('fadeToggle', 対象要素, アニメーション時間 [, コールバック関数(任意)]);
*/
fadeAnime('fadeToggle', fadeToggleElm, 400, function() {
console.log('fadeToggle終了');
});
});
イージング設定や処理速度、コールバック関数(任意)はサイトに合わせて編集してください。