国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JavaScript完美運動框架的進階之旅

Pines_Cheng / 844人閱讀

摘要:運動框架動起來進行運動的節(jié)點定時器你沒看錯,就是那么簡單。直接在定時器內(nèi)部,判斷到達目標值,清除定時器就行拉運動框架運動終止進行運動的節(jié)點運動終止條件。

轉(zhuǎn)自個人博客三省吾身丶丶
原來是JS動畫效果,但是我會過頭再看的時候,發(fā)現(xiàn)太粗略了,于是重新寫了一篇。
喜歡別只收藏啊,點個推薦,大兄弟^ ^!

運動框架的實現(xiàn)思路

運動,其實就是在一段時間內(nèi)改變leftrightwidthheightopactiy的值,到達目的地之后停止。

現(xiàn)在按照以下步驟來進行我們的運動框架的封裝:

勻速運動。

緩沖運動。

多物體運動。

任意值變化。

鏈式運動。

同時運動。

(一)勻速運動 速度動畫 運動基礎(chǔ)

思考:如何讓div動起來?
如下:

設(shè)置元素為絕對定位,只有絕對定位后,left,top等值才生效。

定時器的使用(動態(tài)改變值),這里使用setInterval()每隔指定的時間執(zhí)行代碼。

計時器setInterval(函數(shù),交互時間(毫秒)):在執(zhí)行時,從載入頁面后每隔指定的時間執(zhí)行代碼。

取消計時器clearInterval(函數(shù)) 方法可取消由 setInterval() 設(shè)置的交互時間。

獲取當前的位置,大小等等。offsetLeft(當前元素相對父元素位置)。

速度--物體運動的快慢

定時器間隔時間

改變值的大小

根據(jù)上面的信息我們就可以開始封裝運動框架創(chuàng)建一個變化的div了。

/**
 * 運動框架-1-動起來
 * @param {HTMLElement} element 進行運動的節(jié)點
 */
var timer = null;
function startMove(element) {
    timer = setInterval(function () {//定時器
        element.style.left = element.offsetLeft + 5 + "px";
    }, 30);
}

你沒看錯,就是那么簡單。但是等等, what? 怎么不會停?WTF?

那是因為我們沒有運動終止條件。好再還是比較簡單。直接在定時器內(nèi)部,判斷到達目標值,清除定時器就行拉!

/**
 * 運動框架-2-運動終止
 * @param {HTMLElement} element 進行運動的節(jié)點
 * @param {number}      iTarget 運動終止條件。
 */
 var timer = null;
function startMove(element, iTarget) {
    timer = setInterval(function () {
        element.style.left = element.offsetLeft + 5 + "px";
        if (element.offsetLeft === iTarget) {//停止條件
            clearInterval(timer);
        }
    }, 30);
}

就這樣是不是就完成了呢?已經(jīng)ok了呢?
no。還有一些Bug需要處理。

運動中的Bug

速度取到某些值會無法停止

到達位置后再點擊還會運動

重復(fù)點擊速度加快

速度無法更改

解決BUG

速度取到某些值會無法停止(這個Bug稍后解決,在進化過程中自然解決)

把運動和停止隔開(if/else)

在開始運動時,關(guān)閉已有定時器

把速度用變量保存

/**
 * 運動框架-3-解決Bug
 */
var timer = null;
function startMove(element, iTarget) {
    clearInterval(timer);//在開始運動時,關(guān)閉已有定時器
    timer = setInterval(function () {
        var iSpeed = 5;//把速度用變量保存
        //把運動和停止隔開(if/else)
        if (element.offsetLeft === iTarget) {//結(jié)束運動
            clearInterval(timer);
        } else {
            element.style.left = element.offsetLeft + iSpeed + "px";
        }
    }, 30);
}

這樣一個簡單的運動框架就完成了。但是,再等等。只能向右走?別急,我們不是定義了把速度變成為了變量嗎?只需要對它進行一些處理就行啦!
var iSpeed = 5;-->

//判斷距離目標位置,達到自動變化速度正負
var iSpeed = 0;
if (element.offsetLeft < iTarget) {
    iSpeed = 5;
} else {
    iSpeed = -5;
}
透明度動畫

用變量alpha儲存當前透明度。

把上面的element.offsetLeft改成變量alpha

運動和停止條件部分進行更改。如下:

//透明度瀏覽器兼容實現(xiàn)
if (alpha === iTarget) {
    clearInterval(time);
} else {
    alpha += speed;
    element.style.filter = "alpha(opacity:" + alpha + ")"; //兼容IE
    element.style.opacity = alpha / 100;//標準
}
(二)緩沖動畫

