使用画布创建循环倒数计时器

时间:2015-11-25 15:12:41

标签: jquery canvas progress-bar

有很多圈子进度条插件,但它们都不是我需要的。基本上所有的插件都是从0度到360度或0到270度或类似的东西。我需要的是圆形进度条,例如在10秒内从120度降低到0度。我已经能够通过插件进行120减少,但总是从360度到240度。所以我想插件从让我们说的1/3圈填充到0/3圈填充。

2 个答案:

答案 0 :(得分:1)

你正在寻找这样的东西吗?

https://github.com/johnschult/jquery.countdown360

您可以根据需要对其进行编辑,它将从该秒开始倒计时。 已经有一个演示了。

答案 1 :(得分:1)

如何制作JQuery arcTimer /进度条

这也是我的第一个JQuery插件,所以如果有人看到错误,请指出它。

制作jquery插件非常简单。你需要实现一些方法才能让球滚动。 首先是一个声明插件的匿名函数。

(function ($, window, document, undefined) {
    var pluginName = "arcTimer"; // requiered
    var defaults = {             // requiered
        // you defaults
        // todo see below for setting up defaults
    };

    // this is called to start your plugin.
    // element is the element that the plugin will run in
    // options ar the options passed to the plugin
    function Plugin(element, options) { // "this" is the plugin 
        this.element = element; 
        this.settings = $.extend({}, defaults, options); // gets the setting applying defaults as needed
        this._defaults = defaults; // save the defaults. Not sure if this is needed
        this._name = pluginName;  // save the name
        this._init();   // call your plugin startup code.
    }
    // now define the plugin prototype.
    Plugin.prototype = {
       // todo see below for setting plugin prototype
       _init:function(){ // internal functions and properties are generally prefixed with _
           // todo see below for init code
       }
    }
    // this defines you plugin in the jQuery scope.
    $.fn[pluginName] = function (options) {
        var plugin;
        this.each(function () {
            plugin = $.data(this, "plugin_" + pluginName);
            if (!plugin) {
                plugin = new Plugin(this, options);
                $.data(this, "plugin_" + pluginName, plugin);
            }
        });
        return plugin;
    };

})(jQuery, window, document);

这就是基本的插件结构。我把它称为" arcTimer"并按如下方式使用

HTML

  <div id="testPlug" style = "z-index:1000"></div>

脚本

var aTimer = $("#testPlug").arcTimer({
   // the settings
});

function timerThing(){
    // set the position.
    setTimeout(timerThing,100); // do every 100ms
}
timerThing(); // start it going.

让我们创建设置

defaults = { // angles in normalised Tua. 0 is 0deg, 1 is 360deg (2*PI)
    arcStart : 0, // start pos of arc
    arcEnd : 1,  // end pos of arc
    backgroundColour : "#bbb", // ouside color
    insideRadius : 60,   // inside radius
    outsideRadius : 80,   // outside radius
    centerRadius : undefined, // my bad should be in plugin prototype. But does not matter that its here for now
    outsideDistance : 4,  // pixel clearance of outside arc;
    outlineColour : "#000",  // line colour
    outlineWidth : 2,      // line width
    barColour : "red",  // bar colour
};

现在到功能

一些必需的方法

// starts the timer at is optional. If not there start the thing at 0
start : function (at) {
    // vet at if there else start at 0
    this.position = at !== undefined ? Math.max(0, Math.min(1, at)) : 0;
    this._draw(); // draw it;
},
set : function (pos) {  // sets the pos between 0-1 then draws
    if (pos !== undefined) {
        this.position = Math.max(0, Math.min(1, pos));
        this._draw();
    }
},
complete : function () { // set the pos at 1;
    this.position = 1;
    this._draw();
},

要添加到原型的一些内部变量

_TUA : Math.PI * 2, // two pie
_X : undefined,  // center of arc X
_Y : undefined,
position : 0,   // the bar position 0-1 is full sweep

让我们创建_inti原型

// creates a canvas of the correct size to fit the setting we give
// inserts the canvas into the DOM and saves referances to the plugin prototype
_init : function () {
    this.settings.width = (this.settings.outsideRadius + this.settings.outsideDistance + this.settings.outlineWidth) * 2;
    this.settings.height = this.settings.width;
    this._X = this.settings.height / 2;
    this._Y = this.settings.height / 2;
    var $canvas = $("<canvas id=\"arcTimer_" + $(this.element).attr("id") + "\" width=\"" +
            this.settings.width + "\" height=\"" +
            this.settings.height + "\">" +
            "</canvas>");
    $(this.element).prepend($canvas[0]);
    this.can = $canvas[0];
    this.ctx = $canvas[0].getContext("2d");
    this.ctx.textAlign = "center";
    this.ctx.textBaseline = "middle";
    this.ctx.lineJoin = "round";
    this.ctx.lineCap = "round";
    this.ctx.clearRect(0, 0, this.settings.width, this.settings.height);
},

接下来是一些内部帮助函数。它们相当简单,但同样是一种管理

// draws a arc with at x,y, with an inner radius r1, outer radius r2, 
// from to are in normalized Tua 0 is 0deg, 1 is 360Deg
_drawCircle : function (x, y, r1, r2, from, to) {
    ctx = this.ctx;
    from = from * this._TUA;
    to = to * this._TUA;
    //log("s")
    ctx.beginPath();
    ctx.arc(x, y, r1, to, from, true);
    ctx.arc(x, y, r2, from, to, false);
    ctx.closePath();
    ctx.stroke();
    ctx.fill();
},
// converts a unit value to its range
_mathRange : function (fraction, start, end) {
    return (end - start) * fraction + start;
},
// gets the arc distance in radians at radius  for pixelDist
_mathDistToAngle : function (pixelDist, radius) {
    return pixelDist / radius;
},

最后完成了所有工作。

    _draw : function () {
        var canvas = this.can;  // get the canvas and context
        var ctx = this.ctx;
        // clear the canvas
        ctx.clearRect(0, 0, this.settings.width, this.settings.height);
        // set up styles for outside arc
        ctx.fillStyle = this.settings.backgroundColour;
        ctx.strokeStyle = this.settings.outlineColour;
        ctx.lineWidth = this.settings.outlineWidth;
        // get the angular side of outside clearance
        var pix2Angle = this._mathDistToAngle(this.settings.outsideDistance, this.settings.centerRadius);
        pix2Angle /= this._TUA; // because draw circle use val normalised to tua (PI*2) need to set it to the correct range
        // draw the outside arc
        this._drawCircle(
            this._X,
            this._Y,
            this.settings.insideRadius - this.settings.outsideDistance,
            this.settings.outsideRadius + this.settings.outsideDistance,
            this.settings.arcStart - pix2Angle,
            this.settings.arcEnd + pix2Angle
        );
        // set the inside arc colour
        ctx.fillStyle = this.settings.barColour;
        // draw the inside arc 
        this._drawCircle(
            this._X,
            this._Y,
            this.settings.insideRadius,
            this.settings.outsideRadius,
            this.settings.arcStart,
            this._mathRange(this.position, this.settings.arcStart, this.settings.arcEnd)
        );
    }

这就是它,很容易理解。以下是它的使用。

