Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】Animation Start/Done? Dead. Long Live CSS + DOM Events

2025年10月03日に「Dev.to」が公開したITニュース「Animation Start/Done? Dead. Long Live CSS + DOM Events」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

Angularの非推奨アニメーション機能を、CSSアニメーションとDOMイベント、Angular Signalsで現代的に置き換える方法を紹介。古いやり方を踏襲しつつ、よりシンプルで理解しやすいアニメーション実装を実現できる。

ITニュース解説

このニュース記事は、Angularフレームワークでウェブアプリケーションを開発する際に使われていた古いアニメーションの仕組みが非推奨になったことを受け、現代的な方法で同様のアニメーションを実装する方法について解説している。具体的には、以前のチュートリアルで紹介された、入力フィールドが正しくない場合に左右に揺れる「Wobble(ぐらつき)」アニメーションを例に、その実装を現在のAngularのベストプラクティスに合わせて更新する手順を説明している。

まず、以前の「Wobble」アニメーションがどのように動いていたかを見ていこう。ユーザーがメールアドレスを入力せずに「Continue」ボタンをクリックすると、入力フィールドが左右に揺れる。この動きは、古いAngularのアニメーションモジュールを使って実現されていた。そのコードは、TypeScriptファイルのコンポーネント定義の一部として、@Componentデコレータ内のanimationsプロパティに直接記述されていた。ここでは、triggertransitionanimatekeyframesstyleといったAngular独自のアニメーション用DSL(Domain-Specific Language、ドメイン固有言語)が使われ、falseからtrueへの状態変化に応じてフィールドがtranslateX(X軸方向の移動)で0.75秒かけて揺れる一連の動きが細かく定義されていた。

アニメーションの開始と終了を制御するために、wobbleFieldという名前のsignal(シグナル)が使われていた。これはブール値(真偽値)を保持する特別な変数で、trueになるとアニメーションが開始され、falseになると停止またはリセットされる仕組みである。また、アニメーションが開始したときに特定の処理を行うためのonWobbleStart()関数も定義されていた。この関数は、古いAngularのAnimationEventオブジェクトを受け取り、アニメーションが開始されるとコンソールにイベント情報を表示し、特定の条件(fromState !== 'void')でアニメーションが実行される際にrenderer.addClass()メソッドを使って要素にinvalidというCSSクラスを追加し、フィールドを赤く光らせていた。

これら全てはHTMLテンプレート内で連携して動作していた。<label>要素には@wobble="wobbleField()"という形でアニメーションのトリガーがバインドされており、wobbleFieldシグナルがtrueになるとアニメーションが発火するように設定されていた。また、アニメーションの終了時には(@wobble.done)="wobbleField.set(false)"というイベントハンドラが登録されており、アニメーションが終わるとwobbleFieldシグナルがfalseに戻され、次のアニメーション実行のためにリセットされる。アニメーションの開始時には(@wobble.start)="onWobbleStart($event)"が呼び出され、先述のonWobbleStart()関数が実行されていた。

しかし、Angularのアニメーションモジュールが非推奨になったため、この古いアプローチはもはや推奨されない。そこで、記事では同じ「Wobble」効果を、より現代的な「純粋なCSSキーフレーム」「Angular Signals」「標準のDOMイベント」を使って再構築する方法を提案している。この新しいアプローチの利点は、コードがよりシンプルになり、将来にわたって使え、汎用性が高く、新しい開発者にとっても理解しやすい点にある。

新しい実装への移行はいくつかのステップで行われる。 まず、ステップ1として、アニメーションの動きをCSSで定義する。コンポーネントのCSSファイルに@keyframes wobbleというルールを作成し、translateプロパティを使って0%から100%までの各時点で要素がX軸方向にどのように移動するかを細かく指定する。これにより、AngularのDSLを使わずに純粋なCSSだけで「Wobble」アニメーションが定義される。次に、.wobbleというCSSクラスを定義し、このクラスが適用されたときにwobbleキーフレームアニメーションが0.75秒かけて実行されるように設定する。

ステップ2では、HTMLテンプレート内の古いAngularアニメーションのトリガーをCSSクラスのバインディングに置き換える。具体的には、<label>要素の@wobble="wobbleField()"[class.wobble]="wobbleField()"に変更する。これにより、wobbleFieldシグナルがtrueの場合に.wobbleクラスが要素に追加され、CSSアニメーションが実行されるようになる。この時点では、古い(@wobble.start)(@wobble.done)イベントは一時的に削除される。

ステップ3では、不要になった古いAngularアニメーション関連のコードを削除してクリーンアップする。TypeScriptファイルから@angular/animationsモジュールからのanimatekeyframesstyletransitiontriggerAnimationEventといったインポート文を削除し、@Componentデコレータ内のanimationsプロパティとその定義も全て削除する。さらに、アプリケーションの起動時にアニメーション機能を提供するmain.tsファイルからprovideAnimationsAsync()関数とそのインポートも削除することで、古いアニメーションモジュールを完全にアプリケーションから取り除く。

ステップ4で、ここまでの変更をテストすると、アニメーションが一度は動作するものの、その後はwobbleFieldシグナルがtrueのままでクラスがリセットされないため、再クリックしてもアニメーションが再生されない問題が明らかになる。また、onWobbleStart()関数が呼び出されないため、入力フィールドが赤く光るinvalidクラスが適用されない問題も発生する。

これらの問題を解決するために、ステップ5で標準のDOMアニメーションイベントを使用する。HTMLテンプレートに戻り、アニメーションが終了したときにwobbleFieldシグナルをfalseにリセットするために、<label>要素にanimationendイベントを追加し、(animationend)="wobbleField.set(false)"と設定する。これにより、アニメーションが完了すると.wobbleクラスが解除され、次回のクリックで再度アニメーションが実行できるようになる。また、アニメーションが開始したときにonWobbleStart()関数を呼び出すために、animationstartイベントを追加し、(animationstart)="onWobbleStart($event)"と設定する。

最後にステップ6として、onWobbleStart()関数をDOMイベントに合わせて更新する。古いAngularのAnimationEventではなく、標準のEventオブジェクトを受け取るように関数の引数をprotected onWobbleStart(event: Event)に変更する。また、if (event.fromState !== 'void')という古いAngular固有のチェックは不要になるため削除する。そして、renderer.addClass()メソッドでinvalidクラスを適用する対象を、AngularのAnimationEventから取得していたevent.elementから、標準のEventオブジェクトから取得できるevent.target(アニメーションが適用されている要素自身)に変更する。

これら全ての変更を適用し、最終的にアプリケーションをテストすると、入力フィールドは以前と同じように、不正な入力時に左右に揺れ、赤く光るようになる。そして、何度クリックしてもアニメーションが正しく再生されるようになる。このようにして、古いAngularのアニメーションモジュールに依存せず、純粋なCSSと標準のDOMイベント、そしてAngular Signalsという現代的な方法で、同じ機能を実現できることが示されている。これは、よりクリーンで保守しやすく、パフォーマンスも向上する可能性のある、これからのAngular開発における推奨されるアニメーション実装方法である。

関連コンテンツ

関連IT用語