思考:怎么樣才是緩沖動畫?

應(yīng)該有以下幾點:

逐漸變慢,最后停止

距離越遠速度越大

速度由距離決定

速度=(目標值-當前值)/縮放系數(shù)

Bug :速度取整(使用Math方法),不然會閃

向上取整。Math.ceil(iSpeed)

向下取整。Math.floor(iSpeed)

還是對速度作文章:

/**
 * 運動框架-4-緩沖動畫
 */
function startMove(element, iTarget) {
    clearInterval(timer);
    timer = setInterval(function () {
    //因為速度要動態(tài)改變,所以必須放在定時器中
        var iSpeed = (iTarget - element.offsetLeft) / 10; //(目標值-當前值)/縮放系數(shù)=速度
        iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed); //速度取整
        if (element.offsetLeft === iTarget) {//結(jié)束運動
            clearInterval(timer);
        } else {
            element.style.left = element.offsetLeft + iSpeed + "px";
        }
    }, 30);
}

做到這里,(速度取到某些值會無法停止)這個Bug就自動解決啦!

例子:緩沖菜單

跟隨頁面滾動的緩沖側(cè)邊欄
在線演示:codepen

潛在問題目標值不是整數(shù)時

(三)多物體運動

思考:如何實現(xiàn)多物體運動?

單定時器,存在問題。每個div一個定時器

定時器作為對象的屬性

直接使用element.timer把定時器變成對象上的一個屬性。

參數(shù)的傳遞:物體/目標值
比較簡單把上面框架的進行如下更改:timer-->element.timer

就這樣就行啦!

(四)任意值變化

咳咳。我們來給div加個1px的邊框。boder :1px solid #000

然后來試試下面的代碼

setInterval(function () {
    oDiv.style.width = oDiv.offsetWidth - 1 + "px";
}, 30)

嗯,神奇的事情發(fā)生了!what?我設(shè)置的不是寬度在減嗎?怎么尼瑪增加了! 不對啊,大兄弟。

究竟哪里出了問題呢?

一起找找資料,看看文檔,原來offset這一系列的屬性都會存在,被其他屬性干擾的問題。

好吧,既然不能用,那么我們就順便把任意值變化給做了吧。

第一步:獲取實際樣式

使用offsetLeft..等獲取樣式時, 若設(shè)置了邊框, padding, 等可以改變元素寬度高度的屬性時會出現(xiàn)BUG..

通過查找發(fā)現(xiàn)element.currentStyle(attr)可以獲取計算過之后的屬性。

但是因為兼容性的問題,需封裝getStyle函數(shù)。(萬惡的IE)

當然配合CSS的box-sizing屬性設(shè)為border-box可以達到一樣的效果 ? (自認為,未驗證)。

/**
 * 獲取實際樣式函數(shù)
 * @param   {HTMLElement}   element  需要尋找的樣式的html節(jié)點
 * @param   {String]} attr 在對象中尋找的樣式屬性
 * @returns {String} 獲取到的屬性
 */
function getStyle(element, attr) {
    //IE寫法
    if (element.currentStyle) {
        return element.currentStyle[attr];
    //標準
    } else {
        return getComputedStyle(element, false)[attr];
    }
}
第二步:改造原函數(shù)

添加參數(shù),attr表示需要改變的屬性值。

更改element.offsetLeftgetStyle(element, attr)

需要注意的是:getStyle(element, attr)不能直接使用,因為它獲取到的字符串,例:10px

變量iCurrent使用parseInt(),將樣式轉(zhuǎn)成數(shù)字。

element.style.leftelement.style[attr]

/**
 * 運動框架-4-任意值變化
 * @param {HTMLElement} element 運動對象
 * @param {string}      attr    需要改變的屬性。
 * @param {number}      iTarget 目標值
 */
function startMove(element, attr, iTarget) {
    clearInterval(element.timer);
    element.timer = setInterval(function () {
        //因為速度要動態(tài)改變,所以必須放在定時器中
    var iCurrent=0;
    iCurrent = parseInt(getStyle(element, attr));//實際樣式大小
        var iSpeed = (iTarget - iCurrent) / 10; //(目標值-當前值)/縮放系數(shù)=速度
        iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed); //速度取整
        if (iCurrent === iTarget) {//結(jié)束運動
            clearInterval(element.timer);
        } else {
            element.style[attr] = iCurrent + iSpeed + "px";
        }
    }, 30);
}

試一試,這樣是不是就可以了呢?

還記得上面我們寫的透明度變化嗎? 再試試