&#13;
&#13;
(function ($, window, document, undefined) {
    var pluginName = "arcTimer",
    defaults = { // angles in normalised Tua. 0 is 0deg, 1 is 360deg (2*PI)
        arcStart : 0, //
        arcEnd : 1,
        backgroundColour : "#bbb",
        insideRadius : 60,
        outsideRadius : 80,
        centerRadius : undefined,
        outsideDistance : 4,
        outlineColour : "#000",
        outlineWidth : 2,
        barColour : "red",

    };

    function Plugin(element, options) {
        this.element = element;
        this.settings = $.extend({}, defaults, options);
        this.settings.centerRadius = (this.settings.insideRadius + this.settings.outsideRadius) / 2;
        this._defaults = defaults;
        this._name = pluginName;
        this._init();
    }

    Plugin.prototype = {
        _TUA : Math.PI * 2,
        _X : undefined,
        _Y : undefined,
        position : 0,
        start : function (at) {
            this.position = at !== undefined ? Math.max(0, Math.min(1, at)) : 0;
            this._draw();
        },
        set : function (pos) {
            if (pos !== undefined) {
                this.position = Math.max(0, Math.min(1, pos));
                this._draw();
            }
        },
        complete : function () {
            this.position = 1;
            this._draw();
        },
        _init : function () {
            this.settings.width = (this.settings.outsideRadius + this.settings.outsideDistance + this.settings.outlineWidth) * 2;
            this.settings.height = this.settings.width;
            this._X = this.settings.height / 2;
            this._Y = this.settings.height / 2;
            var $canvas = $("<canvas id=\"arcTimer_" + $(this.element).attr("id") + "\" width=\"" +
                    this.settings.width + "\" height=\"" +
                    this.settings.height + "\">" +
                    "</canvas>");
            $(this.element).prepend($canvas[0]);
            this.can = $canvas[0];
            this.ctx = $canvas[0].getContext("2d");
            this.ctx.textAlign = "center";
            this.ctx.textBaseline = "middle";
            this.ctx.lineJoin = "round";
            this.ctx.lineCap = "round";
            this.ctx.clearRect(0, 0, this.settings.width, this.settings.height);
        },
        _drawCircle : function (x, y, r1, r2, from, to) {
            ctx = this.ctx;
            from = from * this._TUA;
            to = to * this._TUA;
            //log("s")
            ctx.beginPath();
            ctx.arc(x, y, r1, to, from, true);
            ctx.arc(x, y, r2, from, to, false);
            ctx.closePath();
            ctx.stroke();
            ctx.fill();
        },
        _mathRange : function (fraction, start, end) {
            return (end - start) * fraction + start;
        },
        _mathDistToAngle : function (pixelDist, radius) {
            return pixelDist / radius;
        },
        _draw : function () {
            var canvas = this.can;
            var ctx = this.ctx;
            ctx.clearRect(0, 0, this.settings.width, this.settings.height);
            ctx.fillStyle = this.settings.backgroundColour;
            ctx.strokeStyle = this.settings.outlineColour;
            ctx.lineWidth = this.settings.outlineWidth;
            var pix2Angle = this._mathDistToAngle(this.settings.outsideDistance, this.settings.centerRadius);
            pix2Angle /= this._TUA; // because draw circle use val normalised to tua (PI*2) need to set it to the correct range
            this._drawCircle(
                this._X,
                this._Y,
                this.settings.insideRadius - this.settings.outsideDistance,
                this.settings.outsideRadius + this.settings.outsideDistance,
                this.settings.arcStart - pix2Angle,
                this.settings.arcEnd + pix2Angle)
            ctx.fillStyle = this.settings.barColour;
            this._drawCircle(
                this._X,
                this._Y,
                this.settings.insideRadius,
                this.settings.outsideRadius,
                this.settings.arcStart,
                this._mathRange(this.position, this.settings.arcStart, this.settings.arcEnd)
            );
        }
    };

    $.fn[pluginName] = function (options) {
        var plugin;
        this.each(function () {
            plugin = $.data(this, "plugin_" + pluginName);
            if (!plugin) {
                plugin = new Plugin(this, options);
                $.data(this, "plugin_" + pluginName, plugin);
            }
        });
        return plugin;
    };

})(jQuery, window, document);


// create an arc timer from 1/3 to 2/3 of a circle    
var arcT = $("#testPlug").arcTimer({
  arcStart     : 1/3,             // 
  arcEnd       : 2/3,      
  backgroundColour : "#bbb",        
  insideRadius : 60,      
  outsideRadius: 80,
  centerRadius:undefined,
  outsideDistance  : 4,
  outlineColour: "#000",          
  outlineWidth: 2,     
  barColour: "red",      

});
arcT.start();
function timerThing(){
  arcT.position += 0.01;  // update the poistion
  if(arcT.position >= 1){
    arcT.settings.barColour = "#0F0";
    arcT.complete(); // all done.
    // do it again in 2 seconds;
    setTimeout(timerThing,2000);  // up date in 100ms
    arcT.settings.barColour = "#F00";
    arcT.position = 0;
  }else{
    arcT.set(arcT.position); // kind of silly I know but I did not think it out
                          // but I am sure you can modify the plugin to do as needed.
    setTimeout(timerThing,100);  // up date in 100ms
  }
}
timerThing();
    
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="testPlug"></div>
&#13;
&#13;
&#13;

相关问题