溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

封裝運(yùn)動框架實(shí)戰(zhàn)左右與上下滑動的焦點(diǎn)輪播圖(實(shí)例)

發(fā)布時(shí)間:2020-09-10 09:04:23 來源:腳本之家 閱讀:130 作者:ghostwu 欄目:web開發(fā)

在這篇文章打造通用的勻速運(yùn)動框架(實(shí)例講解)中,封裝了一個(gè)勻速運(yùn)動框架,我們在這個(gè)框架的基礎(chǔ)之上,加上緩沖運(yùn)動效果,然后用運(yùn)動框架來做幻燈片(上下,左右)。

封裝運(yùn)動框架實(shí)戰(zhàn)左右與上下滑動的焦點(diǎn)輪播圖(實(shí)例)

緩沖運(yùn)動通常有兩種常見的表現(xiàn):比如讓一個(gè)div從0運(yùn)動到500,一種是事件觸發(fā)的時(shí)候,速度很快, 一種是事件觸發(fā)的時(shí)候慢,然后慢慢加快.我們來實(shí)現(xiàn)先塊后慢的,常見的就是開車,比如剛從高速路上下來的車,就是120km/小時(shí),然后進(jìn)入匝道,變成40km/時(shí). 或者40km/小時(shí)進(jìn)入小區(qū),最后停車,變成0km/小時(shí). 從120km/小時(shí)->40km/小時(shí), 或者40km->0km/小時(shí),都是速度先塊后慢,這種運(yùn)動怎么用程序來表示呢?

封裝運(yùn)動框架實(shí)戰(zhàn)左右與上下滑動的焦點(diǎn)輪播圖(實(shí)例)

可以用目標(biāo)距離( 500 ) - 當(dāng)前距離( 200 ) / 一個(gè)系數(shù)( 比如12 ),就能達(dá)到速度由塊而慢的變化,當(dāng)前距離在起點(diǎn),分子(500 - 0 )最大,所以速度最大,如果當(dāng)前距離快要接近500,分子最小,除完之后的速度也是最小。

<style>
 div{
  width: 200px;
  height: 200px;
  background:red;
  position: absolute;
  left: 0px;
 }
 </style>
 <script>
 window.onload = function(){
  var oBtn = document.querySelector( "input" ),
  oBox = document.querySelector( '#box' ),
  speed = 0, timer = null;
  oBtn.onclick = function(){
  timer = setInterval( function(){
   speed = ( 500 - oBox.offsetLeft ) / 8;
   oBox.style.left = oBox.offsetLeft + speed + 'px';
  }, 30 );
  }
 }
 </script>
</head>
<body>
 <input type="button" value="動起來">
 <div id="box"></div>
</body>
但是,div并不會乖乖地停止在500px這個(gè)目標(biāo)位置,最終卻是停在497.375px,只要查看當(dāng)前的速度,當(dāng)前的值就知道原因了
封裝運(yùn)動框架實(shí)戰(zhàn)左右與上下滑動的焦點(diǎn)輪播圖(實(shí)例)

封裝運(yùn)動框架實(shí)戰(zhàn)左右與上下滑動的焦點(diǎn)輪播圖(實(shí)例)

你會發(fā)現(xiàn),速度永遠(yuǎn)都在0.375這里停著,獲取到的當(dāng)前的距離停在497px? 這里有個(gè)問題,我們的div不是停在497.375px嗎,怎么獲取到的沒有了后面的小數(shù)0.375呢?計(jì)算機(jī)在處理浮點(diǎn)數(shù)會有精度損失。我們可以單獨(dú)做一個(gè)小測試:

<div id="box"></div>
 <script>
 var oBox = document.querySelector( '#box' );
 alert( oBox.offsetLeft );
 </script>

你會發(fā)現(xiàn)這段代碼獲取到左偏移是30px而不是行間樣式中寫的30.2px。因?yàn)樵讷@取當(dāng)前位置的時(shí)候,會舍去小數(shù),所以速度永遠(yuǎn)停在0.375px, 位置也是永遠(yuǎn)停在497,所以,為了到達(dá)目標(biāo),我們就得把速度變成1,對速度向上取整( Math.ceil ),我們就能把速度變成1,div也能到達(dá)500