果然還是不行, (廢話,你見過透明度有"px"單位的么? - -白眼

第三步:透明度兼容處理

思考:需要對那些屬性進行修改?

判斷attr是不是透明度屬性opacity

對于速度進行處理。

為透明度時,由于獲取到的透明度會是小數(shù),所以需要 * 100

并且由于計算機儲存浮點數(shù)的問題,還需要將小數(shù),進行四舍五入為整數(shù)。使用: Math.round(parseFloat(getStyle(element, attr)) * 100)

否則,繼續(xù)使用默認的速度。

對結(jié)果輸出部分進行更改。

判斷是透明度屬性,使用透明度方法

否則,使用使用默認的輸出格式。

/**
 * 運動框架-5-兼容透明度
 * @param {HTMLElement} element 運動對象
 * @param {string}      attr    需要改變的屬性。
 * @param {number}      iTarget 目標值
 */
function startMove(element, attr, iTarget) {
    clearInterval(element.timer);
    element.timer = setInterval(function () {
        //因為速度要動態(tài)改變,所以必須放在定時器中
        var iCurrent = 0;
        if (attr === "opacity") { //為透明度時執(zhí)行。
            iCurrent = Math.round(parseFloat(getStyle(element, attr)) * 100);
        } else { //默認情況
            iCurrent = parseInt(getStyle(element, attr)); //實際樣式大小
        }
        var iSpeed = (iTarget - iCurrent) / 10; //(目標值-當前值)/縮放系數(shù)=速度
        iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed); //速度取整
        if (iCurrent === iTarget) {//結(jié)束運動
            clearInterval(element.timer);
        } else {
            if (attr === "opacity") { //為透明度時,執(zhí)行
                element.style.filter = "alpha(opacity:" + (iCurrent + iSpeed) + ")"; //IE
                element.style.opacity = (iCurrent + iSpeed) / 100; //標準
            } else { //默認
                element.style[attr] = iCurrent + iSpeed + "px";
            }
        }
    }, 30);
}

到這里,這個運動框架就基本上完成了。但是,我們是追求完美的不是嗎?

繼續(xù)進化!

(五)鏈式動畫

鏈式動畫:顧名思義,就是在該次運動停止時,開始下一次運動。

如何實現(xiàn)呢?

使用回調(diào)函數(shù):運動停止時,執(zhí)行函數(shù)

添加func形參(回調(diào)函數(shù))。

在當前屬性到達目的地時iCurrent === iTarget,判斷是否有回調(diào)函數(shù)存在,有則執(zhí)行。

if (iCurrent === iTarget) {//結(jié)束運動
    clearInterval(element.timer);
    if (func) {
        func();//回調(diào)函數(shù)
    }
}

good,鏈式動畫完成!距離完美還差一步!

(六)同時運動

思考:如何實現(xiàn)同時運動?

使用JSON傳遞多個值

使用for in循環(huán),遍歷屬性,與值。

定時器問題!(運動提前停止)

在循環(huán)外設(shè)置變量,假設(shè)所有的值都到達了目的值為true

在循環(huán)中檢測是否到達目標值,若沒有值未到則為false

在循環(huán)結(jié)束后,檢測是否全部達到目標值.是則清除定時器

實現(xiàn):

刪除attriTarget兩個形參,改為json

在函數(shù)開始時,設(shè)置一個標記var flag = true; //假設(shè)所有運動到達終點.

在定時器內(nèi)使用for in,遍歷屬性與目標,改寫原來的attriTarget,為json的屬性與值

修改運動終止條件,只有每一項的實際屬性值iCurrent,等于目標值json[attr]時,flag才為true。清除定時器,判斷是否回調(diào)。

否則,繼續(xù)執(zhí)行代碼,直到所有屬性值等于目標值。

完美運動框架
/**
 * 獲取實際樣式函數(shù)
 * @param   {HTMLElement}   element  需要尋找的樣式的html節(jié)點
 * @param   {String]} attr 在對象中尋找的樣式屬性
 * @returns {String} 獲取到的屬性
 */
function getStyle(element, attr) {
    //IE寫法
    if (element.currentStyle) {
        return element.currentStyle[attr];
        //標準
    } else {
        return getComputedStyle(element, false)[attr];
    }
}
/**
 * 完美運動框架
 * @param {HTMLElement} element 運動對象
 * @param {JSON}        json    屬性:目標值      
 *   @property {String} attr    屬性值
 *   @config   {Number} target  目標值
 * @param {function}    func    可選,回調(diào)函數(shù),鏈式動畫。
 */
