ホームページ > ウェブフロントエンド > jsチュートリアル > 普遍的な等速運動フレームワークを作成する方法

普遍的な等速運動フレームワークを作成する方法

小云云
リリース: 2018-01-15 14:19:18
オリジナル
1246 人が閲覧しました

この記事では主にユニバーサル等速運動フレームワークの作成(例を挙げて解説)に関する記事をお届けします。編集者はこれが非常に良いものだと思ったので、皆さんの参考として今から共有します。編集者をフォローして見てみましょう。皆さんのお役に立てれば幸いです。

この記事は 均一モーション (サイドバー、フェードイン、フェードアウト) に基づく説明 の続きであり、この記事の最後に、サイドバーとフェードインとフェードアウトの 2 つの小さな例を作成しました。透明度効果を変更するには、この記事では、上記のアニメーション関数を引き続き変形して、より多用途かつ強力なものにします:

1、複数のオブジェクトの動きをサポートします

2、同時に動きます

3. 順次移動

これら 3 つの移動方法は、jquery の animate 関数でもサポートされています

1. animate 関数の異なるスタイルを区別するにはどうすればよいですか?

上記では、サイドバー効果に使用されるanimate関数は左の値を変更します


function animate(obj, target, speed) {
 clearInterval(timer);
 timer = setInterval(function () {
 if (obj.offsetLeft == target) {
  clearInterval(timer);
 } else {
  obj.style.left = obj.offsetLeft + speed + 'px';
 }
 }, 30);
}
ログイン後にコピー

フェードイン、フェードアウト効果に使用されるanimate関数は透明度を変更します


function animate(obj, target, speed) {
  clearInterval(timer);
  var cur = 0;
  timer = setInterval(function () {
   cur = css( obj, 'opacity') * 100;
   if( cur == target ){
   clearInterval( timer );
   }else {
   cur += speed;
   obj.style.opacity = cur / 100;
   obj.style.filter = "alpha(opacity:" + cur + ")";
   }
  }, 30);
  }
ログイン後にコピー

そしてカプセル化する関数は普遍的になるために、この関数が左の値と透明度の変更を同時にサポートしなければならないという問題に直面します。より一般的なアプローチは、カルーセル関数などのすべてのスタイル変更をサポートすることです。左右のスライドと上下のスライドがあります。

他のスタイル(マージン、左、上、右、フォントサイズなど)は、スタイルを取得するときとスタイルを変更するときに判断するだけで、目的を達成するために2つのカテゴリに分けることができます。すべて px であり、透明度の px 単位はありません


function animate(obj, attr, target, speed) {
 clearInterval(timer);
 var cur = 0;
 timer = setInterval(function () {
 if (attr == 'opacity') {
  cur = css(obj, 'opacity') * 100;
 } else {
  cur = parseInt(css(obj, attr));
 }

 if (cur == target) {
  clearInterval(timer);
 } else {
  if (attr == 'opacity') {
  obj.style.opacity = ( cur + speed ) / 100;
  obj.style.filter = "alpha(opacity:" + (cur + speed) + ")";
  } else {
  obj.style[attr] = cur + speed + "px";
  }
 }
 }, 30);
}
ログイン後にコピー

マージされたアニメーションには、以前よりも 1 つ多くのパラメーター attr があります。このパラメーターは、変更されたスタイル、obj: 変更されたオブジェクト、target: スタイルが適用されるターゲット値です。変更する必要があります。speed: スタイルの各変更のサイズ

例:


oImg.onmouseover = function () {
  animate(this, 'opacity', 100, 10);
}
ログイン後にコピー

oImg は、ここでの各パラメータの意味は次のとおりです:

this: 現在の画像。オブジェクト

opacity: 変更されたスタイルは透明度です

100: マウスが画像上に移動すると、透明度は 100 になります

10: 透明度は、元の値に基づいて毎回 10 ずつ増加します


