カルーセル チャートのルートは、実際にはイージング関数のカプセル化です。カルーセル チャートが走行中の車である場合、イージング関数はそのエンジンです。今日、この記事では、単純なものから複雑なものまでを説明し、独自の関数をカプセル化します。イージング機能~~
需要の観点から始めて、最初に簡単な要件を与えます:
1. ページ上のボックスを開始位置から 200px まで一定の速度で右に移動させたいです。これ ?
分析:
1) ボックスがどこにあるかを知る必要があります。これは offsetLeft 属性を通じて取得できます
2) ボックスを一定の速度で移動させるには、js に setInterval が必ず必要です。 ) ボックスを右に移動するには、実行を開始しますか?つまり、マージン左と左の位置を含め、ボックスと左側の開始点の間の距離を常に変更する必要があります。ここでは、左の絶対位置を変更することにしました
4) 実行するときに停止する必要があります。開始点から 200px の距離、clearInterval を使用するだけです。
それでは、コードに直接進みましょう
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Document</title> <style type="text/css"> * { margin: 0; padding: 0; } div { position: absolute; top: 50px; width: 100px; height: 100px; background-color: red; } input { width: 100px; height: 30px; color: #fff; background-color: yellowgreen; } </style> </head> <body> <div></div> <input type="button" value="移动到200" /> <script type="text/javascript"> // 获取到元素(这里有个小细节,如果给元素设置了id名,即便不使用获取元素的方法,也能通过这个id名获取到元素哦~~大家可以自己尝试一下) var btn = document.querySelector('input'), dv = document.querySelector('div'); // 添加点击事件 btn.addEventListener('click',function() { var timer = null,// 保存定时器 currentDistance = dv.offsetLeft, // 当前离父盒子的距离 step = 8,// 每次改变的距离 target = 200;// 目标距离 timer = setInterval(function() { currentDistance += step;// 当前距离 = 上一个当前距离 + 改变的距离 if((target - currentDistance) < step) { currentDistance = target; // 如果目标距离与当前距离的差小于了要改变的距离,这时候我们就直接让当前距离等于目标距离,防止盒子停下来的时候有误差 clearInterval(timer); // 清楚定时器 timer = null; // 将timer解绑,释放内存 } dv.style.left = currentDistance + 'px'; // 最核心的一步,改变盒子的left为当前距离 },17) }) </script> </body> </html>
2. 予備的な移動効果が得られたら、要件を改善します:
ボックスが 200 ピクセルの位置に移動した後、ボックスを 200 ピクセルの位置に移動し続けますか? 400pxの位置?
分析:
1) この時点で、クリックするボタンは 2 つあり、1 つは 200px に移動し、もう 1 つは 400px に移動します
2) 2 つの動きがありますが、使用する機能は同じです。ある点が別の点に移動するので、1の移動を関数にカプセル化して再利用することを考えます。
コードをアップロードしてください~
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Document</title> <style type="text/css"> * { margin: 0; padding: 0; } div { position: absolute; top: 50px; width: 100px; height: 100px; background-color: red; } input { width: 100px; height: 30px; color: #fff; background-color: yellowgreen; } </style> </head> <body> <div></div> <input type="button" value="移动到200" /> <input type="button" value="移动到400" /> <script type="text/javascript"> // 封装函数,盒子和目标距离都是不确定的,我们可以将他们作为参数传递。 function animation(tag,target) { var timer = null, currentDistance = tag.offsetLeft, step = 5; step = currentDistance < target? step: -step;// 判断step的正负,200到400时是递增,400到200时是递减 timer = setInterval(function() { if(Math.abs(currentDistance - target) > Math.abs(step)) { // 这里判断条件也要略作改动,使用绝对值进行比较 currentDistance += step; / tag.style.left = currentDistance + 'px'; }else { tag.style.left = target + 'px' // 当当前距离与目标距离之间的差值小于step改变的距离时,我们直接让盒子移动到目标距离。 clearInterval(timer); timer = null; } },17) } var btns = document.querySelectorAll('input'), dv = document.querySelector('div'); btns[0].addEventListener('click',function() { animation(dv,200); }) btns[1].addEventListener('click',function() { animation(dv,400); }) </script> </body> </html>
3. ボックスを前後に移動させる関数をカプセル化しましたが、カルーセルのスクロール効果をもう一度考えてみましょう。均一な速度ではなく、非常にゴツゴツしています。スクロールが完了に近づくと、最初は 、速度が徐々に遅くなります。
要件: ボックスのイージング (つまり、可変速度の動き) を作成します
コードをアップロードします~
function animation(tag,target) { var timer = null; timer = setInterval(function() { var currentDistance = tag.offsetLeft, step = (target - currentDistance) / 5;// 通过目标距离与当前距离的差除以5便达到了我们需要的变速运动,因为step每次定制器执行都要改变,所以放入定时器内 step = step > 0 ? Math.ceil(step):Math.floor(step);// 这里如果将currentDistance定时器外面声明可以不用写,如果放在定时器内声明,因为offsetLeft取整的特性,要对step进行取整 if(Math.abs(currentDistance - target) > Math.abs(step)) { currentDistance += step; tag.style.left = currentDistance + 'px'; }else { tag.style.left = target + 'px' clearInterval(timer); timer = null; } },17)
さて、カルーセル チャートに必要な最も基本的なイージング関数が完成しました ~
より完全なイージング関数です 関数: その機能はより包括的であり、複数のスタイルを同時に変更できます。
function perfectAnimate(tag, obj, fn) {// 传三个参数,运动的盒子,对象(可以传多个属性),回调函数(在执行完后可以再执行自定义的功能) clearInterval(tag.timer);// 这里将定时器作为tag标签的属性保存,可以多次调用函数清除上一个定时器。 tag.timer = setInterval(function () { var flag = true; for (var k in obj) { // 因为并不是所有属性都带px单位,所以这里进行判断分别设置 if (k == 'opacity') { var currentDistance = getStyle(tag, k) * 100, target = obj[k] * 100, step = (target - currentDistance) / 10; step = step > 0 ? Math.ceil(step) : Math.floor(step); currentDistance += step; tag.style[k] = currentDistance / 100; } else if (k == 'zIndex') { tag.style[k] = obj[k]; else { var currentDistance = parseInt(getStyle(tag, k)) || 0, target = obj[k], step = (target - currentDistance) / 10; step = step > 0 ? Math.ceil(step) : Math.floor(step); currentDistance += step; tag.style[k] = currentDistance + 'px'; } if (target != currentDistance) { flag = false // 只要还有属性没有运动完成,就不会清楚定时器 } } if (flag) { clearInterval(tag.timer) fn && fn();// 所有定时器走完,这里执行回调函数,短路操作避免不传回调函数也不会报错。 } }, 17) }
以上がこの記事の全内容です。皆さんの学習に役立つことを願っています。また、皆さんも PHP 中国語 Web サイトをサポートしていただければ幸いです。
JS カルーセルでのイージング関数のカプセル化に関連するその他の記事については、PHP 中国語 Web サイトに注目してください。