• 原生javascript模仿win8等待进度条。


    一、序言

      一直很中意win8等待提示圆圈进度条。win8刚出来那会,感觉好神奇!苦于当时没思路,没去研究。通过最近网上找找资料,终于给搞出来了!先上Demo,献丑了!预览请看:win8进度条

    二、简单介绍

      原生javascript编写,需要理解js基于面向对象编程和圆形坐标计算!

      实现原理:把每个圆点抽象成一个对象(ProgressBarWin8类型),将每个圆点对象存在数组中(progressArray),延迟执行每个圆点对象的run方法,至于圆点运行速度越来越快,是通过改变定时器延迟毫秒数实现的。

     // 判断元素x与圆心x坐标大小,设置定时器延迟时间

    if (this.position.left < this.fixed.left) {
        this.delay += .5;
    } else {
        this.delay -= .5;
    }

      还是上源码吧!表达能力实在不怎么好(代码中注释更详细,会看得更明白)。

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <title>仿win8等待进度条</title>
        <style>
            body {
                margin: 0;
                padding: 0;
                background: green
            }
        </style>
    </head>
    <body>
        <script>
            //********准备条件******** 
            // 弧度角度转换公式:弧度=Math.PI*角度/180; js中Math.sin(),Math.cos()等函数,是根据弧度计算
            // 圆x轴坐标计算公式:Math.cos(Math.PI * 角度/ 180) * 半径 + 圆心x轴坐标
            // 圆y轴坐标计算公式:Math.sin(Math.PI * 角度/ 180) * 半径 + 圆心y轴坐标
            //********准备条件******** 
            
    
            // 圆点元素类(js中没有类的概念,这里模拟而已)
            function ProgressBarWin8() {
                // 圆心坐标
                this.fixed = {
                    left: 0,
                    top: 0
                };
                // html标签元素坐标
                this.position = {
                    left: 0,
                    top: 0
                };
                this.radius = 70; // 圆半径
                this.angle = 270; // 角度,默认270
                this.delay = 30; // 定时器延迟毫秒
                this.timer = null; // 定时器时间对象
                this.dom = null; // html标签元素
                // html标签元素样式, position需设置成absolute
                this.style = {
                    position: "absolute",
                     "10px",
                    height: "10px",
                    background: "#fff",
                    "border-radius": "5px"
                };
            }
    
            // js中每个函数都有个prototype对象属性,每个实例都可以访问
            ProgressBarWin8.prototype = {
                // 运行方法
                run: function() {
                    if (this.timer) {
                        clearTimeout(this.timer);
                    }
                    
                    // 设置html标签元素坐标,即计算圆上的点x,y轴坐标
                    this.position.left = Math.cos(Math.PI * this.angle / 180) * this.radius + this.fixed.left;
                    this.position.top = Math.sin(Math.PI * this.angle / 180) * this.radius + this.fixed.top;
                    this.dom.style.left = this.position.left + "px";
                    this.dom.style.top = this.position.top + "px";
                    
                    // 改变角度
                    this.angle++;
                    
                    // 判断元素x与圆心x坐标大小,设置定时器延迟时间
                    if (this.position.left < this.fixed.left) {
                        this.delay += .5;
                    } else {
                        this.delay -= .5;
                    }
                    
                    var scope = this;
                    // 定时器,循环调用run方法,有点递归的感觉
                    this.timer = setTimeout(function () {
                        // js中函数的调用this指向调用者,当前this是window
                        scope.run();
                    }, this.delay);
                },
                // html标签元素初始设置
                defaultSetting: function () {
                    // 创建一个span元素
                    this.dom = document.createElement("span");
                    // 设置span元素的样式,js中对象的遍历是属性
                    for (var property in this.style) {
                        // js中对象方法可以用.操作符,也可以通过键值对的方式
                        this.dom.style[property] = this.style[property];
                    }
                    // innerWidth innerHeight窗口中文档显示区域的宽度,不包括边框和滚动条,该属性可读可写。
                    // 设置圆心x,y轴坐标,当前可视区域的一般,即中心点
                    this.fixed.left = window.innerWidth / 2;
                    this.fixed.top = window.innerHeight / 2;
                    // 设置span元素的初始坐标
                    this.position.left = Math.cos(Math.PI * this.angle / 180) * this.radius + this.fixed.left;
                    this.position.top = Math.sin(Math.PI * this.angle / 180) * this.radius + this.fixed.top;
                    this.dom.style.left = this.position.left + "px";
                    this.dom.style.top = this.position.top + "px";
                    // 把span标签添加到documet里面
                    document.body.appendChild(this.dom);
                    
                    // 返回当前对象
                    return this;
                }
            };
    
            // 不明白的,把后面的代码注释掉,先测试一个圆点运行情况
            //new ProgressBarWin8().defaultSetting().run();
    
    
    
            var progressArray = [], // 用于存放每个圆点元素对象数组,js中数组大小可变,类似于list集合
                tempArray = [], // 用于存放progressArray抛出来的每个对象,窗口大小改变后,重置每个对象的圆心坐标
                timer = 200; // 每隔多少毫秒执行一个元素对象run方法的定时器
            
            // 创建圆点元素对象,存入数组中,这里创建5个对象
            for (var i = 0; i < 5; ++i) {
                progressArray.push(new ProgressBarWin8().defaultSetting());
            }
            
            // 扩展数组each方法,c#中的lambda大都是这样实现
            Array.prototype.each = function (fn) {
                for (var i = 0, len = this.length; i < len;) {
                    // 通过call(object,arg1,arg2,...)/apply(object,[arg1,arg2,...])方法改变函数fn内this的作用域,  以此可用于继承
                    fn.call(this[i++], arguments);// 或者:fn.apply(this[i++],arguments)
                }
            };
            
            // 窗口大小改变事件,重置每个元素对象的圆心坐标
            window.onresize = function () {
                tempArray.each(function () {
                    this.fixed.left = window.innerWidth / 2;
                    this.fixed.top = window.innerHeight / 2;
                });
            };
    
            // 每个多少毫秒执行数组集合的元素对象run方法
            timer = setInterval(function () {
                if (progressArray.length <= 0) {
                    // 清除此定时器,不然会一直执行(setTimeOut:延迟多少毫秒执行,一次;setInterval:每隔多少毫秒执行,多次)
                    clearInterval(timer);
                } else {
                    // shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值。
                    var entity = progressArray.shift();
                    tempArray.push(entity);
                    // 执行每个元素对象的run方法
                    entity.run();
                }
            },timer);
        </script>
    </body>
    </html>
    

    三、结束语:

      好就点个赞!

  • 相关阅读:
    python学习笔记(二)
    python学习笔记(四)
    首个python程序,一个猜数字的小游戏 ^0^
    python生成随机数
    python生成随机数
    python学习笔记(四)
    我的书《编写高质量代码—Web前端开发修炼之道》面市了,请大家多多支持
    python学习笔记(三)
    EasyNVR纯H5摄像机直播解决方案前端解析之:RTSP安防监控实时直播的网页H5自动播放方案
    基于EasyNVR实现RTSP_Onvif监控摄像头Web无插件化直播监控
  • 原文地址:https://www.cnblogs.com/GodX/p/3681735.html
Copyright © 2020-2023  润新知