<!doctype html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>合并的运动 - by ghostwu</title>
 <style>
 img {
  border: none;
  opacity: 0.3;
  filter: alpha(opacity:30);
  position: absolute;
  left: 200px;
 }

 #box {
  width: 150px;
  height: 300px;
  background: red;
  position: absolute;
  left: -150px;
  top: 50px;
 }

 #box p {
  width: 28px;
  height: 100px;
  position: absolute;
  right: -28px;
  top: 100px;
  background: green;
 }
 </style>
 <script>
 window.onload = function () {
  var oImg = document.getElementById("img"),
  oBox = document.getElementById("box"),
  timer = null;

  oImg.onmouseover = function () {
  animate(this, &#39;opacity&#39;, 100, 10);
  }
  oImg.onmouseout = function () {
  animate(this, &#39;opacity&#39;, 30, -10);
  }

  oBox.onmouseover = function () {
  animate(this, &#39;left&#39;, 0, 10);
  }

  oBox.onmouseout = function () {
  animate(this, &#39;left&#39;, -150, -10);
  }

  function animate(obj, attr, target, speed) {
  clearInterval(timer);
  var cur = 0;
  timer = setInterval(function () {
   if (attr == &#39;opacity&#39;) {
   cur = css(obj, &#39;opacity&#39;) * 100;
   } else {
   cur = parseInt(css(obj, attr));
   }

   if (cur == target) {
   clearInterval(timer);
   } else {
   if (attr == &#39;opacity&#39;) {
    obj.style.opacity = ( cur + speed ) / 100;
    obj.style.filter = "alpha(opacity:" + (cur + speed) + ")";
   } else {
    obj.style[attr] = cur + speed + "px";
   }
   }
  }, 30);
  }

  function css(obj, attr) {
  if (obj.currentStyle) {
   return obj.currentStyle[attr];
  } else {
   return getComputedStyle(obj, false)[attr];
  }
  }
 }
 </script>
</head>
<body>
<p id="box">
 <p>分享到</p>
</p>
<img src="./img/h4.jpg" alt="" id="img"/>
</body>
</html>
ログイン後にコピー

。上記は完全なコード例です。

これら 2 つの関数を個別にテストする場合:

画像に移動してから移動します

共有先に移動してから移動します

これは問題ありません

次のようにテストする場合:

共有に移動を選択し、すぐに画像に移動すると、共有が停止したことがわかります。論理的に言えば、マウスを画像に移動することは、「共有先」のマウスアウトをトリガーすることと同じです。イベント)の場合、この時点では「共有先」を停止するのではなく、非表示にする必要があります。 なぜそうなるのでしょうか?これら 2 つのスポーツはタイマーを共有しているため、マウスが画像上に移動してタイマーがオンになると、「共有」タイマーが停止します。したがって、複数のオブジェクトのモーションを行う場合は、各オブジェクトにタイマーを分割する必要があります。 非常に簡単です。単純なタイマー変数を定義する必要はありません。obj オブジェクトにタイマーを追加するだけで、タイマーの分離効果が得られます。 、ご自身で行ってください 展開:

<!doctype html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Document</title>
 <style>
 img {
  border: none;
  opacity: 0.3;
  filter: alpha(opacity:30);
  position: absolute;
  left: 200px;
 }

 #box {
  width: 150px;
  height: 300px;
  background: red;
  position: absolute;
  left: -150px;
  top: 50px;
 }

 #box p {
  width: 28px;
  height: 100px;
  position: absolute;
  right: -28px;
  top: 100px;
  background: green;
 }
 </style>
 <script>
 window.onload = function () {
  var oImg = document.getElementById("img"),
  oBox = document.getElementById("box");

  oImg.onmouseover = function () {
  animate(this, &#39;opacity&#39;, 100, 10);
  }
  oImg.onmouseout = function () {
  animate(this, &#39;opacity&#39;, 30, -10);
  }

  oBox.onmouseover = function () {
  animate(this, &#39;left&#39;, 0, 10);
  }

  oBox.onmouseout = function () {
  animate(this, &#39;left&#39;, -150, -10);
  }

  function animate(obj, attr, target, speed) {
  clearInterval(obj.timer);
  var cur = 0;
  obj.timer = setInterval(function () {
   if (attr == &#39;opacity&#39;) {
   cur = css(obj, &#39;opacity&#39;) * 100;
   } else {
   cur = parseInt(css(obj, attr));
   }

   if (cur == target) {
   clearInterval(obj.timer);
   } else {
   if (attr == &#39;opacity&#39;) {
    obj.style.opacity = ( cur + speed ) / 100;
    obj.style.filter = "alpha(opacity:" + (cur + speed) + ")";
   } else {
    obj.style[attr] = cur + speed + "px";
   }
   }
  }, 30);
  }

  function css(obj, attr) {
  if (obj.currentStyle) {
   return obj.currentStyle[attr];
  } else {
   return getComputedStyle(obj, false)[attr];
  }
  }
 }
 </script>
</head>
<body>
<p id="box">
 <p>分享到</p>
</p>
<img src="./img/h4.jpg" alt="" id="img"/>
</body>
</html>
ログイン後にコピー

この時点で、マルチオブジェクトモーションとさまざまなスタイルの変更が完了しました

次に、アニメーション関数で複数のスタイルの同時変更をサポートさせます 例:

oBox.onmouseover = function(){
  animate( this, { "width" : 500, "height" : 400 }, 10 );
}
ログイン後にコピー

oBox animateの各パラメータの意味:

this: 現在のp要素

{width : 500, "height" : 400 } : 幅を変更します。これら 2 つのスタイルは同じである必要があります 完了時間、

10: スタイルは元の基準に基づいて毎回 10 ずつ変更されます (幅の初期値 200-> 210、220、など) 230....)

完全な同時動作変更コード:

<!doctype html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Document</title>
 <style>
 p {
 width: 200px;
 height: 200px;
 background: red;
 }
 </style>
 <script>
 window.onload = function () {
  var oBox = document.getElementById("box");
  oBox.onmouseover = function(){
//  animate( this, { "width" : 500, "height" : 500 }, 10 );
  animate( this, { "width" : 500, "height" : 400 }, 10 );
  }

  function animate(obj, attr, speed) {
  clearInterval(obj.timer);
  var cur = 0;
  obj.timer = setInterval(function () {
   for ( var key in attr ) {
   if (key == &#39;opacity&#39;) {
    cur = css(obj, &#39;opacity&#39;) * 100;
   } else {
    cur = parseInt(css(obj, key));
   }
   var target = attr[key];
   if (cur == target) {
    clearInterval(obj.timer);
   } else {
    if (key == &#39;opacity&#39;) {
    obj.style.opacity = ( cur + speed ) / 100;
    obj.style.filter = "alpha(opacity:" + (cur + speed) + ")";
    } else {
    obj.style[key] = cur + speed + "px";
    }
   }
   }
  }, 30);
  }

  function css(obj, attr) {
  if (obj.currentStyle) {
   return obj.currentStyle[attr];
  } else {
   return getComputedStyle(obj, false)[attr];
  }
  }
 }
 </script>
</head>
<body>
 <p id="box"></p>
</body>
</html>
ログイン後にコピー

このコードは自分で拡張してください このコードは同時に動かすことができますが、問題があります:

の初期の幅と高さです。 p(幅:200、高さ:200)

変更ステップサイズは同じ(10)

変更時間は同じ(30ミリ秒ごとに変更)

ターゲット(幅:500、高さ:400)

できる何か問題があると思いますか? (2 人が同じスタートラインにおり、同じ速度、同じタイムですが、同時に異なる目標に到達する必要があります。1 人は 500 点、もう 1 人は 400 点です)

答えは明白です。最も近いターゲット (高さ: 400) を持つターゲットが最初に到達し、オブジェクトのタイマーをオフにすると、遠くにあるもう一方のターゲット (幅: 500) には絶対に到達しません

このコードの下の値とターゲット値:

var target = attr[key];
console.log( key, cur, target );
ログイン後にコピー

出力 結果は次のようになります:

从上图可以看出,height已经达到了400px,但是width停在了410px,为什么不是400px ? 因为width = 400的时候, 就是( cur == 500 ) 相当于( 400 == 500 ) 不成立,所以执行了else语句,width = cur + 10 = 400 + 10 = 410,然后height到达400px停止了定时器,所以width停在了410px.

那么我们怎么解决这个问题呢?

其实也好办,就是height = 400的时候 不要把定时器关了,应该等width = 500的时候再关闭定时器,不就在同一时间,完成了同时到达目标的效果吗?

修改后的代码如下:


<!doctype html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Document</title>
 <style>
 p {
 width: 200px;
 height: 200px;
 background: red;
 }
 </style>
 <script>
 window.onload = function () {
  var oBox = document.getElementById("box");
  oBox.onmouseover = function(){
  animate( this, { "width" : 500, "height" : 400 }, 10 );
  }

  function animate(obj, attr, speed) {
  clearInterval(obj.timer);
  var cur = 0;
  obj.timer = setInterval(function () {
   var bFlag = true;
   for ( var key in attr ) {
   if (key == &#39;opacity&#39;) {
    cur = css(obj, &#39;opacity&#39;) * 100;
   } else {
    cur = parseInt(css(obj, key));
   }
   var target = attr[key];
   if (cur != target) {
    bFlag = false;
    if (key == &#39;opacity&#39;) {
    obj.style.opacity = ( cur + speed ) / 100;
    obj.style.filter = "alpha(opacity:" + (cur + speed) + ")";
    } else {
    obj.style[key] = cur + speed + "px";
    }
   }
   }
   if ( bFlag ) {
   clearInterval( obj.timer );
   }
  }, 30);
  }

  function css(obj, attr) {
  if (obj.currentStyle) {
   return obj.currentStyle[attr];
  } else {
   return getComputedStyle(obj, false)[attr];
  }
  }
 }
 </script>
</head>
<body>
 <p id="box"></p>
</body>
</html>
ログイン後にコピー

声明一个变量,每次变化完一次( width, height )样式 把bFlag = true, 只要在for循环中有一个没有到达目标,bFlag的值都是false,这样就不会关闭定时器。当两个都到达目标,才关闭定时器.

三、顺序运动

如样式变化,按顺序来,不是同时变化, 如:


oBox.onmouseover = function(){
//回调函数: 把函数当做参数传递给另一个函数
  animate( this, { &#39;width&#39; : 500 }, 10, function(){
    animate( this, { &#39;height&#39; : 500 }, 10 );
  } );
}
ログイン後にコピー

当把width变成500px的时候,如果传递了回调函数, 再接着执行回调函数里面的运动

修改后的完整代码:


<!DOCTYPE html>
<html>
<head lang="en">
 <meta charset="UTF-8">
 <title>通用的匀速运动框架 - by ghostwu</title>
 <style>
 p {
  width: 200px;
  height: 200px;
  background: red;
 }
 </style>
 <script>
 window.onload = function () {
  var oBox = document.getElementById("box");
  oBox.onmouseover = function(){
  //回调函数: 把函数当做参数传递给另一个函数
  animate( this, { &#39;width&#39; : 500 }, 10, function(){
   animate( this, { &#39;height&#39; : 500 }, 10 );
  } );
  }

  function animate(obj, attr, speed, fn ) {

  clearInterval(obj.timer);
  var cur = 0;
  obj.timer = setInterval(function () {
   var bFlag = true;
   for (var key in attr) {
   if (key == &#39;opacity&#39;) {
    cur = css(obj, &#39;opacity&#39;) * 100;
   } else {
    cur = parseInt(css(obj, key));
   }
   var target = attr[key];
   if (cur != target) {
    bFlag = false;
    if (key == &#39;opacity&#39;) {
    obj.style.opacity = ( cur + speed ) / 100;
    obj.style.filter = "alpha(opacity:" + (cur + speed) + ")";
    } else {
    obj.style[key] = cur + speed + "px";
    }
   }
   }

   if (bFlag) {
   clearInterval(obj.timer);
   fn && fn.call( obj );
   }
  }, 30);
  }

  function css(obj, attr) {
  if (obj.currentStyle) {
   return obj.currentStyle[attr];
  } else {
   return getComputedStyle(obj, false)[attr];
  }
  }
 }
 </script>
</head>
<body>
<p id="box"></p>
</body>
</html>
ログイン後にコピー

相关推荐:

基于js匀速运动的实例讲解

用js指定步长实现单方向匀速运动

浅谈Javascript如何实现匀速运动_javascript技巧

以上が普遍的な等速運動フレームワークを作成する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート