一、序言
一直很中意win8等待提示圆圈进度条。win8刚出来那会,感觉好神奇!苦于当时没思路,没去研究。通过最近网上找找资料,终于给搞出来了!先上Demo,献丑了!预览请看:win8进度条。
二、简单介绍
原生javascript编写,需要理解js基于面向对象编程和圆形坐标计算!
实现原理:把每个圆点抽象成一个对象(ProgressBarWin8类型),将每个圆点对象存在数组中(progressArray),延迟执行每个圆点对象的run方法,至于圆点运行速度越来越快,是通过改变定时器延迟毫秒数实现的。
// 判断元素x与圆心x坐标大小,设置定时器延迟时间
if (this.position.left this.delay += .5;
} else {
this.delay -= .5;
}
还是上源码吧!表达能力实在不怎么好(代码中注释更详细,会看得更明白)。
仿win8等待进度条
<script> <BR>//********准备条件******** <BR>// 弧度角度转换公式:弧度=Math.PI*角度/180; js中Math.sin(),Math.cos()等函数,是根据弧度计算 <BR>// 圆x轴坐标计算公式:Math.cos(Math.PI * 角度/ 180) * 半径 + 圆心x轴坐标 <BR>// 圆y轴坐标计算公式:Math.sin(Math.PI * 角度/ 180) * 半径 + 圆心y轴坐标 <BR>//********准备条件******** <br><br><BR>// 圆点元素类(js中没有类的概念,这里模拟而已) <BR>function ProgressBarWin8() { <BR>// 圆心坐标 <BR>this.fixed = { <BR>left: 0, <BR>top: 0 <BR>}; <BR>// html标签元素坐标 <BR>this.position = { <BR>left: 0, <BR>top: 0 <BR>}; <BR>this.radius = 70; // 圆半径 <BR>this.angle = 270; // 角度,默认270 <BR>this.delay = 30; // 定时器延迟毫秒 <BR>this.timer = null; // 定时器时间对象 <BR>this.dom = null; // html标签元素 <BR>// html标签元素样式, position需设置成absolute <BR>this.style = { <BR>position: "absolute", <BR>width: "10px", <BR>height: "10px", <BR>background: "#fff", <BR>"border-radius": "5px" <BR>}; <BR>} <br><br>// js中每个函数都有个prototype对象属性,每个实例都可以访问 <BR>ProgressBarWin8.prototype = { <BR>// 运行方法 <BR>run: function() { <BR>if (this.timer) { <BR>clearTimeout(this.timer); <BR>} <br><br>// 设置html标签元素坐标,即计算圆上的点x,y轴坐标 <BR>this.position.left = Math.cos(Math.PI * this.angle / 180) * this.radius + this.fixed.left; <BR>this.position.top = Math.sin(Math.PI * this.angle / 180) * this.radius + this.fixed.top; <BR>this.dom.style.left = this.position.left + "px"; <BR>this.dom.style.top = this.position.top + "px"; <br><br>// 改变角度 <BR>this.angle++; <br><br>// 判断元素x与圆心x坐标大小,设置定时器延迟时间 <BR>if (this.position.left < this.fixed.left) { <BR>this.delay += .5; <BR>} else { <BR>this.delay -= .5; <BR>} <br><br>var scope = this; <BR>// 定时器,循环调用run方法,有点递归的感觉 <BR>this.timer = setTimeout(function () { <BR>// js中函数的调用this指向调用者,当前this是window <BR>scope.run(); <BR>}, this.delay); <BR>}, <BR>// html标签元素初始设置 <BR>defaultSetting: function () { <BR>// 创建一个span元素 <BR>this.dom = document.createElement("span"); <BR>// 设置span元素的样式,js中对象的遍历是属性 <BR>for (var property in this.style) { <BR>// js中对象方法可以用.操作符,也可以通过键值对的方式 <BR>this.dom.style[property] = this.style[property]; <BR>} <BR>// innerWidth innerHeight窗口中文档显示区域的宽度,不包括边框和滚动条,该属性可读可写。 <BR>// 设置圆心x,y轴坐标,当前可视区域的一般,即中心点 <BR>this.fixed.left = window.innerWidth / 2; <BR>this.fixed.top = window.innerHeight / 2; <BR>// 设置span元素的初始坐标 <BR>this.position.left = Math.cos(Math.PI * this.angle / 180) * this.radius + this.fixed.left; <BR>this.position.top = Math.sin(Math.PI * this.angle / 180) * this.radius + this.fixed.top; <BR>this.dom.style.left = this.position.left + "px"; <BR>this.dom.style.top = this.position.top + "px"; <BR>// 把span标签添加到documet里面 <BR>document.body.appendChild(this.dom); <br><br>// 返回当前对象 <BR>return this; <BR>} <BR>}; <br><br>// 不明白的,把后面的代码注释掉,先测试一个圆点运行情况 <BR>//new ProgressBarWin8().defaultSetting().run(); <br><br><br><br>var progressArray = [], // 用于存放每个圆点元素对象数组,js中数组大小可变,类似于list集合 <BR>tempArray = [], // 用于存放progressArray抛出来的每个对象,窗口大小改变后,重置每个对象的圆心坐标 <BR>timer = 200; // 每隔多少毫秒执行一个元素对象run方法的定时器 <br><br>// 创建圆点元素对象,存入数组中,这里创建5个对象 <BR>for (var i = 0; i < 5; ++i) { <BR>progressArray.push(new ProgressBarWin8().defaultSetting()); <BR>} <br><br>// 扩展数组each方法,c#中的lambda大都是这样实现 <BR>Array.prototype.each = function (fn) { <BR>for (var i = 0, len = this.length; i < len;) { <BR>// 通过call(object,arg1,arg2,...)/apply(object,[arg1,arg2,...])方法改变函数fn内this的作用域, 以此可用于继承 <BR>fn.call(this[i++], arguments);// 或者:fn.apply(this[i++],arguments) <BR>} <BR>}; <br><br>// 窗口大小改变事件,重置每个元素对象的圆心坐标 <BR>window.onresize = function () { <BR>tempArray.each(function () { <BR>this.fixed.left = window.innerWidth / 2; <BR>this.fixed.top = window.innerHeight / 2; <BR>}); <BR>}; <br><br>// 每个多少毫秒执行数组集合的元素对象run方法 <BR>timer = setInterval(function () { <BR>if (progressArray.length <= 0) { <BR>// 清除此定时器,不然会一直执行(setTimeOut:延迟多少毫秒执行,一次;setInterval:每隔多少毫秒执行,多次) <BR>clearInterval(timer); <BR>} else { <BR>// shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值。 <BR>var entity = progressArray.shift(); <BR>tempArray.push(entity); <BR>// 执行每个元素对象的run方法 <BR>entity.run(); <BR>} <BR>},timer); <BR></script>