function startMove(element, json, func) {
    var flag = true; //假設(shè)所有運動到達終點.
    clearInterval(element.timer);
    element.timer = setInterval(function () {
        for (var attr in json) {
            //1.取當前的屬性值。
            var iCurrent = 0;
            if (attr === "opacity") { //為透明度時執(zhí)行。
                iCurrent = Math.round(parseFloat(getStyle(element, attr)) * 100);
            } else { //默認情況
                iCurrent = parseInt(getStyle(element, attr)); //實際樣式大小
            }
            //2.算運動速度,動畫緩沖效果
            var iSpeed = (json[attr] - iCurrent) / 10; //(目標值-當前值)/縮放系數(shù)=速度
            iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed); //速度取整

            //3.未到達目標值時,執(zhí)行代碼 
            if (iCurrent != json[attr]) {
                flag = false; //終止條件
                if (attr === "opacity") { //為透明度時,執(zhí)行
                    element.style.filter = "alpha(opacity:" + (iCurrent + iSpeed) + ")"; //IE
                    element.style.opacity = (iCurrent + iSpeed) / 100; //標準
                } else { //默認
                    element.style[attr] = iCurrent + iSpeed + "px";
                }
            } else {
                flag = true;
            }
            //4. 運動終止,是否回調(diào)
            if (flag) {
                clearInterval(element.timer);
                if (func) {
                    func();
                }
            }
        }
    }, 30);
}
運動框架總結(jié)

運動框架演變過程

框架 變化
startMove(element) 運動
startMove(element,iTarget) 勻速-->緩沖-->多物體
startMove(element,attr,iTargrt) 任意值
startMove(element,attr,iTargrt,func) 鏈式運動
startMove(element,json,func) 多值(同時)-->完美運動框架

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/86158.html

相關(guān)文章

  • javascript完美運動

    摘要:在這個完美運動框架中,我們可以只讓一個物體的一個屬性運動,可以鏈式調(diào)用,也可以幾個屬性同時運動。能解決我們項目中遇到的大部分運動。運動框架演變過程運動實現(xiàn)留言板的例子完美運動運動,高度展開發(fā)布 前面的運動,每次只能改一個值,你改div的width的時候,就不能改div的高度,改高度的時候就不能改寬度,如果我的運動想同時改寬度和高度,怎么實現(xiàn)?在這里我們把屬性和目標值用json實現(xiàn)。在這...

    BenCHou 評論0 收藏0
  • 【搶先領(lǐng)】《React 學習之道》我們翻譯了一本最簡單,且最實用 React 實戰(zhàn)教程……

    摘要:學習之道簡體中文版通往實戰(zhàn)大師之旅掌握最簡單,且最實用的教程。前言學習之道這本書使用路線圖中的精華部分用于傳授,并將其融入一個獨具吸引力的真實世界的具體代碼實現(xiàn)。完美展現(xiàn)了的優(yōu)雅。膜拜的學習之道是必讀的一本書。 《React 學習之道》The Road to learn React (簡體中文版) 通往 React 實戰(zhàn)大師之旅:掌握 React 最簡單,且最實用的教程。 showIm...

    oneasp 評論0 收藏0
  • 大前端2018現(xiàn)在上車還還得及么

    摘要:面向?qū)ο笕筇卣骼^承性多態(tài)性封裝性接口。第五階段封裝一個屬于自己的框架框架封裝基礎(chǔ)事件流冒泡捕獲事件對象事件框架選擇框架。核心模塊和對象全局對象,,,事件驅(qū)動,事件發(fā)射器加密解密,路徑操作,序列化和反序列化文件流操作服務(wù)端與客戶端。 第一階段: HTML+CSS:HTML進階、CSS進階、div+css布局、HTML+css整站開發(fā)、 JavaScript基礎(chǔ):Js基礎(chǔ)教程、js內(nèi)置對...

    stormgens 評論0 收藏0
  • 大前端2018現(xiàn)在上車還還得及么

    摘要:面向?qū)ο笕筇卣骼^承性多態(tài)性封裝性接口。第五階段封裝一個屬于自己的框架框架封裝基礎(chǔ)事件流冒泡捕獲事件對象事件框架選擇框架。核心模塊和對象全局對象,,,事件驅(qū)動,事件發(fā)射器加密解密,路徑操作,序列化和反序列化文件流操作服務(wù)端與客戶端。 第一階段: HTML+CSS:HTML進階、CSS進階、div+css布局、HTML+css整站開發(fā)、 JavaScript基礎(chǔ):Js基礎(chǔ)教程、js內(nèi)置對...

    mylxsw 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<