JavaScriptアニメーション関数のカプセル化の詳細な説明

JavaScriptアニメーション関数のカプセル化の詳細な説明

1. アニメーション機能の原理

基本原則: タイマー setInterval() を通じてボックスの位置を連続的に移動します。

実装手順:

  1. ボックスの現在の位置を取得する
  2. 箱を現在の位置に1移動距離追加します
  3. タイマーを使用してこの操作を繰り返す
  4. タイマーを終了する条件を追加する
  5. この要素は、element.style.leftを使用する前に配置する必要があることに注意してください。

以下のように表示されます。

ボックスが与えられたら、それをゆっくりと 300px の位置まで移動させます。

コードは次のとおりです。

<スタイル>
   div{
        位置: 絶対;
        左: 0;
        上: 0;
        幅: 100ピクセル;
        高さ: 100px;
        背景色: シアン;
    }
</スタイル>
</head>
<本文>
    <div></div>
    <スクリプト>
        var div = document.querySelector('div');
        var タイマー = setInterval(関数(){
            if(div.offsetLeft >= 300){
                タイマーの間隔をクリアします。
            }
            div.style.left = div.offsetLeft + 1 + 'px';
        },30); 
    </スクリプト>
</本文>

実行結果は次のとおりです。

正常に実行されました。

しかし、複数の要素を同時にアニメーション化する必要がある場合はどうでしょうか?これを単純なアニメーション関数にカプセル化することを検討できます。

2. アニメーション関数のシンプルなカプセル化

この関数は、アニメーション オブジェクトと移動距離の 2 つのパラメータを渡す必要があります。以下のように表示されます。

 関数 animate(obj,target){
            var タイマー = setInterval(関数(){
            if(obj.offsetLeft >= ターゲット){
                タイマーの間隔をクリアします。
            }
            obj.style.left = obj.offsetLeft + 1 + 'px';
        },30);
        }

上記のカプセル化された関数を呼び出すことでアニメーション効果を実現できます。たとえば、2 つの異なるボックスがある場合、アニメーション関数を個別に呼び出します。

 <スタイル>
       .box1{
            位置: 絶対;
            左: 0;
            上: 50px;
            幅: 100ピクセル;
            高さ: 100px;
            背景色: シアン;
        }
        .box2{
            位置: 絶対;
            左: 0;
            上: 155px;
            幅: 150ピクセル;
            高さ: 150px;
            背景色:ディープスカイブルー;
        }
    </スタイル>

<本文>
   <div class="box1"></div>
   <div class="box2"></div>
    <スクリプト>
        関数 animate(obj,target){
            var タイマー = setInterval(関数(){
            if(obj.offsetLeft >= ターゲット){
                タイマーの間隔をクリアします。
            }
            obj.style.left = obj.offsetLeft + 1 + 'px';
        },30);
        }
        var box1 = document.querySelector('.box1');
        var box2 = document.querySelector('.box2');
        アニメーション(ボックス1,300);
        アニメーション(ボックス2,400);
    </スクリプト>
</本文>

効果は次のとおりです。

アニメーション効果はうまく達成されました。

ただし、上記でカプセル化されたアニメーション関数にはまだ問題があります。アニメーション関数を呼び出すたびに、メモリ領域が解放されるため、メモリリソースが浪費されるという問題が発生します。さらに、毎回呼び出すアニメーション関数の名前は同じであるため、あいまいさが生じやすくなります。そのため、要素ごとに異なるタイマーを使用できます (独自のタイマーを使用)。

3. アニメーション関数は要素ごとに異なるタイマーを記録する

基本原則: JS は、現在のオブジェクトに属性を簡単に追加できる動的言語です。

オブジェクトに属性を追加してさまざまな要素にタイマーを追加することで、次のようにカプセル化できます。

関数 animate(obj,target){
  obj.timer = setInterval(関数(){
     if(obj.offsetLeft >= ターゲット){
         タイマー間隔をクリアします。
     }
     obj.style.left = obj.offsetLeft + 1 + 'px';
 },30);
}

もちろん、一連の操作を実行した後にのみ要素をアニメーション化したい場合は、特定のイベントを追加し、そのイベント内に関数呼び出しを記述することができます。

最初の例を例にとり、クリック イベントを追加すると、ボタンがクリックされたときにのみボックスが移動します。

 var box1 = document.querySelector('.box1');
        var btn = document.querySelector('ボタン')
       btn.addEventListener('click',function(){
            アニメーション(ボックス1,300);
        })

効果は次のとおりです。

効果は達成されましたが、ボタンをクリックし続けるとどうなるでしょうか?

