Javascript動(dòng)畫效果(3)
前面我們已經(jīng)介紹了速度動(dòng)畫、透明度動(dòng)畫、多物體運(yùn)動(dòng)和任意值變化,并且我們?cè)?a target="_blank" href="http://www.dbjr.com.cn/article/94481.htm">Javascript動(dòng)畫效果(二)中介紹到我們封裝了一個(gè)簡(jiǎn)單的插件雛形,接下來我們對(duì)前面的動(dòng)畫效果進(jìn)行進(jìn)一步擴(kuò)充,盡量將我們的框架做到更實(shí)用。在這里我們還需要了解兩個(gè)運(yùn)動(dòng),一個(gè)是鏈?zhǔn)竭\(yùn)動(dòng),一個(gè)是同時(shí)運(yùn)動(dòng)。它們間的區(qū)別分別是:鏈?zhǔn)竭\(yùn)動(dòng)是指運(yùn)動(dòng)一個(gè)接著一個(gè)(一個(gè)運(yùn)動(dòng)完成馬上進(jìn)行下一個(gè)運(yùn)動(dòng));而同時(shí)運(yùn)動(dòng)是指所有的運(yùn)動(dòng)同時(shí)進(jìn)行。在這里,我們?cè)撊绾螌?shí)現(xiàn)呢?
1、鏈?zhǔn)竭\(yùn)動(dòng)
前面的效果中,我們已經(jīng)能對(duì)任意值進(jìn)行相應(yīng)的變化,我們?cè)撊绾卧谝粋€(gè)動(dòng)畫后添加一個(gè)動(dòng)畫呢?
思路:我們能不能在參數(shù)中傳入一個(gè)函數(shù),當(dāng)一個(gè)效果完成后馬上執(zhí)行后面的函數(shù)(效果),該函數(shù)可以是想要的動(dòng)畫效果
實(shí)現(xiàn):在function startMove(obj,attr,iTarget)中在傳入一個(gè)參數(shù)fn,代表一個(gè)函數(shù)。這時(shí)我們還需要修改的有在定時(shí)器的后面增加一個(gè)判斷if(fn){fn(); },當(dāng)存在fn函數(shù)時(shí)執(zhí)行fn函數(shù),當(dāng)不存在fn函數(shù)時(shí)清除定時(shí)器。這樣我們的window.onload函數(shù)也應(yīng)該發(fā)生相應(yīng)變化,代碼如下:
window.onload = function() { var Li = document.getElementById('li1'); Li.onmouseover = function() { startMove(Li, 'width', 400, function() { startMove(Li, 'height', 200, function() { startMove(Li, 'opacity', 100); }); }); }; Li.onmouseout = function() { startMove(Li, 'opacity', 30, function() { startMove(Li, 'height', 100, function() { startMove(Li, 'width', 200); }); }); }; };
所以我們得到鏈?zhǔn)竭\(yùn)動(dòng)的如下代碼:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>鏈?zhǔn)竭\(yùn)動(dòng)</title> <style type="text/css"> body,ul,li{ margin: 0px; padding: 0px; } ul,li{ list-style: none; } ul li{ width: 200px; height: 100px; background: yellow; margin-bottom: 20px; border: 4px solid #000; filter:alpha(opacity:30); opacity:0.3; } </style> </head> <body> <ul> <li id="li1"></li> </ul> <script type="text/javascript"> window.onload = function(){ var Li = document.getElementById('li1'); Li.onmouseover = function(){ startMove(Li,'width',400,function(){ startMove(Li,'height',200,function(){ startMove(Li,'opacity',100); }); }); }; Li.onmouseout = function(){ startMove(Li,'opacity',30,function(){ startMove(Li,'height',100,function(){ startMove(Li,'width',200); }); }); }; }; function startMove(obj,attr,iTarget,fn){ clearInterval(obj.timer); obj.timer = setInterval(function(){ var icur = 0; if(attr == 'opacity'){ icur = Math.round(parseFloat(getStyle(obj,attr))*100); }else{ icur = parseInt(getStyle(obj,attr)); } var speed = (iTarget - icur)/10; speed = speed>0?Math.ceil(speed):Math.floor(speed); if(iTarget == icur){ clearInterval(obj.timer); if(fn){ fn(); } } else{ if(attr == 'opacity'){ obj.style.filter = 'alpha(opacity:'+(icur+speed)+')'; obj.style.opacity = (icur+speed)/100; } else{ obj.style[attr] = icur+speed+'px'; } } },30) } function getStyle(obj,attr){ if(obj.currentStyle){ return obj.currentStyle[attr]; } else{ return getComputedStyle(obj,false)[attr]; } } </script> </body> </html>
2、同時(shí)運(yùn)動(dòng)
說到同時(shí)運(yùn)動(dòng),你可能會(huì)覺得很簡(jiǎn)單,直接在onmouseover事件后面同時(shí)添加兩個(gè)不同的starMove()函數(shù)就可以解決了(錯(cuò)誤思路!),實(shí)際上并不是這樣的,當(dāng)有多個(gè)效果時(shí),我們看到的是最后添加的那個(gè)效果。也就是說我們想同時(shí)改變寬度和高度(高度在后),我們得到的效果為只改變高度,寬度并沒有變化。這里我們應(yīng)該繼續(xù)傳參數(shù)么?從鏈?zhǔn)竭\(yùn)動(dòng)來看,傳參數(shù)的效果只能在后面添加函數(shù)得到連續(xù)的動(dòng)畫效果。
思路:我們可不可以用JSON的方法來同時(shí)改變多個(gè)動(dòng)畫效果?
實(shí)現(xiàn):將function startMove(obj,attr,iTarget,fn)中的attr和iTarget合并為一個(gè)參數(shù):json,我們用for/in的方法來遍歷json中的數(shù)據(jù),例如:
var json = {"a":12,"b":21}; for(var attr in json){ alert(json);//結(jié)果分別是:a,b alert(json[attr]);//結(jié)果分別是:12,21 }
按照此方法,我們依次改變前面的代碼:在定時(shí)器函數(shù)的后面加上代碼:for(var attr in json) {...},并且修改里面的iTarget為json[attr],再將window.onload函數(shù)修改為:
window.onload = function() { var Li = document.getElementById('li1'); Li.onmouseover = function() { startMove(Li, { width: 400, height: 200, opacity: 100 }); }; Li.onmouseout = function() { startMove(Li, { width: 200, height: 100, opacity: 30 }); }; };
這時(shí)我們差不多就可以得到我們想要的效果了,但是這樣離我們最終的效果還是查了那么一點(diǎn)點(diǎn),比如說我們將onmouseover事件中的starMove中的width修改為202,再執(zhí)行我們的代碼,我們會(huì)發(fā)現(xiàn)最終的height不是200px,opacity也不是100,如圖:
這樣就很尷尬了,之前我們的效果不是還蠻好的么?我們?cè)倩氐轿覀兊腏S代碼中分析結(jié)構(gòu),覺得最有可能出錯(cuò)的就是starMove函數(shù)中,我們發(fā)現(xiàn)這段代碼的意思有點(diǎn)難理解:
if(json[attr] == icur) { clearInterval(obj.timer); if(fn) { fn(); } }
我們并不知道是不是所有的運(yùn)動(dòng)都到達(dá)終點(diǎn)時(shí)停止所有運(yùn)動(dòng)還是當(dāng)只有一個(gè)運(yùn)動(dòng)達(dá)到終點(diǎn)時(shí)立馬停止所有運(yùn)動(dòng)。但是通過我們前面的操作,可以知道的實(shí)際結(jié)果為,只有一個(gè)運(yùn)動(dòng)到達(dá)終點(diǎn)值時(shí),所有的運(yùn)動(dòng)都停止了(此時(shí)還有運(yùn)動(dòng)沒執(zhí)行完),我們?cè)撊绾芜M(jìn)行操作呢?
思路:我們可以假定一個(gè)參數(shù)flag,并且賦值為true,在執(zhí)行clearInterval(obj.timer);操作前我們先進(jìn)行判斷if(json[attr] != icur) { flag = false;},后面執(zhí)行之前else里面的語句,再執(zhí)行如下語句if(flag = true) {clearInterval(obj.timer); if(fn) {fn();}},這樣我們就可以得到同時(shí)運(yùn)動(dòng)的完整代碼如下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>鏈?zhǔn)竭\(yùn)動(dòng)</title> <style type="text/css"> body,ul,li{ margin: 0px; padding: 0px; } ul,li{ list-style: none; } ul li{ width: 200px; height: 100px; background: yellow; margin-bottom: 20px; border: 4px solid #000; filter:alpha(opacity:30); opacity:0.3; } </style> </head> <body> <ul> <li id="li1"></li> </ul> <script type="text/javascript"> window.onload = function(){ var Li = document.getElementById('li1'); Li.onmouseover = function(){ startMove(Li,{width:202,height:200,opacity:100}); }; Li.onmouseout = function(){ startMove(Li,{width:200,height:100,opacity:30}); }; }; function getStyle(obj, attr) { if(obj.currentStyle) { return obj.currentStyle[attr]; } else { return getComputedStyle(obj, false)[attr]; } } function startMove(obj, json, fn) { //定義標(biāo)桿 var flag = true; //假設(shè)的 clearInterval(obj.timer); obj.timer = setInterval(function() { for(var attr in json) { var icur = 0; if(attr == 'opacity') { icur = Math.round(parseFloat(getStyle(obj, attr)) * 100); } else { icur = parseInt(getStyle(obj, attr)); } var speed = (json[attr] - icur) / 10; speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); if(json[attr] != icur) { flag = false; } if(attr == 'opacity') {//判斷是否為opacity obj.style.filter = 'alpha(opacity:' + (icur + speed) + ')'; obj.style.opacity = (icur + speed) / 100; } else { obj.style[attr] = icur + speed + 'px'; } if(flag){ clearInterval(obj.timer); if(fn){ fn(); } } } }, 30) } </script> </body> </html>
這樣我們的同時(shí)運(yùn)動(dòng)的動(dòng)畫效果就實(shí)現(xiàn)了。在這里,你有沒有覺得很神奇?
在這里我們已經(jīng)將一個(gè)簡(jiǎn)單的運(yùn)動(dòng)插件封裝完成了,我們將里面的代碼做一些解釋,并且將它保存為一個(gè)foodoir.animate.js文件,代碼如下:
/* * 簡(jiǎn)單的運(yùn)動(dòng)框架 * 作者:foodoir * 此框架僅作參考!??! * * 使用方法見博文 */ function getStyle(obj, attr) { if(obj.currentStyle) { return obj.currentStyle[attr]; } else { return getComputedStyle(obj, false)[attr]; } } function startMove(obj, json, fn) { clearInterval(obj.timer); //清除定時(shí)器,避免重復(fù)生成多個(gè)定時(shí)器 obj.timer = setInterval(function() { var flag = true; //假設(shè)剛開始時(shí)所有運(yùn)動(dòng)都已完成 for(var attr in json) { //遍歷json var icur = null; //1.判斷類型 if(attr == 'opacity') { icur = Math.round(parseFloat(getStyle(obj, attr)) * 100); } else { icur = parseInt(getStyle(obj, attr)); } //2.算速度 var speed = (json[attr] - icur) / 5; speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); //3.檢測(cè)停止 if(icur != json[attr]) { flag = false; } if(attr == 'opacity') { obj.style.filter = 'alpha(opacity:' + (icur + speed) + ')'; obj.style.opacity = (icur + speed) / 100; } else { obj.style[attr] = icur + speed + 'px'; } } if(flag) { //當(dāng)所有運(yùn)動(dòng)都完成時(shí),清除定時(shí)器 clearInterval(obj.timer); if(fn) { fn(); } } }, 30); }
后面,我們將介紹用自己的框架來實(shí)現(xiàn)多種動(dòng)畫效果,并且和jquery中的動(dòng)畫效果進(jìn)行比較。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
js判斷某個(gè)字符出現(xiàn)的次數(shù)的簡(jiǎn)單實(shí)例
下面小編就為大家?guī)硪黄猨s判斷某個(gè)字符出現(xiàn)的次數(shù)的簡(jiǎn)單實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-06-06關(guān)于js拖拽上傳 [一個(gè)拖拽上傳修改頭像的流程]
拖拽是操作系統(tǒng)用戶體驗(yàn)最偉大的改進(jìn)之一。它讓人隨心所欲的操作,更符合人們的直觀感受。2011-07-07javascript截取字符串(通過substring實(shí)現(xiàn)并支持中英文混合)
用js方法substring()、方法substr()實(shí)現(xiàn)如標(biāo)題所示的截取字符串并支持中英文混合,具體代碼如下,感興趣的各位可以參考下哈2013-06-06js實(shí)現(xiàn)使用鼠標(biāo)拖拽切換圖片的方法
這篇文章主要介紹了js實(shí)現(xiàn)使用鼠標(biāo)拖拽切換圖片的方法,涉及javascript操作圖片實(shí)現(xiàn)輪播效果的相關(guān)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-05-05JavaScript實(shí)現(xiàn)自動(dòng)彈出窗口并自動(dòng)關(guān)閉窗口的方法
這篇文章主要介紹了JavaScript實(shí)現(xiàn)自動(dòng)彈出窗口并自動(dòng)關(guān)閉窗口的方法,可實(shí)現(xiàn)從頁面左側(cè)彈出窗口5秒后窗口向右移動(dòng)并消失的效果,涉及javascript針對(duì)頁面窗口及樣式的定義操作技巧,需要的朋友可以參考下2015-08-08

webpack中CommonsChunkPlugin詳細(xì)教程(小結(jié))

微信小程序 獲取手機(jī)號(hào) JavaScript解密示例代碼詳解