
アイコンモーフィングアニメーションを実装したい……



アイコンの形状変化を作りたい……
今回はこのようなお悩みをお持ちの方へ向けて
Web制作において必須のUI要素
アイコンモーフィングアニメーション
をご紹介します。
- 形状変化(形状の変化)
- パス変化(SVGパスの変化)
- カラー変化(色の変化)
- スケール変化(拡大/縮小)
- ローテーション変化(回転変化)
- 透明度変化(透明度の変化)



特に状態変化やトグル切り替えには、アイコンモーフィングアニメーションが非常に効果的です。この記事のコードをご活用いただきWeb制作の効率化に繋がれば何よりです。
なお、今回ご紹介するアニメーションはCSSとJavaScriptで実装できるので、基本的なコーディング知識があれば安心してご利用いただけます。
あわせて読みたい
アイコンモーフィングアニメーションとは
アイコンモーフィングアニメーションは、アイコンの形状や属性が滑らかに変化することで、状態変化やトグル切り替えを視覚的に表現するアニメーション効果です。ユーザーに直感的な理解を提供し、インタラクション促進を実現する効果的な手法です。
効果的な使用場面
適している場面
- 状態切り替え(ON/OFF)
- トグルボタン
- メニュー開閉
- 設定変更
- モード切り替え
- アプリ状態表示
避けるべき場面
- 過度に派手なアニメーション
- パフォーマンスを重視する場面
- アクセシビリティを重視する場面
実装方法の比較
アニメーション | 難易度 | 視覚的インパクト | パフォーマンス | ブラウザ対応 |
---|---|---|---|---|
形状変化 | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
パス変化 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ |
カラー変化 | ⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
スケール変化 | ⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
ローテーション変化 | ⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
透明度変化 | ⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
FontAwesomeの読み込み
FontAwesomeアイコンを使用するために、HTMLのheadセクションに以下のコードを追加してください。
※バージョンはご自身の環境にあわせてご選択ください。基本は最新で大丈夫かと思います。
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
形状変化
アイコンの形状が滑らかに変化するアニメーションです。
① デモ
See the Pen アイコンモーフィング形状変化 by ケケンタ (@lgshifbg-the-looper) on CodePen.
- 滑らかな形状変化
- 視覚的インパクトが高い
- 状態変化の明確化
② HTML
<div class="icon-container">
<div class="shape-morphing-icons">
<div class="shape-morphing-icon" data-state="play">
<i class="fas fa-play play-icon"></i>
<i class="fas fa-pause pause-icon"></i>
</div>
<div class="shape-morphing-icon" data-state="menu">
<i class="fas fa-bars menu-icon"></i>
<i class="fas fa-times close-icon"></i>
</div>
</div>
</div>
③ CSS
/* 共通スタイル */
.icon-container {
display: flex;
justify-content: center;
align-items: center;
min-height: 300px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
font-family: 'Arial', sans-serif;
}
/* 固有のスタイル */
.shape-morphing-icons {
display: flex;
gap: 30px;
}
.shape-morphing-icon {
position: relative;
width: 60px;
height: 60px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
transition: all 0.5s ease;
}
.shape-morphing-icon i {
font-size: 32px;
color: white;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
position: absolute;
transition: all 0.5s ease;
}
/* 初期状態の設定 */
.shape-morphing-icon[data-state="play"] .pause-icon,
.shape-morphing-icon[data-state="menu"] .close-icon {
opacity: 0;
transform: scale(0.5);
visibility: hidden;
}
.shape-morphing-icon[data-state="play"] .play-icon,
.shape-morphing-icon[data-state="menu"] .menu-icon {
opacity: 1;
transform: scale(1);
visibility: visible;
}
/* 状態変更時の表示制御 */
.shape-morphing-icon[data-state="pause"] .play-icon {
opacity: 0;
transform: scale(0.5);
visibility: hidden;
}
.shape-morphing-icon[data-state="pause"] .pause-icon {
opacity: 1;
transform: scale(1);
visibility: visible;
}
.shape-morphing-icon[data-state="close"] .menu-icon {
opacity: 0;
transform: scale(0.5);
visibility: hidden;
}
.shape-morphing-icon[data-state="close"] .close-icon {
opacity: 1;
transform: scale(1);
visibility: visible;
}
/* アニメーション効果 */
@keyframes shapeMorph {
0% {
transform: scale(1);
opacity: 1;
}
25% {
transform: scale(0.8);
opacity: 0.3;
}
50% {
transform: scale(0.6);
opacity: 0;
}
75% {
transform: scale(0.8);
opacity: 0.3;
}
100% {
transform: scale(1);
opacity: 1;
}
}
.shape-morphing-icon.morphing i {
animation: shapeMorph 0.6s cubic-bezier(0.4, 0, 0.2, 1);
}
/* アニメーション中の重なり防止 */
.shape-morphing-icon.morphing .play-icon,
.shape-morphing-icon.morphing .pause-icon,
.shape-morphing-icon.morphing .menu-icon,
.shape-morphing-icon.morphing .close-icon {
transition: none;
}
④ JavaScript
document.addEventListener('DOMContentLoaded', function() {
const icons = document.querySelectorAll('.shape-morphing-icon');
// 形状変化モーフィングアニメーションクラス
class ShapeMorphingAnimation {
constructor(icons) {
this.icons = icons;
this.init();
}
init() {
this.icons.forEach((icon) => {
icon.addEventListener('click', () => {
this.toggleShape(icon);
});
});
}
toggleShape(icon) {
const currentState = icon.getAttribute('data-state');
const newState = this.getNextState(currentState);
icon.classList.add('morphing');
icon.setAttribute('data-state', newState);
// アイコンの表示制御を実行
this.updateIconVisibility(icon, newState);
setTimeout(() => {
icon.classList.remove('morphing');
}, 600);
}
getNextState(currentState) {
const stateMap = {
'play': 'pause',
'pause': 'play',
'menu': 'close',
'close': 'menu'
};
return stateMap[currentState] || currentState;
}
// 状態に応じたアイコンの表示制御
updateIconVisibility(icon, newState) {
const allIcons = icon.querySelectorAll('i');
// アニメーション開始時:現在のアイコンをフェードアウト
allIcons.forEach(iconElement => {
iconElement.style.transition = 'opacity 0.15s ease-out';
iconElement.style.opacity = '0';
});
// アニメーション中間:アイコンを完全に非表示
setTimeout(() => {
allIcons.forEach(iconElement => {
iconElement.style.visibility = 'hidden';
});
// 新しい状態のアイコンを準備
const targetIcon = icon.querySelector(`.${newState}-icon`);
if (targetIcon) {
targetIcon.style.visibility = 'visible';
targetIcon.style.opacity = '0';
targetIcon.style.transform = 'scale(0.6) rotate(90deg)';
}
}, 150);
// アニメーション完了:新しいアイコンをフェードイン
setTimeout(() => {
const targetIcon = icon.querySelector(`.${newState}-icon`);
if (targetIcon) {
targetIcon.style.transition = 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)';
targetIcon.style.opacity = '1';
targetIcon.style.transform = 'scale(1)';
}
}, 300);
}
}
// アニメーション初期化
new ShapeMorphingAnimation(icons);
});
⑤ カスタマイズ例
/* 形状変化速度の調整 */
.shape-morphing-icon {
transition: all 0.8s ease;
}
/* 形状変化時の影効果 */
.shape-morphing-icon.morphing {
filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.4));
}
/* 形状変化時の色変化 */
.shape-morphing-icon.morphing i {
color: #ffd700;
}
パス変化
SVGパスが滑らかに変化するアニメーションです。
① デモ
See the Pen Untitled by ケケンタ (@lgshifbg-the-looper) on CodePen.
- SVGパスの動的変化
- 滑らかな形状変換
- 高度な視覚効果
② HTML
<div class="icon-container">
<div class="path-morphing-icons">
<svg class="path-morphing-icon" viewBox="0 0 24 24" data-state="menu">
<path class="path-line" d="M3 6h18M3 12h18M3 18h18"/>
<path class="path-close" d="M18 6L6 18M6 6l12 12"/>
</svg>
<svg class="path-morphing-icon" viewBox="0 0 24 24" data-state="play">
<path class="path-play" d="M8 5v14l11-7z"/>
<path class="path-pause" d="M6 4h4v16H6V4zm8 0h4v16h-4V4z"/>
</svg>
</div>
</div>
③ CSS
/* 共通スタイル */
.icon-container {
display: flex;
justify-content: center;
align-items: center;
min-height: 300px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
font-family: 'Arial', sans-serif;
}
/* 固有のスタイル */
.path-morphing-icons {
display: flex;
gap: 40px;
}
.path-morphing-icon {
width: 60px;
height: 60px;
cursor: pointer;
transition: all 0.5s ease;
}
.path-morphing-icon path {
stroke: white;
stroke-width: 2;
fill: none;
stroke-linecap: round;
stroke-linejoin: round;
transition: all 0.5s ease;
}
.path-morphing-icon[data-state="menu"] .path-close,
.path-morphing-icon[data-state="play"] .path-pause {
opacity: 0;
stroke-dasharray: 0;
visibility: hidden;
}
.path-morphing-icon[data-state="menu"] .path-line,
.path-morphing-icon[data-state="play"] .path-play {
opacity: 1;
stroke-dasharray: 24;
visibility: visible;
}
/* 状態変更時の表示制御 */
.path-morphing-icon[data-state="close"] .path-line {
opacity: 0;
stroke-dasharray: 0;
visibility: hidden;
}
.path-morphing-icon[data-state="close"] .path-close {
opacity: 1;
stroke-dasharray: 24;
visibility: visible;
}
.path-morphing-icon[data-state="pause"] .path-play {
opacity: 0;
stroke-dasharray: 0;
visibility: hidden;
}
.path-morphing-icon[data-state="pause"] .path-pause {
opacity: 1;
stroke-dasharray: 24;
visibility: visible;
}
/* アニメーション効果 */
@keyframes pathMorph {
0% {
stroke-dasharray: 24;
opacity: 1;
visibility: visible;
}
25% {
stroke-dasharray: 18;
opacity: 0.7;
visibility: visible;
}
50% {
stroke-dasharray: 12;
opacity: 0.3;
visibility: visible;
}
75% {
stroke-dasharray: 6;
opacity: 0.1;
visibility: visible;
}
100% {
stroke-dasharray: 0;
opacity: 0;
visibility: visible;
}
}
.path-morphing-icon.morphing path {
animation: pathMorph 0.6s cubic-bezier(0.4, 0, 0.2, 1);
}
/* アニメーション中の重なり防止 */
.path-morphing-icon.morphing .path-line,
.path-morphing-icon.morphing .path-close,
.path-morphing-icon.morphing .path-play,
.path-morphing-icon.morphing .path-pause {
transition: none;
}
④ JavaScript
document.addEventListener('DOMContentLoaded', function() {
const icons = document.querySelectorAll('.path-morphing-icon');
// パス変化モーフィングアニメーションクラス
class PathMorphingAnimation {
constructor(icons) {
this.icons = icons;
this.init();
}
init() {
this.icons.forEach((icon) => {
icon.addEventListener('click', () => {
this.togglePath(icon);
});
});
}
togglePath(icon) {
const currentState = icon.getAttribute('data-state');
const newState = this.getNextState(currentState);
icon.classList.add('morphing');
icon.setAttribute('data-state', newState);
// アニメーション完了後にパスの表示状態を復元
setTimeout(() => {
icon.classList.remove('morphing');
this.updatePathVisibility(icon, newState);
}, 600);
}
// パスの表示状態を更新
updatePathVisibility(icon, state) {
const allPaths = icon.querySelectorAll('path');
allPaths.forEach(path => {
if (state === 'menu' && path.classList.contains('path-line')) {
path.style.opacity = '1';
path.style.strokeDasharray = '24';
path.style.visibility = 'visible';
} else if (state === 'menu' && path.classList.contains('path-close')) {
path.style.opacity = '0';
path.style.strokeDasharray = '0';
path.style.visibility = 'hidden';
} else if (state === 'close' && path.classList.contains('path-line')) {
path.style.opacity = '0';
path.style.strokeDasharray = '0';
path.style.visibility = 'hidden';
} else if (state === 'close' && path.classList.contains('path-close')) {
path.style.opacity = '1';
path.style.strokeDasharray = '24';
path.style.visibility = 'visible';
} else if (state === 'play' && path.classList.contains('path-play')) {
path.style.opacity = '1';
path.style.strokeDasharray = '24';
path.style.visibility = 'visible';
} else if (state === 'play' && path.classList.contains('path-pause')) {
path.style.opacity = '0';
path.style.strokeDasharray = '0';
path.style.visibility = 'hidden';
} else if (state === 'pause' && path.classList.contains('path-play')) {
path.style.opacity = '0';
path.style.strokeDasharray = '0';
path.style.visibility = 'hidden';
} else if (state === 'pause' && path.classList.contains('path-pause')) {
path.style.opacity = '1';
path.style.strokeDasharray = '24';
path.style.visibility = 'visible';
}
});
}
getNextState(currentState) {
const stateMap = {
'menu': 'close',
'close': 'menu',
'play': 'pause',
'pause': 'play'
};
return stateMap[currentState] || currentState;
}
}
// アニメーション初期化
new PathMorphingAnimation(icons);
});
⑤ カスタマイズ例
/* パス変化速度の調整 */
.path-morphing-icon {
transition: all 0.8s ease;
}
/* パス変化時の色変化 */
.path-morphing-icon.morphing path {
stroke: #ffd700;
}
/* パス変化時の太さ調整 */
.path-morphing-icon.morphing path {
stroke-width: 3;
}
カラー変化
アイコンの色が滑らかに変化するアニメーションです。
① デモ
See the Pen Untitled by ケケンタ (@lgshifbg-the-looper) on CodePen.
- 滑らかな色の変化
- 視覚的インパクトが高い
- 状態変化の明確化
② HTML
<div class="icon-container">
<div class="color-morphing-icons">
<i class="fas fa-heart color-morphing-icon" data-state="normal"></i>
<i class="fas fa-star color-morphing-icon" data-state="normal"></i>
<i class="fas fa-magic color-morphing-icon" data-state="normal"></i>
<i class="fas fa-gem color-morphing-icon" data-state="normal"></i>
</div>
</div>
③ CSS
/* 共通スタイル */
.icon-container {
display: flex;
justify-content: center;
align-items: center;
min-height: 300px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
font-family: 'Arial', sans-serif;
}
/* 固有のスタイル */
.color-morphing-icons {
display: flex;
gap: 20px;
}
.color-morphing-icon {
font-size: 48px;
color: white;
cursor: pointer;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
transition: all 0.6s ease;
}
.color-morphing-icon[data-state="normal"] {
color: white;
transform: scale(1);
}
.color-morphing-icon[data-state="active"] {
color: #ff6b6b;
transform: scale(1.2);
}
/* アニメーション効果 */
@keyframes colorMorph {
0% {
color: white;
transform: scale(1);
}
25% {
color: #ffd700;
transform: scale(1.1);
}
50% {
color: #ffd700;
transform: scale(1.1);
}
75% {
color: #ffd700;
transform: scale(1.1);
}
100% {
color: #ff6b6b;
transform: scale(1.2);
}
}
/* 逆方向のアニメーション */
@keyframes colorMorphReverse {
0% {
color: #ff6b6b;
transform: scale(1.2);
}
25% {
color: #ffd700;
transform: scale(1.1);
}
50% {
color: #ffd700;
transform: scale(1.1);
}
75% {
color: #ffd700;
transform: scale(1.1);
}
100% {
color: white;
transform: scale(1);
}
}
.color-morphing-icon.morphing {
animation: colorMorph 0.6s cubic-bezier(0.4, 0, 0.2, 1);
}
.color-morphing-icon.morphing.reverse {
animation: colorMorphReverse 0.6s cubic-bezier(0.4, 0, 0.2, 1);
}
/* アニメーション完了後の状態制御 */
.color-morphing-icon[data-state="normal"] {
color: white;
transform: scale(1);
}
.color-morphing-icon[data-state="active"] {
color: #ff6b6b;
transform: scale(1.2);
}
④ JavaScript
document.addEventListener('DOMContentLoaded', function() {
const icons = document.querySelectorAll('.color-morphing-icon');
// カラー変化モーフィングアニメーションクラス
class ColorMorphingAnimation {
constructor(icons) {
this.icons = icons;
this.init();
}
init() {
this.icons.forEach((icon) => {
icon.addEventListener('click', () => {
this.toggleColor(icon);
});
});
}
toggleColor(icon) {
const currentState = icon.getAttribute('data-state');
const newState = currentState === 'normal' ? 'active' : 'normal';
// アニメーション開始
icon.classList.add('morphing');
// 逆方向のアニメーションの場合はreverseクラスを追加
if (currentState === 'active') {
icon.classList.add('reverse');
}
icon.setAttribute('data-state', newState);
// アニメーション完了後にクラスを削除
setTimeout(() => {
icon.classList.remove('morphing', 'reverse');
}, 600);
}
}
// アニメーション初期化
new ColorMorphingAnimation(icons);
});
⑤ カスタマイズ例
/* カラー変化速度の調整 */
.color-morphing-icon {
transition: all 1s ease;
}
/* カラー変化時の影効果 */
.color-morphing-icon.morphing {
text-shadow: 0 4px 8px rgba(0, 0, 0, 0.5);
}
/* カラー変化時の回転効果 */
.color-morphing-icon.morphing {
animation: colorMorphRotate 0.6s ease;
}
@keyframes colorMorphRotate {
0% { transform: scale(1) rotate(0deg); }
50% { transform: scale(1.1) rotate(180deg); }
100% { transform: scale(1.2) rotate(360deg); }
}
スケール変化
アイコンが拡大・縮小しながら変化するアニメーションです。
① デモ
See the Pen Untitled by ケケンタ (@lgshifbg-the-looper) on CodePen.
- 動的な拡大・縮小
- 視覚的インパクトが高い
- 状態変化の明確化
② HTML
<div class="icon-container">
<div class="scale-morphing-icons">
<i class="fas fa-bullseye scale-morphing-icon" data-state="small"></i>
<i class="fas fa-theater-masks scale-morphing-icon" data-state="small"></i>
<i class="fas fa-mask scale-morphing-icon" data-state="small"></i>
<i class="fas fa-palette scale-morphing-icon" data-state="small"></i>
</div>
</div>
③ CSS
/* 共通スタイル */
.icon-container {
display: flex;
justify-content: center;
align-items: center;
min-height: 300px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
font-family: 'Arial', sans-serif;
}
/* 固有のスタイル */
.scale-morphing-icons {
display: flex;
gap: 20px;
}
.scale-morphing-icon {
font-size: 48px;
color: white;
cursor: pointer;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
transition: all 0.5s ease;
}
.scale-morphing-icon[data-state="small"] {
transform: scale(1);
color: white;
}
.scale-morphing-icon[data-state="large"] {
transform: scale(1.5);
}
/* アニメーション効果 */
@keyframes scaleMorph {
0% {
transform: scale(1);
}
50% {
transform: scale(1.25);
}
100% {
transform: scale(1.5);
}
}
/* 逆方向のアニメーション */
@keyframes scaleMorphReverse {
0% {
transform: scale(1.5);
}
50% {
transform: scale(1.25);
}
100% {
transform: scale(1);
}
}
.scale-morphing-icon.morphing {
animation: scaleMorph 0.5s ease;
}
.scale-morphing-icon.morphing.reverse {
animation: scaleMorphReverse 0.5s ease;
}
④ JavaScript
document.addEventListener('DOMContentLoaded', function() {
const icons = document.querySelectorAll('.scale-morphing-icon');
// スケール変化モーフィングアニメーションクラス
class ScaleMorphingAnimation {
constructor(icons) {
this.icons = icons;
this.init();
}
init() {
this.icons.forEach((icon) => {
icon.addEventListener('click', () => {
this.toggleScale(icon);
});
});
}
toggleScale(icon) {
const currentState = icon.getAttribute('data-state');
const newState = currentState === 'small' ? 'large' : 'small';
// アニメーション開始
icon.classList.add('morphing');
// 逆方向のアニメーションの場合はreverseクラスを追加
if (currentState === 'large') {
icon.classList.add('reverse');
}
icon.setAttribute('data-state', newState);
// アニメーション完了後にクラスを削除
setTimeout(() => {
icon.classList.remove('morphing', 'reverse');
}, 500);
}
}
// アニメーション初期化
new ScaleMorphingAnimation(icons);
});
⑤ カスタマイズ例
/* スケール変化速度の調整 */
.scale-morphing-icon {
transition: all 0.8s ease;
}
/* スケール変化時の影効果 */
.scale-morphing-icon.morphing {
text-shadow: 0 6px 12px rgba(0, 0, 0, 0.5);
}
/* スケール変化時の回転効果 */
.scale-morphing-icon.morphing {
animation: scaleMorphRotate 0.5s ease;
}
@keyframes scaleMorphRotate {
0% { transform: scale(1) rotate(0deg); }
50% { transform: scale(1.25) rotate(180deg); }
100% { transform: scale(1.5) rotate(360deg); }
}
ローテーション変化
アイコンが回転しながら変化するアニメーションです。
① デモ
See the Pen Untitled by ケケンタ (@lgshifbg-the-looper) on CodePen.
- 動的な回転動き
- 視覚的インパクトが高い
- 方向性のある表現
② HTML
<div class="icon-container">
<div class="rotation-morphing-icons">
<i class="fas fa-cog rotation-morphing-icon" data-state="normal"></i>
<i class="fas fa-sync rotation-morphing-icon" data-state="normal"></i>
<i class="fas fa-bullseye rotation-morphing-icon" data-state="normal"></i>
<i class="fas fa-star rotation-morphing-icon" data-state="normal"></i>
</div>
</div>
③ CSS
/* 共通スタイル */
.icon-container {
display: flex;
justify-content: center;
align-items: center;
min-height: 300px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
font-family: 'Arial', sans-serif;
}
/* 固有のスタイル */
.rotation-morphing-icons {
display: flex;
gap: 20px;
}
.rotation-morphing-icon {
font-size: 48px;
color: white;
cursor: pointer;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
transition: all 0.6s ease;
}
.rotation-morphing-icon[data-state="normal"] {
transform: rotate(0deg);
color: white;
}
.rotation-morphing-icon[data-state="rotated"] {
transform: rotate(180deg);
color: #00d2ff;
}
/* アニメーション効果 */
@keyframes rotationMorph {
0% {
transform: rotate(0deg);
color: white;
}
50% {
transform: rotate(90deg);
color: #ffd700;
}
100% {
transform: rotate(180deg);
color: #00d2ff;
}
}
/* 逆方向のアニメーション */
@keyframes rotationMorphReverse {
0% {
transform: rotate(180deg);
color: #00d2ff;
}
50% {
transform: rotate(90deg);
color: #ffd700;
}
100% {
transform: rotate(0deg);
color: white;
}
}
.rotation-morphing-icon.morphing {
animation: rotationMorph 0.6s ease;
}
.rotation-morphing-icon.morphing.reverse {
animation: rotationMorphReverse 0.6s ease;
}
④ JavaScript
document.addEventListener('DOMContentLoaded', function() {
const icons = document.querySelectorAll('.rotation-morphing-icon');
// ローテーション変化モーフィングアニメーションクラス
class RotationMorphingAnimation {
constructor(icons) {
this.icons = icons;
this.init();
}
init() {
this.icons.forEach((icon) => {
icon.addEventListener('click', () => {
this.toggleRotation(icon);
});
});
}
toggleRotation(icon) {
const currentState = icon.getAttribute('data-state');
const newState = currentState === 'normal' ? 'rotated' : 'normal';
// アニメーション開始
icon.classList.add('morphing');
// 逆方向のアニメーションの場合はreverseクラスを追加
if (currentState === 'rotated') {
icon.classList.add('reverse');
}
icon.setAttribute('data-state', newState);
// アニメーション完了後にクラスを削除
setTimeout(() => {
icon.classList.remove('morphing', 'reverse');
}, 600);
}
}
// アニメーション初期化
new RotationMorphingAnimation(icons);
});
⑤ カスタマイズ例
/* ローテーション変化速度の調整 */
.rotation-morphing-icon {
transition: all 1s ease;
}
/* ローテーション変化時の影効果 */
.rotation-morphing-icon.morphing {
text-shadow: 0 4px 8px rgba(0, 0, 0, 0.5);
}
/* ローテーション変化時のスケール効果 */
.rotation-morphing-icon.morphing {
animation: rotationMorphScale 0.6s ease;
}
@keyframes rotationMorphScale {
0% { transform: rotate(0deg) scale(1); }
50% { transform: rotate(90deg) scale(1.2); }
100% { transform: rotate(180deg) scale(1); }
}
透明度変化
アイコンの透明度が滑らかに変化するアニメーションです。
① デモ
See the Pen Untitled by ケケンタ (@lgshifbg-the-looper) on CodePen.
- 滑らかな透明度変化
- 控えめな表現
- 上品な印象
② HTML
<div class="icon-container">
<div class="opacity-morphing-icons">
<i class="fas fa-magic opacity-morphing-icon" data-state="visible"></i>
<i class="fas fa-gem opacity-morphing-icon" data-state="visible"></i>
<i class="fas fa-star opacity-morphing-icon" data-state="visible"></i>
<i class="fas fa-heart opacity-morphing-icon" data-state="visible"></i>
</div>
</div>
③ CSS
/* 共通スタイル */
.icon-container {
display: flex;
justify-content: center;
align-items: center;
min-height: 300px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
font-family: 'Arial', sans-serif;
}
/* 固有のスタイル */
.opacity-morphing-icons {
display: flex;
gap: 20px;
}
.opacity-morphing-icon {
font-size: 48px;
color: white;
cursor: pointer;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
transition: all 0.5s ease;
}
.opacity-morphing-icon[data-state="visible"] {
opacity: 1;
color: white;
}
.opacity-morphing-icon[data-state="hidden"] {
opacity: 0.3;
color: #ff9ff3;
}
/* アニメーション効果 */
@keyframes opacityMorph {
0% {
opacity: 1;
color: white;
}
50% {
opacity: 0.6;
color: #ffd700;
}
100% {
opacity: 0.3;
color: #ff9ff3;
}
}
/* 逆方向のアニメーション */
@keyframes opacityMorphReverse {
0% {
opacity: 0.3;
color: #ff9ff3;
}
50% {
opacity: 0.6;
color: #ffd700;
}
100% {
opacity: 1;
color: white;
}
}
.opacity-morphing-icon.morphing {
animation: opacityMorph 0.5s ease;
}
.opacity-morphing-icon.morphing.reverse {
animation: opacityMorphReverse 0.5s ease;
}
④ JavaScript
document.addEventListener('DOMContentLoaded', function() {
const icons = document.querySelectorAll('.opacity-morphing-icon');
// 透明度変化モーフィングアニメーションクラス
class OpacityMorphingAnimation {
constructor(icons) {
this.icons = icons;
this.init();
}
init() {
this.icons.forEach((icon) => {
icon.addEventListener('click', () => {
this.toggleOpacity(icon);
});
});
}
toggleOpacity(icon) {
const currentState = icon.getAttribute('data-state');
const newState = currentState === 'visible' ? 'hidden' : 'visible';
// アニメーション開始
icon.classList.add('morphing');
// 逆方向のアニメーションの場合はreverseクラスを追加
if (currentState === 'hidden') {
icon.classList.add('reverse');
}
icon.setAttribute('data-state', newState);
// アニメーション完了後にクラスを削除
setTimeout(() => {
icon.classList.remove('morphing', 'reverse');
}, 500);
}
}
// アニメーション初期化
new OpacityMorphingAnimation(icons);
});
⑤ カスタマイズ例
/* 透明度変化速度の調整 */
.opacity-morphing-icon {
transition: all 0.8s ease;
}
/* 透明度変化時の影効果 */
.opacity-morphing-icon.morphing {
text-shadow: 0 4px 8px rgba(0, 0, 0, 0.5);
}
/* 透明度変化時のスケール効果 */
.opacity-morphing-icon.morphing {
animation: opacityMorphScale 0.5s ease;
}
@keyframes opacityMorphScale {
0% { opacity: 1; transform: scale(1); }
50% { opacity: 0.6; transform: scale(0.9); }
100% { opacity: 0.3; transform: scale(1); }
}
まとめ
今回ご紹介した6種類のアイコンモーフィングアニメーションは、それぞれ異なる特徴と用途があります。
用途別おすすめ
- 状態切り替え: 形状変化・パス変化
- トグルボタン: カラー変化・スケール変化
- メニュー開閉: ローテーション変化・透明度変化
実装のポイント
- パフォーマンスを考慮: 軽量で滑らかなアニメーション
- ユーザビリティを重視: 過度な動きは避ける
- ブラウザ対応: 主要ブラウザでの動作確認
- アクセシビリティ: 動きに敏感なユーザーへの配慮
FontAwesomeアイコンのメリット
- 統一感: デザインの一貫性が向上
- 拡張性: 豊富なアイコンライブラリから選択可能
- カスタマイズ性: 色やサイズの調整が容易
- ブラウザ互換性: より安定した表示
- プロフェッショナル性: ビジネス用途に適した見た目