oBtn.onclick = function(){
 timer = setInterval( function(){
 speed = ( 500 - oBox.offsetLeft ) / 8;
 if( speed > 0 ) {
  speed = Math.ceil( speed );
 }
 console.log( speed, oBox.offsetLeft );
 oBox.style.left = oBox.offsetLeft + speed + 'px';
 }, 30 );
}

第二個(gè)問題,如果div的位置是在900,也就是說從900運(yùn)動到500,有沒有這樣的需求呢? 肯定有啊,輪播圖,從右到左就是這樣的啊。

<style>
 #box{
  width: 200px;
  height: 200px;
  background:red;
  position: absolute;
  left: 900px;
 }
 </style>
 <script>// <![CDATA[
 window.onload = function(){
  var oBtn = document.querySelector( "input" ),
  oBox = document.querySelector( '#box' ),
  speed = 0, timer = null;
  oBtn.onclick = function(){
  timer = setInterval( function(){
   speed = ( 500 - oBox.offsetLeft ) / 8;
   if( speed > 0 ) {
   speed = Math.ceil( speed );
   }
   oBox.style.left = oBox.offsetLeft + speed + 'px';
  }, 30 );
  }
 }
 // ]]></script>
</head>
<body>
 <input type="button" value="動起來">
 <div id="box"></div>
</body>
最后目標(biāo)停在503.5px,速度這個(gè)時(shí)候是負(fù)值,最后速度停在-0.5,對于反方向的速度,我們就要把它變成-1,才能到達(dá)目標(biāo),所以用向下取整(Math.floor)
封裝運(yùn)動框架實(shí)戰(zhàn)左右與上下滑動的焦點(diǎn)輪播圖(實(shí)例)
oBtn.onclick = function(){
 timer = setInterval( function(){
 speed = ( 500 - oBox.offsetLeft ) / 8;
 if( speed > 0 ) {
  speed = Math.ceil( speed );
 }else {
  speed = Math.floor( speed );
 }
 console.log( speed, oBox.offsetLeft );
 oBox.style.left = oBox.offsetLeft + speed + 'px';
 }, 30 );
}

然后我們把這個(gè)緩沖運(yùn)動整合到勻速運(yùn)動框架,就變成:

function css(obj, attr, value) {
 if (arguments.length == 3) {
 obj.style[attr] = value;
 } else {
 if (obj.currentStyle) {
  return obj.currentStyle[attr];
 } else {
  return getComputedStyle(obj, false)[attr];
 }
 }
}

function animate(obj, attr, fn) {
 clearInterval(obj.timer);
 var cur = 0;
 var target = 0;
 var speed = 0;
 obj.timer = setInterval(function () {
 var bFlag = true;
 for (var key in attr) {
  if (key == 'opacity ') {
  cur = css(obj, 'opacity') * 100;
  } else {
  cur = parseInt(css(obj, key));
  }
  target = attr[key];
  speed = ( target - cur ) / 8;
  speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
  if (cur != target) {
  bFlag = false;
  if (key == 'opacity') {
   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 );
}

有了這勻速運(yùn)動框架,我們就來做幻燈片:

上下幻燈片的html樣式文件:

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>slide - by ghostwu</title>
 <link rel="stylesheet" href="css/slide3.css" rel="external nofollow" >
 <script src="js/animate.js"></script>
 <script src="js/slide.js"></script>
</head>
<body>
<div id="slide">
 <div id="slide-img">
 <div id="img-container">
  <img src="./img/1.jpg" alt="">
  <img src="./img/2.jpg" alt="">
  <img src="./img/3.jpg" alt="">
  <img src="./img/4.jpg" alt="">
  <img src="./img/5.jpg" alt="">
 </div>
 </div>
 <div id="slide-nums">
 <ul>
  <li class="active"></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
 </ul>
 </div>
</div>
</body>
</html>

slide3.css文件:

* {
 margin: 0;
 padding: 0;
}
li {
 list-style-type: none;
}
#slide {
 width: 800px;
 height: 450px;
 position: relative;
 margin:20px auto;
}
#slide-img {
 position: relative;
 width: 800px;
 height: 450px;
 overflow: hidden;
}
#img-container {
 position: absolute;
 left: 0px;
 top: 0px;
 height: 2250px;
 /*font-size:0px;*/
}
#img-container img {
 display: block;
 float: left;
}
#slide-nums {
 position: absolute;
 right:10px;
 bottom:10px;
}
#slide-nums li {
 float: left;
 margin:0px 10px;
 background: white;
 width: 20px;
 height: 20px;
 text-align: center;
 line-height: 20px;
 border-radius:10px;
 text-indent:-999px;
 opacity:0.6;
 filter:alpha(opacity:60);
 cursor:pointer;
}
#slide-nums li.active {
 background: red;
}

