目次
JavaScriptを使用してキーフレームを生成します
ステップ1:開始状態と終了状態を計算します
ステップ2:キーフレームを生成します
ステップ3:CSSアニメーションを有効にします
拡張可能な部品を構築します
パフォーマンスチェック
最終的な考慮事項
ホームページ ウェブフロントエンド CSSチュートリアル パフォーマンスの拡張可能なアニメーション:その場でキーフレームを構築します

パフォーマンスの拡張可能なアニメーション:その場でキーフレームを構築します

Apr 08, 2025 am 10:51 AM

パフォーマンスの拡張可能なアニメーション:その場でキーフレームを構築します

CSSアニメーションテクノロジーはますます成熟しており、開発者により強力なツールを提供しています。特にCSSアニメーションは、ほとんどのアニメーションユースケースを解決するための基礎となっています。ただし、一部のアニメーションでは、より微調整された処理が必要です。

誰もが知っているように、アニメーションは合成層で実行する必要があります(ここでは繰り返されません。興味がある場合は、関連する文献を参照してください)。これは、アニメーションの変換または不透明な属性が公開レイアウトまたは描画レイヤーに触れないことを意味します。アニメーションの高さや幅などの属性はこれらのレイヤーをトリガーし、ブラウザにスタイルを再計算するように強制します。

さらに、実際の60 FPSアニメーションを実装したい場合でも、フリップテクノロジーを使用してよりスムーズなアニメーションを実現するなど、JavaScriptを使用する必要がある場合があります。

ただし、拡張可能なアニメーションに変換プロパティを使用することの問題は、スケーリング関数がアニメーションの高さ/幅プロパティとまったく同じではないことです。すべての要素が伸び(スケールアップ)または絞られた(スケーリングされた)ため、コンテンツにゆがんだ効果があります。

したがって、私の一般的な解決策(おそらく、おそらく、その理由は後で詳細に説明されるでしょう)は、ブランドン・スミスの記事の方法3です。このアプローチは依然として高さに移行しますが、JavaScriptを使用してコンテンツのサイズを計算し、RequestAnimationFrameを使用して遷移を強制します。 Outsystemsでは、実際にこの方法を使用して、OutSystems UI Accordionモード用のアニメーションを構築します。

JavaScriptを使用してキーフレームを生成します

最近、私はポール・ルイスによる別の素晴らしい記事に出くわし、アニメーションの展開と折り畳みの新しいソリューションを詳述しました。

彼の言葉では、主なアイデアは動的なキーフレームを生成し、徐々に...

[…] 0から100まで、要素とそのコンテンツに必要なスケーリング値を計算します。これらの値は、文字列に簡素化し、スタイル要素としてページに注入できます。

これを達成するための3つの主な手順があります。

ステップ1:開始状態と終了状態を計算します

両方の状態の正しいスケーリング値を計算する必要があります。これは、開始状態としてプロキシ化され、最終状態の値でそれを分割する要素にgetBoundingClientRect()を使用することを意味します。次のように見えるはずです:

関数calculatestartscale(){
  const start = startelement.getBoundingClientRect();
  const end = endelement.getBoundingClientRect();
  戻る {
    X:start.width / end.width、
    Y:start.height / end.height
  };
}
ログイン後にコピー

ステップ2:キーフレームを生成します

次に、必要なフレーム数を長さとして使用して、ループ用に実行する必要があります。 (スムーズなアニメーションを確保するために、60フレームを超えてはなりません。)それぞれの反復で、緩和関数を使用して正しい緩和値を計算します。

関数の使いやすさ(v、pow = 4){
  return 1 -math.pow(1 -v、pow);
}

easedStep = ease(i/frame);
ログイン後にコピー

この値を使用して、次の数学式を使用して、現在のステップで要素のスケーリングを取得します。

 const xscale = x(1 -x) * easedStep;
const yscale = y(1 -y) * easedStep;
ログイン後にコピー