アイコンモーフィングアニメーションは、Webサイトのインタラクション性を向上させる効果的な手法です。FontAwesomeアイコンを使用することで、より統一感のあるデザインを実現できます。この記事のコードを参考に、プロジェクトに最適なアニメーションを実装してください!
あわせて読みたい
もっと効率的にWeb制作を学びたい方へ
Web制作の学習は楽しいものですが、一人で進めていると「これで合っているのかな?」と不安になることもありますよね。
僕も独学でWeb制作を学んできましたが、今思うと「もっと早く知りたかった」と思うことがたくさんあります。
特に以下のような方は、一度プログラミングスクールの利用を検討してみることをおすすめします。
- 学習の方向性に迷いがある方
- 効率的にスキルを身につけたい方
- 転職や副業でWeb制作を活用したい方
- 挫折経験がある方
忍者CODEなら、業界最安値で24時間サポート付きの学習環境が整っています。


関連記事
基本的なアニメーション
スクロール系
メニュー・タブ・ナビゲーション
\どれを読むか迷ったときのおすすめ‼/
フォーム・UI要素
\どれを読むか迷ったときのおすすめ‼/
ボタン・アイコン
\どれを読むか迷ったときのおすすめ‼/
テキスト
\どれを読むか迷ったときのおすすめ‼/
コメント