/** * Basic structure: TC_Class is the public class that is returned upon being called * * So, if you do * var tc = $(".timer").TimeCircles(); * * tc will contain an instance of the public TimeCircles class. It is important to * note that TimeCircles is not chained in the conventional way, check the * documentation for more info on how TimeCircles can be chained. * * After being called/created, the public TimerCircles class will then- for each element * within it's collection, either fetch or create an instance of the private class. * Each function called upon the public class will be forwarded to each instance * of the private classes within the relevant element collection **/ (function($) { // Used to disable drawing on IE8, which can't use canvas var cant_draw = false; var tick_duration = 200; // in ms var debug = (location.hash === "#debug"); function debug_log(msg) { if(debug) { console.log(msg); } } var allUnits = ["Days", "Hours", "Minutes", "Seconds"]; var nextUnits = { Seconds: "Minutes", Minutes: "Hours", Hours: "Days", Days: "Years" }; var secondsIn = { Seconds: 1, Minutes: 60, Hours: 3600, Days: 86400, Months: 2678400, Years: 31536000 }; /** * Converts hex color code into object containing integer values for the r,g,b use * This function (hexToRgb) originates from: * http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb * @param {string} hex color code */ function hexToRgb(hex) { // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF") var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; hex = hex.replace(shorthandRegex, function(m, r, g, b) { return r + r + g + g + b + b; }); var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); return result ? { r: parseInt(result[1], 16), g: parseInt(result[2], 16), b: parseInt(result[3], 16) } : null; } /** * Function s4() and guid() originate from: * http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript */ function s4() { return Math.floor((1 + Math.random()) * 0x10000) .toString(16) .substring(1); } /** * Creates a unique id * @returns {String} */ function guid() { return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4(); } function parse_date(str) { var match = str.match(/^[0-9]{4}-[0-9]{2}-[0-9]{2}\s[0-9]{1,2}:[0-9]{2}:[0-9]{2}$/); if (match !== null && match.length > 0) { var parts = str.split(" "); var date = parts[0].split("-"); var time = parts[1].split(":"); return new Date(date[0], date[1] - 1, date[2], time[0], time[1], time[2]); } // Fallback for different date formats var d = Date.parse(str); if(!isNaN(d)) return d; d = Date.parse(str.replace(/-/g, '/').replace('T', ' ')); if(!isNaN(d)) return d; // Cant find anything return new Date(); } function parse_times(diff, old_diff, total_duration, units, floor) { var raw_time = {}; var raw_old_time = {}; var time = {}; var pct = {}; var old_pct = {}; var old_time = {}; var greater_unit = null; for(var i in units) { var unit = units[i]; var maxUnits; if(greater_unit === null) { maxUnits = total_duration / secondsIn[unit]; } else { maxUnits = secondsIn[greater_unit] / secondsIn[unit]; } var curUnits = (diff / secondsIn[unit]); var oldUnits = (old_diff / secondsIn[unit]); if(floor) curUnits = Math.floor(curUnits); if(floor) oldUnits = Math.floor(oldUnits); if(unit !== "Days"){ curUnits = curUnits % maxUnits; oldUnits = oldUnits % maxUnits; } raw_time[unit] = curUnits; time[unit] = Math.abs(curUnits); raw_old_time[unit] = oldUnits; old_time[unit] = Math.abs(oldUnits); pct[unit] = Math.abs(curUnits) / maxUnits; old_pct[unit] = Math.abs(oldUnits) / maxUnits; greater_unit = unit; } return { raw_time: raw_time, raw_old_time: raw_old_time, time: time, old_time: old_time, pct: pct, old_pct: old_pct }; } var TC_Instance_List = {}; // Try fetch/share instance if(window !== window.top && typeof window.top.TC_Instance_List !== "undefined") { TC_Instance_List = window.top.TC_Instance_List; } else { window.top.TC_Instance_List = TC_Instance_List; } (function(){ var vendors = ['webkit', 'moz']; for(var x = 0; x < vendors.length && !window.top.requestAnimationFrame; ++x) { window.top.requestAnimationFrame = window.top[vendors[x]+'RequestAnimationFrame']; } if (!window.top.requestAnimationFrame) { window.top.requestAnimationFrame = function(callback, element, instance) { if(typeof instance === "undefined") instance = { data: { last_frame: 0 } }; var currTime = new Date().getTime(); var timeToCall = Math.max(0, 16 - (currTime - instance.data.last_frame)); var id = window.top.setTimeout(function() { callback(currTime + timeToCall); }, timeToCall); instance.data.last_frame = currTime + timeToCall; return id; }; window.top.cancelAnimationFrame = function(id) { clearTimeout(id); } } })(); var TC_Instance = function(element, options) { this.element = element; this.container; this.listeners = null; this.data = { paused: false, last_frame: 0, animation_frame: null, timer: false, total_duration: null, prev_time: null, drawn_units: [], text_elements: { Days: null, Hours: null, Minutes: null, Seconds: null }, attributes: { canvas: null, context: null, item_size: null, line_width: null, radius: null, outer_radius: null }, state: { fading: { Days: false, Hours: false, Minutes: false, Seconds: false } } }; this.config = null; this.setOptions(options); this.initialize(); }; TC_Instance.prototype.initialize = function(clear_listeners) { // Initialize drawn units this.data.drawn_units = []; for(var unit in this.config.time) { if(this.config.time[unit].show){ this.data.drawn_units.push(unit); } } // Avoid stacking $(this.element).children('div.time_circles').remove(); if(typeof clear_listeners === "undefined") clear_listeners = true; if(clear_listeners || this.listeners === null) { this.listeners = { all: [], visible: [] }; } this.container = $("