次に、アニメーション文字列に手順を追加します。

アニメーション= `$ {step}%{
  変換:スケール($ {xscale}、$ {yscale});
} `;
ログイン後にコピー

コンテンツが伸び/傾斜していることを避けるために、逆の値を使用して、逆にアニメーション化する必要があります。

 const invxscale = 1 / xscale;
const invyScale = 1 / yscale;

inverseanimation = `$ {step}%{
  変換:scale($ {invxscale}、$ {invyscale});
} `;
ログイン後にコピー

最後に、完成したアニメーションを返したり、新しく作成したスタイルのタグに直接注入したりできます。

ステップ3:CSSアニメーションを有効にします

CSSに関しては、正しい要素でアニメーションを有効にする必要があります。

 .element- expanded {
  アニメーション名:アニメーション;
  アニメーション期間:300ms;
  アニメーション - タイミング機能:ステップエンド;
}

.element-contents-Expanded {
  Animation-Name:InverseAnimation;
  アニメーション期間:300ms;
  アニメーション - タイミング機能:ステップエンド;
}
ログイン後にコピー

CodepenでPaul Lewisの記事(Chrisが寄稿)でメニューの例を表示できます。

拡張可能な部品を構築します

これらの基本的な概念を習得したので、この手法を拡張可能な部分などのさまざまなユースケースに適用できるかどうかを確認したかったのです。

この場合、特にスケーリングを計算する関数では、高さをアニメーション化するだけです。セクションタイトルからy値を崩壊した状態として取得し、セクション全体を拡張状態を表すようにします。

 _CALCULATESCALES(){
      var collapsed = this._sectionItemtitle.getBoundingClientRect();
      var拡張= this._section.getBoundingClientRect();

      //ラッパーに適用するために、高さが崩壊したCSS変数を作成します
      this._sectionWrapper.style.setProperty( ' -  title-height'、collapsed.height 'px');

      this._collapsed = {
        Y:Collapsed.height / Expanded.height
      }
    }
ログイン後にコピー

拡張部品に絶対的な位置を持たせたいので(崩壊した状態でスペースを占有することを避けるため)、崩壊した高さを使用してCSS変数を設定し、ラッパーに適用します。これは、相対的なポジショニングを持つ唯一の要素です。

次は、キーフレームを作成する関数です: _createEaseAnimations() 。これは、上記のものとそれほど違いはありません。このユースケースでは、実際に4つのアニメーションを作成する必要があります。

  1. ラッパーのアニメーションを拡張します
  2. コンテンツの逆拡張アニメーション
  3. フォールドラッパーのアニメーション
  4. コンテンツの逆折りたたみアニメーション

以前と同じアプローチに従い、60の長さのループを実行して(60 FPSアニメーションを滑らかにするため)、緩和ステップに基づいてキーフレームの割合を作成します。次に、最終的なアニメーション文字列にプッシュします。

 Outeranimation.push( `
  $ {パーセント}%{
    変換:scaley($ {yscale});
  } `);

inneranimation.push( `
  $ {パーセント}%{
    変換:scaley($ {invsaley});
  } `);
ログイン後にコピー

最初に、完成したアニメーションを保存するスタイルタグを作成します。これはコンストラクターとして構築されているため、複数のパターンを簡単に追加できるようにするため、これらの生成されたアニメーションはすべて同じスタイルシートになりたいです。したがって、最初に、要素が存在することを確認します。存在しない場合は、それを作成し、意味のあるクラス名を追加します。それ以外の場合は、拡張可能なセクションごとにスタイルシートを取得することになりますが、これは理想的ではありません。

 var sectionease = document.queryselector( '。セクションアニメーション');
 if(!sectionease){
  sectionease = document.createelement( 'style');
  sectionease.classlist.add( 'section-animations');
 }
ログイン後にコピー