ボタンをクリックし続けると、ボックスの実行速度がどんどん速くなることがわかります。これは、同時に開始したタイマーが多すぎるためです。どうすれば解決できるでしょうか?解決策は、要素が最初に前のタイマーをクリアし、実行するタイマーを 1 つだけ保持するようにして、関数の先頭でタイマーをクリアする操作を追加することです。コードは次のとおりです:

  関数 animate(obj,target){
            タイマー間隔をクリアします。
            obj.timer = setInterval(関数(){
            if(obj.offsetLeft >= ターゲット){
                タイマー間隔をクリアします。
            }
            obj.style.left = obj.offsetLeft + 1 + 'px';
        },30);
        }
        var box1 = document.querySelector('.box1');
        var btn = document.querySelector('ボタン');
       btn.addEventListener('click',function(){
            アニメーション(ボックス1,300);
        })

現時点での運用効果は

成功しました。

上記の一連の操作により、実装したアニメーションがすべて均一な速度であることがわかります。効果をより美しくするために、アニメーションを低速で実行することができます。

4. 緩和効果の原理

イージングアニメーションは要素の移動速度を変更するもので、最も一般的なのは速度をゆっくり停止することです。

  • アイデア: 箱が移動する距離を徐々に短くすると、速度もゆっくりと低下します。
  • コアアルゴリズム: (目標値 - 現在の位置) / 10 を各移動の距離ステップとして計算
  • 停止条件: 現在のボックスの位置が目標位置と等しいときにタイマーを停止します

ステップ値は切り上げられる必要があることに注意してください

上記の例では、ボタンをクリックすると、要素が低速で移動するようにします。カプセル化されたアニメーション関数を次のように変更できます。

関数 animate(obj,target){
            クリア間隔(obj.timer)
            obj.timer = setInterval(関数(){
                var ステップ = (ターゲット - obj.offsetLeft)/10;
            if(obj.offsetLeft == target){
                タイマー間隔をクリアします。
            }
            obj.style.left = obj.offsetLeft + ステップ + 'px';
        },30);
        }

効果は次のとおりです。

この効果の方が良く見えませんか?しかし、要素がどれだけ移動したかを確認してみましょう。正確に目標値の 300 ピクセルになっていますか?

確認してみると、要素が指定された位置に到達していないことがわかりました。これは、ステップの式に問題があるためです。除算演算を実行すると、小数点が出てくる可能性があり、位置のずれにつながります。したがって、ステップの式を四捨五入する必要があります。要素は前方(正の方向)に移動しているので、採用する戦略は切り上げです。

 var step = Math.ceil((target - obj.offsetLeft)/10);

それでは、最終目的地を見てみましょう。

現時点では、私たちはちょうど目標地点に到着したところです。

5. アニメーション機能は複数の目標値間を移動する

しかし、ステップ サイズが負の場合はどうなるでしょうか?

たとえば、現在ボックスがあり、それに 2 つのボタンを追加します。1 つは要素を 400 ピクセルに移動し、もう 1 つは要素を 700 ピクセルに移動します。

関数 animate(obj,target){
    クリア間隔(obj.timer)
     obj.timer = setInterval(関数(){
         var step = Math.ceil((target - obj.offsetLeft)/10);
     if(obj.offsetLeft >= ターゲット){
         タイマー間隔をクリアします。
     }
     obj.style.left = obj.offsetLeft + ステップ + 'px';
 },30);
}
 var box1 = document.querySelector('.box1');
 var btn = document.querySelectorAll('ボタン')
 btn[0].addEventListener('click',function(){
     アニメーション(ボックス1,400);
 })
  btn[1].addEventListener('click',function(){
     アニメーション(ボックス1,700);
 })

効果は次のとおりです。

このとき、前進すると要素は正確に目標位置に到達でき、要素は 2 ピクセル間の移動の効果も実現できますが、後退するときに到達する位置は目標位置ではないことがわかります。これは、要素が後退するときに反対方向に移動しているためです。このとき、ステップ長も反対の位置に丸める、つまり切り捨てる必要があります。

このとき、歩幅の条件を判断する必要があります。歩幅がゼロより大きい場合は切り上げます。歩幅がゼロより小さい場合は切り捨てます。調整された歩幅の計算式は次のとおりです。

 var ステップ = (ターゲット - obj.offsetLeft)/10;
 ステップ > 0 ですか? Math.ceil(step) : Math.floor(step);

それでは効果を見てみましょう:

問題は解決しました。

しかし、この時点では、要素を 2 つの場所間で移動するだけを実装しています。移動後に色を変更したい場合はどうすればよいでしょうか。これを実現するには、アニメーション関数にコールバック関数を追加します。

6. アニメーション関数にコールバック関数を追加する