animate.js文件:

function css(obj, attr, value) {
 if (arguments.length == 3) {
 obj.style[attr] = value;
 } else {
 if (obj.currentStyle) {
  return obj.currentStyle[attr];
 } else {
  return getComputedStyle(obj, false)[attr];
 }
 }
}

function animate(obj, attr, fn) {
 clearInterval(obj.timer);
 var cur = 0;
 var target = 0;
 var speed = 0;
 obj.timer = setInterval(function () {
 var bFlag = true;
 for (var key in attr) {
  if (key == 'opacity ') {
  cur = css(obj, 'opacity') * 100;
  } else {
  cur = parseInt(css(obj, key));
  }
  target = attr[key];
  speed = ( target - cur ) / 8;
  speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
  if (cur != target) {
  bFlag = false;
  if (key == 'opacity') {
   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 );
}

slide.js文件:

window.onload = function () {
 function Slide() {
 this.oImgContainer = document.getElementById("img-container");
 this.aLi = document.getElementsByTagName("li");
 this.index = 0;
 }

 Slide.prototype.bind = function () {
 var that = this;
 for (var i = 0; i < this.aLi.length; i++) {
  this.aLi[i].index = i;
  this.aLi[i].onmouseover = function () {
  that.moveTop( this.index );
  }
 }
 }

 Slide.prototype.moveTop = function (i) {
 this.index = i;
 for( var j = 0; j < this.aLi.length; j++ ){
  this.aLi[j].className = '';
 }
 this.aLi[this.index].className = 'active';
 animate( this.oImgContainer, {
  "top" : -this.index * 450,
  "left" : 0
 });
 }
 
 var oSlide = new Slide();
 oSlide.bind();

}

左右幻燈片只需要改下樣式即可

樣式文件:

* {
 margin: 0;
 padding: 0;
}
li {
 list-style-type: none;
}
#slide {
 width: 800px;
 height: 450px;
 position: relative;
 margin:20px auto;
}
#slide-img {
 position: relative;
 width: 800px;
 height: 450px;
 overflow: hidden;
}
#img-container {
 position: absolute;
 left: 0px;
 top: 0px;
 width: 4000px;
}
#img-container img {
 display: block;
 float: left;
}
#slide-nums {
 position: absolute;
 right:10px;
 bottom:10px;
}
#slide-nums li {
 float: left;
 margin:0px 10px;
 background: white;
 width: 20px;
 height: 20px;
 text-align: center;
 line-height: 20px;
 border-radius:10px;
 text-indent:-999px;
 opacity:0.6;
 filter:alpha(opacity:60);
 cursor:pointer;
}
#slide-nums li.active {
 background: red;
}

js調(diào)用文件:

window.onload = function () {
 function Slide() {
 this.oImgContainer = document.getElementById("img-container");
 this.aLi = document.getElementsByTagName("li");
 this.index = 0;
 }

 Slide.prototype.bind = function () {
 var that = this;
 for (var i = 0; i < this.aLi.length; i++) {
  this.aLi[i].index = i;
  this.aLi[i].onmouseover = function () {
  that.moveLeft( this.index );
  }
 }
 }

 Slide.prototype.moveLeft = function (i) {
 this.index = i;
 for( var j = 0; j < this.aLi.length; j++ ){
  this.aLi[j].className = '';
 }
 this.aLi[this.index].className = 'active';
 animate( this.oImgContainer, {
  "left" : -this.index * 800
 });
 }
 
 var oSlide = new Slide();
 oSlide.bind();

}

以上這篇封裝運(yùn)動框架實(shí)戰(zhàn)左右與上下滑動的焦點(diǎn)輪播圖(實(shí)例)就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持億速云。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI