【JavaScript框架封裝】實現一個類似於JQuery的動畫框架的封裝
版權宣告:本文為博主原創文章,未經博主允許不得轉載。更多學習資料請訪問我愛科技論壇:www.52tech.tech https://blog.csdn.net/m0_37981569/article/details/81123854
// 動畫框架
(function (xframe) {
// 需要參與鏈式訪問的(必須使用prototype的方式來給物件擴充方法)
xframe.extend({});
// 不需要參與鏈式訪問的
xframe.extend(xframe, {});
// 實現動畫框架的封裝
xframe.Animate = (function (xframe) {
// 1. 定義需要的API介面(API內部用於放置屬性)
var api = {
timer: null,// 這是一個動畫迴圈控制程式碼
queen: [] // 多個物件同時執行的一個陣列佇列
};
// 執行部門-------------------------------------------------
/**
* 在把需要的執行引數都準備好了之後(多個物件),就開始執行這個執行函式
*/
api.run = function () {
// 定義一個定時器,用於不斷地執行我自己定義的動畫函式資訊
api.timer = setInterval(function () {
// 由於所有的引數都已經準備好了,因此這裡只需要直接進行迴圈操作即可
api.loop();
}, 16); // 這裡迴圈的週期設定的是16mm
}
/**
* 執行動畫迴圈操作
*/
api.loop = function () {
// obj裡面儲存了obj = {id, now, pass, tween, duration, style}
api.queen.forEach(function (obj) {
// 遍歷佇列中的每一項引數,開始執行移動操作
api.move(obj);
});
}
/**
* 實現物體的移動
*/
api.move = function (obj) {
// 1. 計算當前的時間
obj.pass = +new Date();
// 2. 獲取動畫時間程式(這裡的動畫樣式預設是一個彈簧的顯示樣式)
var tween = api.getTween(obj.now, obj.pass, obj.duration, `easeOutBounce`);
// 注意我們再每一次移動這個物體物件之前需要把這個物體物件的動畫時間程式更新一下,這樣到了後面的修改物件的屬性的時候這個引數的數值才會動態改變
obj.tween = tween;
//console.log(tween);
// 3. 設定屬性資訊
if (tween >= 1) {
// 如果動畫時間程式結束了(百分比資訊)
api.stop();
} else {
// 4. 通過設定物件的屬性資訊來移動每一個物件
api.setManyProperty(obj);
}
}
// 新增部門-------------------------------------------------
/**
* @param 獲取使用者輸入的引數,開始對引數進行解析,開始新增引數,然後實現動畫的開始執行
*/
api.add = function () {
var args = arguments,
id = args[0],
json = args[1],
duration = args[2];
// 獲取輸入的引數,然後開始使用介面卡解析資料
try {
// 1. 呼叫介面卡準備引數
api.adapterMany(id, json, duration);
// 2. 開始執行動畫
api.run();
} catch (e) {
console.error(e.message);
}
}
/**
* 這是一個介面卡,用於解析一個物件的引數資訊(只能處理一個物件)
* @param id
* @param json
* @param duration
*/
api.adapterOne = function (id, json, duration) {
var obj = {} // 這裡的OBj就是一個字面量格式, 用於儲存需要的引數資訊
obj.id = id // ID編號
obj.now = +new Date() // 開始時間
obj.pass = 0 // 當前時間
obj.tween = 0 // 動畫時間程式
obj.duration = duration // 動畫的持續時間
obj.styles = [] // 用於存放所有的樣式資訊
// 根據使用者輸入的引數資訊選擇不同的動畫速度
if ($.isString(duration)) {
switch (duration) {
case `slow`:
case `慢`:
duration = 8000;
break;
case `normal`:
case `普通`:
duration = 4000;
break;
case `fast`:
case `快`:
duration = 1000;
break;
}
}
// 設定樣式資訊
obj.styles = api.getStyles(id, json);
return obj;
}
/**
* 這個介面卡針對的是處理多個物件的動畫資訊
* @param id
* @param json
* @param data
*/
api.adapterMany = function (id, json, data) {
// 處理多個物件的引數資訊(同樣的引數,但是需要處理不同的資訊,針對的是多個物件的引數)
var obj = this.adapterOne(id, json, data);
// 開始向我已有的佇列中新增資料資訊(此時queen佇列裡面就是存放了我所有的資料資訊)
api.queen.push(obj);
}
/**
* 獲取樣式資訊
* @param id
* @param json
*/
api.getStyles = function (id, json) {
// animate(`#sun`, {left: 200, top : 500}, 7000);
// 把使用者傳遞過來的引數資訊轉換我需要的格式
var styles = [];
// 開始解析json資料資訊
for (var item in json) {
var style = {};
// 這裡的item就是下面的:left, top
style.name = item;
// 獲取物體開始的位置
style.start = parseFloat($(id).css(item).toString());
// 計算物體的偏移量(移動的距離)
style.length = parseFloat(json[item]) - style.start;
styles.push(style);
}
return styles;
}
/**
* 用於獲取一個動畫時間程式
* @param now 開始時間
* @param pass 當前時間
* @param all 持續時間
* @param ease 動畫效果
*/
api.getTween = function (now, pass, all, ease) {
// 1.定義常見的動畫效果
var eases = {
//線性勻速
linear: function (t, b, c, d) {
return (c - b) * (t / d);
},
//彈性運動
easeOutBounce: function (t, b, c, d) {
if ((t /= d) < (1 / 2.75)) {
return c * (7.5625 * t * t) + b;
} else if (t < (2 / 2.75)) {
return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b;
} else if (t < (2.5 / 2.75)) {
return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;
} else {
return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;
}
},
//其他
swing: function (t, b, c, d) {
return this.easeOutQuad(t, b, c, d);
},
easeInQuad: function (t, b, c, d) {
return c * (t /= d) * t + b;
},
easeOutQuad: function (t, b, c, d) {
return -c * (t /= d) * (t - 2) + b;
},
easeInOutQuad: function (t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t + b;
return -c / 2 * ((--t) * (t - 2) - 1) + b;
},
easeInCubic: function (t, b, c, d) {
return c * (t /= d) * t * t + b;
},
easeOutCubic: function (t, b, c, d) {
return c * ((t = t / d - 1) * t * t + 1) + b;
},
easeInOutCubic: function (t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t * t + b;
return c / 2 * ((t -= 2) * t * t + 2) + b;
},
easeInQuart: function (t, b, c, d) {
return c * (t /= d) * t * t * t + b;
},
easeOutQuart: function (t, b, c, d) {
return -c * ((t = t / d - 1) * t * t * t - 1) + b;
},
easeInOutQuart: function (t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b;
return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
},
easeInQuint: function (t, b, c, d) {
return c * (t /= d) * t * t * t * t + b;
},
easeOutQuint: function (t, b, c, d) {
return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
},
easeInOutQuint: function (t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t * t * t * t + b;
return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;
},
easeInSine: function (t, b, c, d) {
return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;
},
easeOutSine: function (t, b, c, d) {
return c * Math.sin(t / d * (Math.PI / 2)) + b;
},
easeInOutSine: function (t, b, c, d) {
return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;
},
easeInExpo: function (t, b, c, d) {
return (t == 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;
},
easeOutExpo: function (t, b, c, d) {
return (t == d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;
},
easeInOutExpo: function (t, b, c, d) {
if (t == 0) return b;
if (t == d) return b + c;
if ((t /= d / 2) < 1) return c / 2 * Math.pow(2, 10 * (t - 1)) + b;
return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;
},
easeInCirc: function (t, b, c, d) {
return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;
},
easeOutCirc: function (t, b, c, d) {
return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;
},
easeInOutCirc: function (t, b, c, d) {
if ((t /= d / 2) < 1) return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;
return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;
},
easeInElastic: function (t, b, c, d) {
var s = 1.70158;
var p = 0;
var a = c;
if (t == 0) return b;
if ((t /= d) == 1) return b + c;
if (!p) p = d * .3;
if (a < Math.abs(c)) {
a = c;
var s = p / 4;
}
else var s = p / (2 * Math.PI) * Math.asin(c / a);
return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
},
easeOutElastic: function (t, b, c, d) {
var s = 1.70158;
var p = 0;
var a = c;
if (t == 0) return b;
if ((t /= d) == 1) return b + c;
if (!p) p = d * .3;
if (a < Math.abs(c)) {
a = c;
var s = p / 4;
}
else var s = p / (2 * Math.PI) * Math.asin(c / a);
return a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b;
},
easeInOutElastic: function (t, b, c, d) {
var s = 1.70158;
var p = 0;
var a = c;
if (t == 0) return b;
if ((t /= d / 2) == 2) return b + c;
if (!p) p = d * (.3 * 1.5);
if (a < Math.abs(c)) {
a = c;
var s = p / 4;
}
else var s = p / (2 * Math.PI) * Math.asin(c / a);
if (t < 1) return -.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b;
},
easeInBack: function (t, b, c, d, s) {
if (s == undefined) s = 1.70158;
return c * (t /= d) * t * ((s + 1) * t - s) + b;
},
easeOutBack: function (t, b, c, d, s) {
if (s == undefined) s = 1.70158;
return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
},
easeInOutBack: function (t, b, c, d, s) {
if (s == undefined) s = 1.70158;
if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;
return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;
},
easeInBounce: function (t, b, c, d) {
return c - this.easeOutBounce(d - t, 0, c, d) + b;
},
easeInOutBounce: function (t, b, c, d) {
if (t < d / 2) return this.easeInBounce(t * 2, 0, c, d) * .5 + b;
return this.easeOutBounce(t * 2 - d, 0, c, d) * .5 + c * .5 + b;
}
};
// 2. 計算每一次動畫迴圈的小號時長
var yongshi = pass - now;
// 3. 獲取相應的動畫效果
return eases[ease](yongshi, 0, 1, all);
}
/**
* 通過設定一個物件的屬性資訊來實現物體的運動效果(如果只有一個屬性資訊的話)
* @param obj
*/
api.setOneProperty = function (obj) {
// 用於設定一個物件的屬性資訊(obj.id, obj.json)
// 【注意點】:這裡是動畫實現的一個核心要點,通過修改物件的屬性資訊來移動物體
if (obj.name === `opacity`) {
$(obj.id).css(obj.name, (obj.start + obj.length * obj.tween));
} else {
// 對於設定物件的其他屬性資訊都是需要新增一個px,畫素值資訊
$(obj.id).css(obj.name, (obj.start + obj.length * obj.tween) + `px`);
}
}
/**
* 用於設定一個物件的鎖哥屬性資訊 obj.json = {width : `200px`, height : `500px`, `opacity` : `0.1`}
*/
api.setManyProperty = function (obj) {
// 由於obj.styles裡面是一個陣列
obj.styles.forEach(function (style) {
// 遍歷當前物件的所有樣式屬性資訊
obj.name = style.name;
obj.start = style.start;
obj.length = style.length;
api.setOneProperty(obj);
console.log(obj.tween);
});
// 由於styles裡面只儲存了style.name, style.start, style.length三個屬性資訊, 因此需要處理一下
}
/**
* 結束動畫的執行
*/
api.stop = function () {
clearInterval(api.timer);
}
// 後勤部門----------------------------------------------------
api.destory = function () {
}
// 使用者只需要把需要的引數新增進來們就可以執行一個動畫
// 使用者只需要傳進來三個引數,id, json, duration就可以實現一個動畫
xframe.animate = api.add;
})(xframe);
})(xframe);
相關文章
- 【JavaScript框架封裝】實現一個類似於JQuery的CSS樣式框架的封裝JavaScript框架封裝jQueryCSS
- 【JavaScript框架封裝】公共框架的封裝JavaScript框架封裝
- 封裝框架的實踐封裝框架
- Flutter 基於Bloc框架的封裝FlutterBloC框架封裝
- RN自定義元件封裝 - 播放類似PPT動畫元件封裝動畫
- web自動化框架—BasePage 類的簡單封裝Web框架封裝
- 基於javascript的拖拽類封裝^o^JavaScript封裝
- 一次Android動畫工具類的封裝Android動畫封裝
- 封裝一個在react上更易用的redux框架封裝ReactRedux框架
- 封裝一個簡單的動畫函式封裝動畫函式
- 【JavaScript框架封裝】JavaScript中的文字字串的轉義和反轉義的實現JavaScript框架封裝字串
- 關於網路框架設計封裝的扯淡框架封裝
- 關於緩動動畫函式的封裝動畫函式封裝
- 一、類的封裝性封裝
- 基於gin框架封裝的web專案骨架goskeleton框架封裝WebGo
- 採用 SwiftNIO 實現一個類似 Express 的 Web 框架SwiftExpressWeb框架
- Android Room封裝成一個類似Redis的快取資料庫的效果AndroidOOM封裝Redis快取資料庫
- 一步步封裝實現自己的網路請求框架封裝框架
- javascript封裝動畫函式(勻速、變速)JavaScript封裝動畫函式
- 039.CI4框架CodeIgniter,封裝Model模型繫結資料庫的封裝框架封裝模型資料庫
- 基於原生fetch封裝一個帶有攔截器功能的fetch,類似axios的攔截器封裝iOS
- 【JavaScript框架封裝】使用Prototype給Array,String,Function物件的方法擴充JavaScript框架封裝Function物件
- jquery 封裝 bootstrap tablejQuery封裝boot
- Flutter 網路請求框架封裝Flutter框架封裝
- 封裝一個通用的PopupWindow封裝
- 封裝定時任務框架的正確方式封裝框架
- 使用promise封裝jquery的ajax來實現async和await方式Promise封裝jQueryAI
- 淺析jQuery原理並仿寫封裝一個自己的庫jQuery封裝
- python自動化測試框架,封裝方法方式Python框架封裝
- 一個簡單的 Amqp 封裝MQ封裝
- 封裝一個自己的js庫封裝JS
- 如何基於 React 封裝一個元件React封裝元件
- canvas簡單封裝一個echarts實現不了的餅圖Canvas封裝Echarts
- 基於Promise實現對Ajax的簡單封裝Promise封裝
- javascript原生封裝一個淡入淡出效果的函式JavaScript封裝函式
- 基於spring boot框架進行二次封裝,微型框架編寫思路Spring Boot框架封裝
- 十五、類與封裝的概念封裝
- Flutter的移動端相機快門動畫封裝Flutter動畫封裝