コールバック関数の原則: 関数はパラメータとして使用できます。この関数を別の関数にパラメータとして渡します。その関数が実行されると、渡された関数が再度実行されます。この処理をコールバックと呼びます。

コールバック関数はタイマーが終了する場所に記述されます。

具体的な実装コードは次のとおりです。

 関数 animate(obj,target,callback){
            クリア間隔(obj.timer)
            obj.timer = setInterval(関数(){
                var ステップ = (ターゲット - obj.offsetLeft)/10;
                ステップ = ステップ > 0 ? Math.ceil(step) : Math.floor(step);
            if(obj.offsetLeft == target){
                タイマー間隔をクリアします。
                if(コールバック){
                    折り返し電話();
                } 
            }
            obj.style.left = obj.offsetLeft + ステップ + 'px';
            },30);
        }
        var box1 = document.querySelector('.box1');
        var btn = document.querySelectorAll('ボタン');
       btn[0].addEventListener('click',function(){
            アニメーション(ボックス1,400,関数(){
                box1.style.backgroundColor = 'ピンク';
            });
        })
        btn[1].addEventListener('click',function(){
            アニメーション(ボックス1,700,関数(){
                box1.style.backgroundColor = '赤';
            });
        })

効果は次のとおりです。

上記はアニメーション関数のカプセル化です。具体的に使用する場合は、js ファイルにカプセル化しておき、必要なときに直接参照することができます。

JavaScript アニメーション関数のカプセル化の詳細な説明に関するこの記事はこれで終わりです。JavaScript アニメーション関数のカプセル化に関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • JavaScriptスローモーションアニメーション機能のカプセル化方法
  • JavaScriptの速度変更アニメーション関数のカプセル化により、任意の数の属性が追加されます
  • JavaScript は左右のスローアニメーション機能を実装します
  • jQuery animate() アニメーション効果をネイティブ JS で実装する簡単な例

<<:  base target="" はフレームを開くためのベースリンクのターゲットを指定します

>>:  Linux ネットワーク システムの紹介

推薦する

Vue+Websocketはチャット機能を実装するだけです

この記事では、チャット機能を簡単に実装するためのVue+Websocketの具体的なコードを参考まで...

Tomcatの全体構造の簡単な紹介

Tomcat は Web コンテナとして広く知られています。Java を学び始めたときから現在の仕事...

珍しいけれど役に立つJSテクニックをいくつか紹介します

序文プログラミング言語には通常、さまざまな隠されたトリックが含まれており、これらのトリックを上手に使...

Mysql の一般的なベンチマーク コマンドの概要

mysqlslap共通パラメータの説明–auto-generate-sql システムはテスト用のSQ...

mysqlは、現在の時刻が開始時刻と終了時刻の間にあるかどうかを判断し、開始時刻と終了時刻が空であることが許可されます。

目次要件: 進行中のアクティビティ データを照会する次のSQLクエリは、上記の4つの要件を満たし、タ...

Linux で MySQL 5.7.19 をアンインストールする方法

1. MySQLが以前にインストールされていたかどうかを確認するコマンド: rpm -qa|grep...

手の動きをリアルタイムで監視するための Handtrack.js ライブラリ (推奨)

【はじめに】: Handtrack.jsは、ブラウザ上で直接リアルタイムの手の動きの追跡と検出を実...

Vue の foreach 配列と js の traversal 配列の書き方の説明

Vue foreach配列を記述し、jsで配列をトラバースする方法シナリオVueでAxiosを使用し...

仮想スクロールを簡単に実装するためのVueサンプルコード

目次序文ローリング原理成し遂げるソースコード参照する序文モバイル Web ページの日常的な開発では、...

Docker コンテナ データ ボリュームの名前付きマウントと匿名マウントの問題

目次コンテナデータボリュームとはコンテナ データ ボリュームが必要なのはなぜですか?使用データボリュ...

Docker-compose を使用して GitLab をデプロイする方法

Docker-compose は GitLab をデプロイします1. Dockerをインストールする...

Nest.js のハッシュと暗号化の例の詳細な説明

0x0 はじめにまず、ハッシュアルゴリズムとは何でしょうか?メッセージやセッション項目など、一部のデ...

Mysql データベースの日付と日時型でデフォルト値 0000-00-00 を設定するときに発生するエラー問題の詳細な説明

現象: MySQL バージョン 5.7 以降では、日付型と日付時刻型のデフォルト値が「0000-00...

フレックスマルチカラムレイアウトで発生する問題と解決策の詳細な説明

フレックス レイアウトは間違いなくシンプルで使いやすいです。レイアウトをよりシンプルかつ高速にします...

Linux ネットワークプログラミング機能の簡単な分析

目次1.ソケットを作成する2. ソケットをバインドする3. 聞き手を作る。聞く4. 接続が受け入れら...