johnschult / jquery.countdown360 Goto Github PK
View Code? Open in Web Editor NEWThis is a simple attractive circular countdown timer that counts down a number of seconds. The style is configurable and a callback is supported on completion.
This is a simple attractive circular countdown timer that counts down a number of seconds. The style is configurable and a callback is supported on completion.
Hi,
I feel resume()
should be available to control. Is it there? because I did not find in API
What would be the easiest way to make this? Basically when the timer hits 0, it doesn't stop there but starts going to negative (eg. -1, -2,...). And when that happens the stroke would not be countining down but would be a whole circle and either be flashing red or just be red?
Thanks for answer in advance :)
Let's say the amount of time remaining is sent dynamically from a server that keeps countdown even though the page is closed. If the page is refreshed, the counter will take the last remaining time but the counter will still be 100% loaded even though we are half of the clock (server side). Is there a way to tell the counter this is the remaining time based on the original time? Therefore the clock will not show full stroke but only part of it.
Example: I have a countdown of 60 seconds but when displaying the page, the server actually tells me that there're only 30 seconds remaining. The counter should show the stroke half way.
I would like to show one countdown without this number, is it possible?
Is there anyway to set the countdown to use minutes instead of seconds?
Or even set the seconds but change the number inside the circle to be minutes?
Hello John, and thanks for sharing.
After calling countdown.stop(), it is not possible to retrieve the value of the stopped countdown since secondsElapsed is not stored, but always calculated as per current time. I would suggest to handle secondsElapsed within "this". Then update this.secondsElapsed in _draw only, and all other functions in countdown would just take this.secondsElapsed. This would allow to add a function such as:
getSecondsElapsed: function () {
return this.secondsElapsed;
},
What do you think ?
Honestly since I don't see any other questions about this i might be doing it wrong but I can't add the { console.log('completed')} after the function I called without my IDE underlining it in red and I also get a error when I try to exclude it.
Hi,
Thanks for the plugin. Minor adjustment.
I believe onComplete should be empty function and not 'undefined' by default.
Otherwise it forces me to always define it, even if I don't need it.
Hi John,
thanx for the work you have done. I was searching for a solution to stop or destroy the countdown after the redirection to another page on complete using ajax function. I tried: $("#countdown").countdown360(){...}.stop(); instead of start in the second page script but the first countdown still running.
the script on the first page is here:
var timer = $("#countdown").countdown360({
radius : 60,
seconds : 10,
fontColor : '#FFFFFF',
autostart : false,
onComplete : function(){valider();}
})
timer.start();
then the second page:
var timer = $("#countdown").countdown360({
radius : 60,
seconds : 10,
fontColor : '#FFFFFF',
autostart : false,
onComplete : function(){valider();}
})
timer.stop();
thanx for your help
Nicely crafted!!!
Best regards
Hi there,
i have made an environment where i re-use the same timer, but i set its "seconds" with a variable.
Now this all works perfectly, but for some reason, the next time the counter shows again, i see a 0 behind the new counter digit. So essentialy i have overlapping text/seconds (at start, as soon as the new counter starts counting down, its all good again).
Any info about why this is happening ( i do understand this is/could be due re-using the same timer, where it still has the previous last number 0 in its display) and/or how i can reset or clear the timer for re-use? Or is there a reset action, or could this be added for these kind of situations?
Thanks for any info from anyone regarding this issue.
this work code in clockwise: true
;(function ($, window, document, undefined) {
var pluginName = "countdown360",
defaults = {
radius: 15.5, // radius of arc
strokeStyle: "#477050", // the color of the stroke
strokeWidth: undefined, // the stroke width, dynamically calulated if omitted in options
fillStyle: "#8ac575", // the fill color
fontColor: "#477050", // the font color
fontFamily: "sans-serif", // the font family
fontSize: undefined, // the font size, dynamically calulated if omitted in options
fontWeight: 700, // the font weight
autostart: true, // start the countdown automatically
seconds: 10, // the number of seconds to count down
label: ["second", "seconds"], // the label to use or false if none
startOverAfterAdding: true, // Start the timer over after time is added with addSeconds
onComplete: undefined,
clockwise: false
};
function Plugin(element, options) {
this.element = element;
this.settings = $.extend({}, defaults, options);
if (!this.settings.fontSize) {
this.settings.fontSize = this.settings.radius / 1.2;
}
if (!this.settings.strokeWidth) {
this.settings.strokeWidth = this.settings.radius / 4;
}
this._defaults = defaults;
this._name = pluginName;
this._init();
}
Plugin.prototype = {
extendTimer: function (value) {
var seconds = parseInt(value),
secondsElapsed = Math.round((new Date().getTime() - this.startedAt.getTime()) / 1000);
if ((this._secondsLeft(secondsElapsed) + seconds) <= this.settings.seconds) {
this.startedAt.setSeconds(this.startedAt.getSeconds() + parseInt(value));
}
},
addSeconds: function (value) {
var secondsElapsed = Math.round((new Date().getTime() - this.startedAt.getTime()) / 1000);
if (this.settings.startOverAfterAdding) {
this.settings.seconds = this._secondsLeft(secondsElapsed) + parseInt(value);
this.start();
} else {
this.settings.seconds += parseInt(value);
}
},
start: function () {
this.startedAt = new Date();
this._drawCountdownShape(Math.PI * 3.5, !this.settings.clockwise);
this._drawCountdownLabel(0);
this.interval = setInterval(jQuery.proxy(this._draw, this), 1000);
},
stop: function (cb) {
clearInterval(this.interval);
if (cb) {
cb();
}
},
_init: function () {
this.settings.width = (this.settings.radius * 2) + (this.settings.strokeWidth * 2);
this.settings.height = this.settings.width;
this.settings.arcX = this.settings.radius + this.settings.strokeWidth;
this.settings.arcY = this.settings.arcX;
this._initPen(this._getCanvas());
if (this.settings.autostart) {
this.start();
}
},
_getCanvas: function () {
var $canvas = $("<canvas id=\"countdown360_" + $(this.element).attr("id") + "\" width=\"" + this.settings.width + "\" height=\"" + this.settings.height + "\">" +
"<span id=\"countdown-text\" role=\"status\" aria-live=\"assertive\"></span></canvas>");
$(this.element).prepend($canvas[0]);
return $canvas[0];
},
_initPen: function (canvas) {
this.pen = canvas.getContext("2d");
this.pen.lineWidth = this.settings.strokeWidth;
this.pen.strokeStyle = this.settings.strokeStyle;
this.pen.fillStyle = this.settings.fillStyle;
this.pen.textAlign = "center";
this.pen.textBaseline = "middle";
this.ariaText = $(canvas).children("#countdown-text");
this._clearRect();
},
_clearRect: function () {
this.pen.clearRect(0, 0, this.settings.width, this.settings.height);
},
_secondsLeft: function (secondsElapsed) {
return this.settings.seconds - secondsElapsed;
},
_drawCountdownLabel: function (secondsElapsed) {
this.ariaText.text(secondsLeft);
this.pen.font = this.settings.fontWeight + " " + this.settings.fontSize + "px " + this.settings.fontFamily;
var secondsLeft = this._secondsLeft(secondsElapsed),
label = secondsLeft === 1 ? this.settings.label[0] : this.settings.label[1],
drawLabel = this.settings.label && this.settings.label.length === 2,
x = this.settings.width / 2;
if (drawLabel) {
y = this.settings.height / 2 - (this.settings.fontSize / 6.2);
} else {
y = this.settings.height / 2;
}
this.pen.fillStyle = this.settings.fillStyle;
this.pen.fillText(secondsLeft + 1, x, y);
this.pen.fillStyle = this.settings.fontColor;
this.pen.fillText(secondsLeft, x, y);
if (drawLabel) {
this.pen.font = "normal small-caps " + (this.settings.fontSize / 3) + "px " + this.settings.fontFamily;
this.pen.fillText(label, this.settings.width / 2, this.settings.height / 2 + (this.settings.fontSize / 2.2));
}
},
_drawCountdownShape: function (endAngle, drawStroke) {
this.pen.fillStyle = this.settings.fillStyle;
this.pen.beginPath();
this.pen.arc(this.settings.arcX, this.settings.arcY, this.settings.radius, Math.PI * 1.5, endAngle, false);
this.pen.fill();
if (drawStroke) {
this.pen.stroke();
}
},
_draw: function () {
var secondsElapsed = Math.round((new Date().getTime() - this.startedAt.getTime()) / 1000);
if (this.settings.clockwise) {
var endAngle = (((Math.PI * 2) / this.settings.seconds) * secondsElapsed) - (Math.PI * .5);
} else {
var endAngle = (Math.PI * 3.5) - (((Math.PI * 2) / this.settings.seconds) * secondsElapsed);
}
this._clearRect();
if (secondsElapsed < this.settings.seconds) {
this._drawCountdownShape(Math.PI * 3.5, false);
this._drawCountdownShape(endAngle, true);
this._drawCountdownLabel(secondsElapsed);
} else {
this._drawCountdownShape(Math.PI * 3.5, this.settings.clockwise);
this._drawCountdownLabel(this.settings.seconds);
this.stop();
this.settings.onComplete();
}
}
};
$.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);
When I run plugin passing NaN value it shows NaN seconds.
Does it should get the default value or zero instead of NaN?
Hi,
I have issue, i want to start circle again from that position where i left it while refreshing page. I am using database value with it.
It shows correct seconds but counting circle again start from starting position, I want to show it from old position where it was. As Example my counting is from 37 Seconds and circle in middle when i refresh page , it is at 37 seconds but counting circle is again at starting position. Can you help me for sorting out it.
Thanks in advance
dual bar progress
https://github.com/kamlekar/slim-scroll
+
https://github.com/johnschult/jquery.countdown360/
add code in jquery.countdown360 down line var secondsElapsed
this code
var porcentaje = (secondsElapsed * 100) / this.settings.seconds ;
$(".indicator").css("width", porcentaje + "%");
and HTML code
<style> .indicator-wrapper { position: fixed; top: 0; width: 100%; height: 5px; } .indicator { width: 0; height: 100%; background: linear-gradient(135deg,hsl(238deg 84% 61%) 0,hsl(288deg 65% 46% / 63%) 100%); box-shadow: 0 2px 5px #4f46e5; } </style>Example like this codepen
20 seconds - text-warning
10 seconds - text-danger
I tried trying but doesn't work that's why I don't understand where your exactly function name example like this
if(countdown.seconds <= "20")
{
document.getElementById("countdown360_countdown").classList.add("text-warning");
} else if (countdown.seconds <= "10")
document.getElementById("countdown360_countdown").classList.add("text-danger");
}
Please add features we sure many peoples needed this that's why your code works well than other. thank you very much!
When countdown is 2,3,4,5.... "second" have a "s" : "seconds".
When countdown is 1 "second" don't have a "s" : "second".
When countdown is 0, "second" have a "s" : "seconds
Problem is here : label = secondsLeft === 1 ? this.settings.label[0] : this.settings.label[1],
Resolved by : label = secondsLeft <= 1 ? this.settings.label[0] : this.settings.label[1],
In response to a StackOverflow request, I modified your source to support clockwise rotation of the outer ring. http://stackoverflow.com/questions/27268404/how-to-make-countdown-timer-rotate-for-each-second/27271253#27271253 Feel free to incorporate those change.
I could not find any function to get elapsed (or even remaining)
when the timer finishes, the oncomplete option executes a function that changes some attributes and add classes of some div and hide the countdown div.
$("#countdown").countdown360({ strokeStyle : '#ffe1b7', fillStyle : "#fef7ec", radius : 25, seconds : 30, fontColor : '#ffe1b7', smooth : true, label : ["sec", "sec"], onComplete : function () { $("#countdown").addClass('affichage-block'); $("#callnosms").addClass('mb-xl'); $("#callnosms").removeClass('label_smssend'); $("#callnosms").html('<a href=""> xxxxxxx</a>'); } }).start()
the problem is that this function is executes depending on the refresh time. it means each 16ms on the smooth option or each 1 sec in the default option. so when i want to remove the class that i added on the callnosms div it will reappear again. even the link i added in the callnosms element cant be executed on click!
so am i missing something on the code thx for the help
I really like this beautifull countdown and for most, it was what I was looking for for my project.
However I was missing some things.
I needed to be able to:
I managed to get all these options to work and I would love to share it here. However, I've never contributed anything on github so I don't really know how to do this.
If anyone is interested in the things I've added, please feel free to contact me!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.