JavaScript

最終更新日:
公開日:

レシピ

アニメーション

画像のぼかしをアニメーションで変化させる

CSSのfilterプロパティblurメソッドで指定した画像のぼかし具合をアニメーションで変化させる方法について解説します。

この記事のポイント

  • 画像のぼかしはfilterプロパティblurメソッドを使う
  • アニメーションはtransitionプロパティanimationプロパティを使う
  • JavaScriptでclass属性を編集することでアニメーションを実行する

目次

画像のぼかし具合の変化をアニメーションにする

CSSではimg要素で読み込んだ画像のぼかし具合をfilterプロパティblurメソッドで調整することができます。
このプロパティはtransitionプロパティanimationプロパティと組み合わせることで、ぼかす過程をアニメーションにすることも可能です。

今回はこれらのプロパティとJavaScriptによるclass属性の編集操作を組み合わせることで、ぼかし具合をアニメーションさせていきます。
transitionプロパティを使うパターンとanimationプロパティを使うパターンの2種類解説していきますが、まずはtransitionプロパティを使ったパターンから解説していきます。

以下の例は「デフォルト」「2px」「5px」「10px」の4つのボタンからいずれかを押すと、表示している画像のうち2枚目のimg要素class属性を切り替えて、ぼかし具合の変化のアニメーションを再生します。

サンプルページはこちら

HTML コード例

<article id="content1">
	<h1>JavaScriptレシピ</h1>
	<ul id="btn_change">
		<li><a href="#" class="active">デフォルト</a></li>
		<li><a href="#">2px</a></li>
		<li><a href="#">5px</a></li>
		<li><a href="#">10px</a></li>
	</ul>
	<div>
		<figure><img id="pic1" src="./image/bear.png" alt="元画像"><figcaption>元の状態</figcaption></figure>
		<figure><img id="pic2" src="./image/bear.png" alt="加工画像"><figcaption>調整後</figcaption></figure>
	</div>
</article>

CSSは下の方の「ぼかしの調整」部分に記述している箇所が非常に重要です。
ここではfilterプロパティによるぼかし具合の調整に加えて、transitionプロパティを使ったアニメーションの設定も行います。

CSS コード例

article {
	padding: 20px;
	background-color: #bedef7;
}
h1 {
	margin: 0 0 20px;
	padding: 0;
	font-size: 100%;
}

/* ぼかし具合の切り替えボタン
------------------------------ */
ul {
	overflow: hidden;
	margin: 0;
	padding: 0;
}
ul li {
	float: left;
	margin: 0 20px 0 0;
	display: inline-block;
	padding: 0;
}
ul li a {
	display: inline-block;
	margin-bottom: 20px;
	padding: 10px 20px;
	color: #fff;
	font-size: 86%;
	text-decoration: none;
	border-radius: 5px;
	background-color: #4a93cb;
}
ul li a:hover,
ul li a.active {
	background-color: #71b2e4;
}

/* 画像エリア
------------------------------ */
div {
	overflow: hidden;
}
figure {
	float: left;
	margin: 0 20px 0 0;
	padding: 0;
}
figure img {
	width: 400px;
	height: auto;
}

/* ぼかしの調整
------------------------------ */
#pic2 {
	filter: blur(0);
	transition-property: filter;
	transition-duration: .5s;
	transition-timing-function: ease;
}
#pic2.light {
	filter: blur(2px);
}
#pic2.medium {
	filter: blur(5px);
}
#pic2.strong {
	filter: blur(10px);
}

blurメソッド0は初期状態でぼかす前の元画像と同じ状態です。
それ以外の値とボタンとの関係は以下のように設定します。

クラス名対応するボタンblurメソッドの値
.light2px2px
.medium5px5px
.strong10px10px

最後にJavaScriptのコードです。

JavaScript コード例

window.addEventListener('DOMContentLoaded', function(){

	const pic2 = document.getElementById('pic2');		
	const btn_change = document.getElementById('btn_change');
	const btns = document.querySelectorAll('#btn_change li a');

	for(var btn of btns) {

		btn.addEventListener('click', (e)=> {

			e.preventDefault();
			e.target.classList.add('active');

			const btns2 = document.querySelectorAll('#btn_change li a');

			for(var i_btn of btns2) {
				i_btn.classList.remove('active');
			}

			switch(e.target.textContent) {

				case '2px':
					pic2.setAttribute('class','light');
					break;

				case '5px':
					pic2.setAttribute('class','medium');
					break;

				case '10px':
					pic2.setAttribute('class','strong');
					break;

				default:
					pic2.removeAttribute('class');
					break;
			}

		});
	}
});

switch文の条件式にある「e.target.textContent」は押されたボタンのテキストを取得しています。
このテキストをcase文で判定して、適用するblurメソッドを決定します。

case文ではimg要素に対してsetAttributeメソッドremoveAttributeメソッドを使ってclass属性を書き換えます。
適用するクラスが切り替わることで、CSSに記述したtransitionプロパティのアニメーションが実行される仕組みになっています。

animationプロパティを使ったぼかしのアニメーション

上記のコードではtransitionプロパティを使ってアニメーションの設定を行いましたが、animationプロパティに置き換えた場合のCSSは以下のようになります。
変更はCSSのみとなり、HTMLとJavaScriptについては変更の必要はありません。

transitionプロパティとは1点だけ異なる点があります。
animationプロパティのアニメーションを設定する@keyframesは現在適用されているプロパティの値を引き継ぐことができません。
そのため、何かボタンを押してアニメーションを実行した後の状態で、他のボタンが押されたときに次のアニメーションを開始するときは初期値「blur(0)」からのスタートになります。

CSS コード例

article {
	padding: 20px;
	background-color: #bedef7;
}
h1 {
	margin: 0 0 20px;
	padding: 0;
	font-size: 100%;
}

/* ぼかし具合の切り替えボタン
------------------------------ */
ul {
	overflow: hidden;
	margin: 0;
	padding: 0;
}
ul li {
	float: left;
	margin: 0 20px 0 0;
	display: inline-block;
	padding: 0;
}
ul li a {
	display: inline-block;
	margin-bottom: 20px;
	padding: 10px 20px;
	color: #fff;
	font-size: 86%;
	text-decoration: none;
	border-radius: 5px;
	background-color: #4a93cb;
}
ul li a:hover,
ul li a.active {
	background-color: #71b2e4;
}

/* 画像エリア
------------------------------ */
div {
	overflow: hidden;
}
figure {
	float: left;
	margin: 0 20px 0 0;
	padding: 0;
}
figure img {
	width: 400px;
	height: auto;
}

/* ぼかしの調整
------------------------------ */
#pic2 {
	filter: blur(0);
}
#pic2.light {
	animation: a1 .5s ease forwards;
}
#pic2.medium {
	animation: a2 .5s ease forwards;
}
#pic2.strong {
	animation: a3 .5s ease forwards;
}

@keyframes a1 {
	100% {filter: blur(2px);}
}
@keyframes a2 {
	100% {filter: blur(5px);}
}
@keyframes a3 {
	100% {filter: blur(10px);}
}