前言:
本人纯小白一个,有很多地方理解的没有各位大牛那么透彻,如有错误,请各位大牛指出斧正!小弟感激不尽。
本篇文章为您分析一下原生JS写一个运动插件
基本功能:
-
补充中......
-
补充中......
HTML结构
<div class="container"></div>
<p>
<button id="start">开始</button>
<button id="stop">结束</button>
</p>
html的结构只是为了调试运动插件而随意创建的。
CSS样式
<style>
.container {
width: 100px;
height: 100px;
background-color: aqua;
position: absolute;
left: 0;
top: 0;
}
p{
position: absolute;
top: 50px;
left: 100px;
}
</style>
页面效果如下:
JS行为
需求分析:
-
动画: 某些元素的某些CSS属性,在一段时间内,从一个值变化到另一个值
-
动画插件: 某些数据(数字),在一段时间内,从一个值变化到另一个值
-
不考虑DOM元素,DOM元素由用户传入
-
创建一个构造函数,让用户传入一些必须的参数(值、函数)
-
引入helper.js插件(自己封装的),使用对象混合
-
计算运动的总次数
-
获取当前的运动状态
-
计算所有属性每次运动的距离
-
为Animate函数添加方法
页面效果如下:
/**
* 动画: 某些元素的某些CSS属性,在一段时间内,从一个值变化到另一个值
* 动画插件: 某些数据,在一段时间内,从一个值变化到另一个值
* 构造函数
* @param {Object} option 配置对象
*/
this.myPlugin.Animate = function (option) {
// 第一步: 默认配置
var defalutOption = {
duration: 16, // 默认间隔时间,单位毫秒
total: 1000, // 默认总时间,单位毫秒
begin: {}, // 需要变化的初始值
end: {} // 需要变化的结束值
}
// 第二步: 对象混合 参考helper.js中的对象混合插件
this.option = myPlugin.mixin(defalutOption, option);
// 计时器的id
var timer = null;
// 第三步: 运行总次数 变化的次数
this.number = Math.ceil(this.option.total / this.option.duration);
// 3.1 当前运动的次数
this.curNumber = 0;
// 第四步: 得到当前的运动状态 参考helper.js中的对象克隆插件 因为当前的运动属性肯定和你的初始值运动属性是一样的,所有我们要克隆他
this.curData = myPlugin.clone(this.option.begin);
// 第五步: 所有属性运动的总距离
this.distance = {};
// 5.1 所有属性每次运动的距离
this.everyDistance = {};
// 循环begin和end的所有属性
for (var prop in this.option.begin) {
// 5.2 所有属性运动的距离 = 结束值 - 初始值
this.distance[prop] = this.option.end[prop] - this.option.begin[prop];
// 5.3 所有属性每次运动的距离 = 运动总距离 / 运动次数
this.everyDistance[prop] = this.distance[prop] / this.number;
}
}
在原型上添加方法
/**
* 在原型上添加动画方法,因为每创建一个Animate函数时都会创建一个start方法,这样代码比较冗余
* 第七步: 7.1 开始动画
*/
this.myPlugin.Animate.prototype.start = function () {
// 第八步: 如果这个定时器已经有动画了或者当前运动的次数达到了运动的总次数
if (this.timer || this.curNumber === this.number) {
// 不做任何处理 此处并非清空定时器
return;
}
// 8.1 保存this
var self = this;
// 第九步: 开启一个定时器
this.timer = setInterval(function () {
// 9.1 每次运动次数加一
self.curNumber++;
// 9.2 如果当前运动的次数等于总次数
if (self.curNumber === self.number) {
self.stop();
if (self.option.onover) {
self.option.onover.call(self);
}
}
}, this.option.duration)
}
/**
* 第七步: 7.2 停止动画
*/
this.myPlugin.Animate.prototype.stop = function () {
// 清空定时器
clearInterval(this.timer);
// 将定时器设置为null
this.timer = null;
}
来源:https://www.cnblogs.com/qq4297751/p/12651460.html