これについて言えば、あなたはすでに「拡張可能な部分が複数ある場合、同じ名前のアニメーションを使用していて、その内容が間違った値を持っている可能性がありますか?」と考えているかもしれません。

あなたは絶対に正しいです!これを防ぐために、動的なアニメーション名も生成します。とてもクールですよね?

querySelectorAll('.section')クエリを実行して、名前に一意の要素を追加する場合、コンストラクターに渡されたインデックスを使用します。

 var sectionexpandanimationname = "sectionexpandanimation" index;
var sectionExpandContentsAnimationName = "sectionExpandContentsAnimation"インデックス;
ログイン後にコピー

次に、この名前を使用して、現在拡張可能なセクションにCSS変数を設定します。この変数はこの範囲内にあるため、アニメーションをCSSの新しい変数として設定するだけで、各パターンはそれぞれのanimation-name値を取得します。

 .section.is--拡張{
  アニメーション名:var( -  sectionexpandanimation);
}

.is-expanded .section-item {
  アニメーション名:var( -  sectionexpandcontentsanimation);
}

.section.is  -  collapsed {
  アニメーション名:var( -  sectioncollapseanimation);
}

.is  -  collapsed .section-item {
  Animation-Name:var( -  sectionCollapseContentSanimation);
}
ログイン後にコピー

スクリプトの残りの部分は、イベントリスナーの追加、崩壊/展開状態、およびいくつかのヘルパー機能の改善の追加に関連しています。

HTMLおよびCSSについて:拡張可能な関数を適切に機能させるには、追加の作業が必要です。アニメーションを実行しない相対要素として追加のラッパーが必要です。拡張可能な子要素には絶対的な位置があるため、崩壊したときにスペースを占有しません。

リバースアニメーションを行う必要があるため、コンテンツの傾きを避けるためにフルサイズをスケーリングするようにすることを忘れないでください。

 .section-item-wrapper {
  min-height:var( -  title-height);
  位置:相対;
}

。セクション {
  アニメーション期間:300ms;
  アニメーション - タイミング機能:ステップエンド;
  含有:コンテンツ;
  左:0;
  位置:絶対;
  上:0;
  変換オリジン:左上。
  ウィルチェンジ:変換;
}

.section-item {
  アニメーション期間:300ms;
  アニメーション - タイミング機能:ステップエンド;
  含有:コンテンツ;
  変換オリジン:左上。
  ウィルチェンジ:変換;  
}
ログイン後にコピー

animation-timing-functionプロパティの重要性を強調したいと思います。各キーフレーム間の緩和を避けるために、 linearまたはstep-endに設定する必要があります。

あなたが知っているように、 will-changeプロパティは、よりスムーズな体験のために変換アニメーションのGPU加速度を有効にします。 contentsの値を持つcontainsプロパティを使用すると、ブラウザの他のツリーとは独立してブラウザプロセス要素が役立ち、レイアウト、スタイル、ドロー、サイズの属性を再計算する領域を制限します。

visibilityopacityを使用して、コンテンツを非表示にし、崩壊したときに画面読者がそれにアクセスしないようにします。

 .section-item-content {
  不透明:1;
  トランジション:不透明度500msの容易さ。
}

.is  -  collapsed .section-item-content {
  不透明:0;
  可視性:隠された;
}
ログイン後にコピー

最後に、拡張できる部分があります!これがあなたが見るための完全なコードとデモンストレーションです:

パフォーマンスチェック

アニメーションに対処するたびに、パフォーマンスを念頭に置いておく必要があります。開発者ツールを使用して、このすべての作業がパフォーマンスの面で価値があるかどうかを確認しましょう。 [パフォーマンス]タブ(Chrome Devtoolsを使用しています)を使用して、アニメーション中にFPSとCPUの使用を分析できます。

結果はとても良いです!

FPS測定ツールを使用して値をより詳細に確認すると、乱用であっても、常に60 fpsのマークに達することがわかります。

