封裝運(yùn)動(dòng)框架實(shí)戰(zhàn)左右與上下滑動(dòng)的焦點(diǎn)輪播圖(實(shí)例)
在這篇文章打造通用的勻速運(yùn)動(dòng)框架(實(shí)例講解)中,封裝了一個(gè)勻速運(yùn)動(dòng)框架,我們?cè)谶@個(gè)框架的基礎(chǔ)之上,加上緩沖運(yùn)動(dòng)效果,然后用運(yùn)動(dòng)框架來(lái)做幻燈片(上下,左右)。
緩沖運(yùn)動(dòng)通常有兩種常見(jiàn)的表現(xiàn):比如讓一個(gè)div從0運(yùn)動(dòng)到500,一種是事件觸發(fā)的時(shí)候,速度很快, 一種是事件觸發(fā)的時(shí)候慢,然后慢慢加快.我們來(lái)實(shí)現(xiàn)先塊后慢的,常見(jiàn)的就是開(kāi)車(chē),比如剛從高速路上下來(lái)的車(chē),就是120km/小時(shí),然后進(jìn)入匝道,變成40km/時(shí). 或者40km/小時(shí)進(jìn)入小區(qū),最后停車(chē),變成0km/小時(shí). 從120km/小時(shí)->40km/小時(shí), 或者40km->0km/小時(shí),都是速度先塊后慢,這種運(yùn)動(dòng)怎么用程序來(lái)表示呢?
可以用目標(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="動(dòng)起來(lái)"> <div id="box"></div> </body>


你會(huì)發(fā)現(xiàn),速度永遠(yuǎn)都在0.375這里停著,獲取到的當(dāng)前的距離停在497px? 這里有個(gè)問(wèn)題,我們的div不是停在497.375px嗎,怎么獲取到的沒(méi)有了后面的小數(shù)0.375呢?計(jì)算機(jī)在處理浮點(diǎn)數(shù)會(huì)有精度損失。我們可以單獨(dú)做一個(gè)小測(cè)試:
<div id="box"></div> <script> var oBox = document.querySelector( '#box' ); alert( oBox.offsetLeft ); </script>
你會(huì)發(fā)現(xiàn)這段代碼獲取到左偏移是30px而不是行間樣式中寫(xiě)的30.2px。因?yàn)樵讷@取當(dāng)前位置的時(shí)候,會(huì)舍去小數(shù),所以速度永遠(yuǎn)停在0.375px, 位置也是永遠(yuǎn)停在497,所以,為了到達(dá)目標(biāo),我們就得把速度變成1,對(duì)速度向上取整( 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è)問(wèn)題,如果div的位置是在900,也就是說(shuō)從900運(yùn)動(dòng)到500,有沒(méi)有這樣的需求呢? 肯定有啊,輪播圖,從右到左就是這樣的啊。
<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="動(dòng)起來(lái)"> <div id="box"></div> </body>

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)動(dòng)整合到勻速運(yùn)動(dòng)框架,就變成:
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)動(dòng)框架,我們就來(lái)做幻燈片:
上下幻燈片的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)動(dòng)框架實(shí)戰(zhàn)左右與上下滑動(dòng)的焦點(diǎn)輪播圖(實(shí)例)就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
JavaScript實(shí)現(xiàn)網(wǎng)頁(yè)截屏的5種方法小結(jié)
本文主要介紹了JavaScript實(shí)現(xiàn)網(wǎng)頁(yè)截屏的5種方法小結(jié),感興趣的可以了解一下2009-10-10JS實(shí)現(xiàn)touch 點(diǎn)擊滑動(dòng)輪播實(shí)例代碼
這篇文章主要介紹了JS實(shí)現(xiàn)touch 點(diǎn)擊滑動(dòng)輪播實(shí)例代碼,需要的朋友可以參考下2017-01-01window.print()前端實(shí)現(xiàn)網(wǎng)頁(yè)打印功能詳解
JavaScript 函數(shù)window.print()可用于打印你的應(yīng)用的內(nèi)容,但是它針對(duì)的是使用默認(rèn)打印體驗(yàn)打印顯示在屏幕上的內(nèi)容,這篇文章主要給大家介紹了關(guān)于window.print()前端實(shí)現(xiàn)網(wǎng)頁(yè)打印功能的相關(guān)資料,需要的朋友可以參考下2024-04-04JavaScript使用delete刪除數(shù)組元素用法示例【數(shù)組長(zhǎng)度不變】
這篇文章主要介紹了JavaScript使用delete刪除數(shù)組元素用法,結(jié)合實(shí)例形式分析了delete刪除數(shù)組元素的具體用法與注意事項(xiàng),需要的朋友可以參考下2017-01-01在原生不支持的舊環(huán)境中添加兼容的Object.keys實(shí)現(xiàn)方法
下面小編就為大家?guī)?lái)一篇在原生不支持的舊環(huán)境中添加兼容的Object.keys實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-09-09Ajax與Axios的基礎(chǔ)知識(shí)以及詳細(xì)對(duì)比總結(jié)
在Web開(kāi)發(fā)中Ajax和Axios是兩種實(shí)現(xiàn)異步數(shù)據(jù)請(qǐng)求的技術(shù),Ajax可以在不刷新頁(yè)面的情況下與服務(wù)器通信,Axios是一個(gè)基于Promise的HTTP客戶(hù)端,簡(jiǎn)化了HTTP請(qǐng)求的過(guò)程,兩者都能處理多種數(shù)據(jù)格式,這篇文章主要介紹了Ajax與Axios的基礎(chǔ)知識(shí)以及詳細(xì)對(duì)比總結(jié),需要的朋友可以參考下2024-09-09js中各種數(shù)據(jù)類(lèi)型檢測(cè)和判定的實(shí)戰(zhàn)示例
typeof一般被用于判斷一個(gè)變量的類(lèi)型,我們可以利用typeof來(lái)判斷number,string,object,boolean,function,undefined,symbol這七種類(lèi)型,下面這篇文章主要給大家介紹了關(guān)于js中各種數(shù)據(jù)類(lèi)型檢測(cè)和判定的相關(guān)資料,需要的朋友可以參考下2022-11-11