最終的な考慮事項

それで、最終的な結論は何ですか?これは他のすべての方法に取って代わりますか?これは「聖杯」の解決策ですか?

私の意見では、いいえ。

しかし...これは問題ではありません!リストのもう1つのソリューションです。また、他のアプローチと同様に、ユースケースをターゲットにする最良の方法であるかどうかを分析する必要があります。

この技術には利点があります。ポール・ルイスが言ったように、これには準備には多くの作業が必要です。ただし、一方で、ページが読み込まれているときに1回だけ行う必要があります。相互作用中、クラスを切り替えるだけです(場合によっては、アクセシビリティのために、またプロパティを切り替えます)。

ただし、これにより、要素のUIにいくつかの制限があります。拡張可能な部分要素でわかるように、逆スケーリングにより、フローティングアクションやメニューなどの絶対的およびオフキャンバス要素に対してより信頼性が高くなります。 overflow: hiddenを使用するため、境界線をスタイリングすることは困難です。

それにもかかわらず、このアプローチには大きな可能性があると思います。あなたの考えを教えてください!

以上がパフォーマンスの拡張可能なアニメーション:その場でキーフレームを構築しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Vue 3 Vue 3 Apr 02, 2025 pm 06:32 PM

それは' Vueチームにそれを成し遂げてくれておめでとうございます。それは大規模な努力であり、長い時間がかかったことを知っています。すべての新しいドキュメントも同様です。

ブラウザから有効なCSSプロパティ値を取得できますか? ブラウザから有効なCSSプロパティ値を取得できますか? Apr 02, 2025 pm 06:17 PM

私はこの非常に正当な質問で誰かに書いてもらいました。 Leaは、ブラウザから有効なCSSプロパティ自体を取得する方法についてブログを書いています。それはこのようなものです。

CI/CDで少し CI/CDで少し Apr 02, 2025 pm 06:21 PM

「ウェブサイト」は「モバイルアプリ」よりも適していると言いますが、Max Lynchからのこのフレーミングが好きです。

粘着性のあるポジショニングとサスのダッシュを備えた積み重ねられたカード 粘着性のあるポジショニングとサスのダッシュを備えた積み重ねられたカード Apr 03, 2025 am 10:30 AM

先日、Corey Ginnivanのウェブサイトから、この特に素敵なビットを見つけました。そこでは、スクロール中にカードのコレクションが互いに積み重ねられていました。

WordPressブロックエディターでのマークダウンとローカリゼーションを使用します WordPressブロックエディターでのマークダウンとローカリゼーションを使用します Apr 02, 2025 am 04:27 AM

WordPressエディターでユーザーに直接ドキュメントを表示する必要がある場合、それを行うための最良の方法は何ですか?

レスポンシブデザインのブラウザを比較します レスポンシブデザインのブラウザを比較します Apr 02, 2025 pm 06:25 PM

これらのデスクトップアプリがいくつかあり、目標があなたのサイトをさまざまな次元ですべて同時に表示しています。たとえば、書くことができます

フレックスレイアウト内の紫色のスラッシュ領域が誤って「オーバーフロー空間」と見なされるのはなぜですか? フレックスレイアウト内の紫色のスラッシュ領域が誤って「オーバーフロー空間」と見なされるのはなぜですか? Apr 05, 2025 pm 05:51 PM

フレックスレイアウトの紫色のスラッシュ領域に関する質問フレックスレイアウトを使用すると、開発者ツールなどの混乱する現象に遭遇する可能性があります(D ...

スティッキーヘッダーとフッターにCSSグリッドを使用する方法 スティッキーヘッダーとフッターにCSSグリッドを使用する方法 Apr 02, 2025 pm 06:29 PM

CSS Gridは、レイアウトをこれまで以上に簡単にするように設計されたプロパティのコレクションです。何でもするように、少し学習曲線がありますが、グリッドは

See all articles