Changeset 113803 in spip-zone
- Timestamp:
- Feb 7, 2019, 4:55:54 PM (2 years ago)
- Location:
- _plugins_/timecircles/branches/v1.5.3
- Files:
-
- 1 deleted
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
_plugins_/timecircles/branches/v1.5.3/js/timecircles.js
r112655 r113803 1 1 /** 2 * TimeCircles v1.5.3.15 / SPIP 3.1+ 3 * by Wim Barelds - https://wimbarelds.nl/ 4 * brought to SPIP by Loiseau2nuit (2018) 5 * https://contrib.spip.net/Loiseau2nuit 6 * Licence: MIT 7 * 8 * Calling functions brought by lib/timecircles.js 9 * with some little default settings. 10 * Copy this file in your own '/squelettes/js' 11 * directory to tweak countdowns & timers 12 * 13 * See & tweak for yourself custom examples: 14 * http://git.wimbarelds.nl/TimeCircles/ 15 **/ 16 jQuery(document).ready(function(){ 17 $(".DateCountdown").TimeCircles(); 18 $(".CountDownTimer").TimeCircles({ time: { Days: { show: false }, Hours: { show: false } }}); 19 $(".PageOpenTimer").TimeCircles(); 20 21 var updateTime = function(){ 22 var date = $("#date").val(); 23 var time = $("#time").val(); 24 var datetime = date + ' ' + time + ':00'; 25 $(".DateCountdown").data('date', datetime).TimeCircles().start(); 26 } 27 $("#date").change(updateTime).keyup(updateTime); 28 $("#time").change(updateTime).keyup(updateTime); 29 30 // Start and stop are methods applied on the public TimeCircles instance 31 $(".startTimer").click(function() { 32 $(".CountDownTimer").TimeCircles().start(); 33 }); 34 $(".stopTimer").click(function() { 35 $(".CountDownTimer").TimeCircles().stop(); 36 }); 37 38 // Fade in and fade out are examples of how chaining can be done with TimeCircles 39 $(".fadeIn").click(function() { 40 $(".PageOpenTimer").fadeIn(); 41 }); 42 $(".fadeOut").click(function() { 43 $(".PageOpenTimer").fadeOut(); 44 }); 45 46 $(window).on('resize', function(){ 47 $('.DateCountdown').TimeCircles().rebuild(); 48 $('.CountDownTimer').TimeCircles().rebuild(); 49 $('.PageOpenTimer').TimeCircles().rebuild(); 50 }); 51 52 }); 2 * Basic structure: TC_Class is the public class that is returned upon being called 3 * 4 * So, if you do 5 * var tc = $(".timer").TimeCircles(); 6 * 7 * tc will contain an instance of the public TimeCircles class. It is important to 8 * note that TimeCircles is not chained in the conventional way, check the 9 * documentation for more info on how TimeCircles can be chained. 10 * 11 * After being called/created, the public TimerCircles class will then- for each element 12 * within it's collection, either fetch or create an instance of the private class. 13 * Each function called upon the public class will be forwarded to each instance 14 * of the private classes within the relevant element collection 15 **/ 16 (function($) { 17 18 var useWindow = window; 19 20 // From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys 21 if (!Object.keys) { 22 Object.keys = (function() { 23 'use strict'; 24 var hasOwnProperty = Object.prototype.hasOwnProperty, 25 hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'), 26 dontEnums = [ 27 'toString', 28 'toLocaleString', 29 'valueOf', 30 'hasOwnProperty', 31 'isPrototypeOf', 32 'propertyIsEnumerable', 33 'constructor' 34 ], 35 dontEnumsLength = dontEnums.length; 36 37 return function(obj) { 38 if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) { 39 throw new TypeError('Object.keys called on non-object'); 40 } 41 42 var result = [], prop, i; 43 44 for (prop in obj) { 45 if (hasOwnProperty.call(obj, prop)) { 46 result.push(prop); 47 } 48 } 49 50 if (hasDontEnumBug) { 51 for (i = 0; i < dontEnumsLength; i++) { 52 if (hasOwnProperty.call(obj, dontEnums[i])) { 53 result.push(dontEnums[i]); 54 } 55 } 56 } 57 return result; 58 }; 59 }()); 60 } 61 62 // Used to disable some features on IE8 63 var limited_mode = false; 64 var tick_duration = 200; // in ms 65 66 var debug = (location.hash === "#debug"); 67 function debug_log(msg) { 68 if (debug) { 69 console.log(msg); 70 } 71 } 72 73 var allUnits = ["Days", "Hours", "Minutes", "Seconds"]; 74 var nextUnits = { 75 Seconds: "Minutes", 76 Minutes: "Hours", 77 Hours: "Days", 78 Days: "Years" 79 }; 80 var secondsIn = { 81 Seconds: 1, 82 Minutes: 60, 83 Hours: 3600, 84 Days: 86400, 85 Months: 2678400, 86 Years: 31536000 87 }; 88 89 /** 90 * Converts hex color code into object containing integer values for the r,g,b use 91 * This function (hexToRgb) originates from: 92 * http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb 93 * @param {string} hex color code 94 */ 95 function hexToRgb(hex) { 96 // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF") 97 var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; 98 hex = hex.replace(shorthandRegex, function(m, r, g, b) { 99 return r + r + g + g + b + b; 100 }); 101 102 var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); 103 return result ? { 104 r: parseInt(result[1], 16), 105 g: parseInt(result[2], 16), 106 b: parseInt(result[3], 16) 107 } : null; 108 } 109 110 function isCanvasSupported() { 111 var elem = document.createElement('canvas'); 112 return !!(elem.getContext && elem.getContext('2d')); 113 } 114 115 /** 116 * Function s4() and guid() originate from: 117 * http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript 118 */ 119 function s4() { 120 return Math.floor((1 + Math.random()) * 0x10000) 121 .toString(16) 122 .substring(1); 123 } 124 125 /** 126 * Creates a unique id 127 * @returns {String} 128 */ 129 function guid() { 130 return s4() + s4() + '-' + s4() + '-' + s4() + '-' + 131 s4() + '-' + s4() + s4() + s4(); 132 } 133 134 /** 135 * Array.prototype.indexOf fallback for IE8 136 * @param {Mixed} mixed 137 * @returns {Number} 138 */ 139 if (!Array.prototype.indexOf) { 140 Array.prototype.indexOf = function(elt /*, from*/) 141 { 142 var len = this.length >>> 0; 143 144 var from = Number(arguments[1]) || 0; 145 from = (from < 0) 146 ? Math.ceil(from) 147 : Math.floor(from); 148 if (from < 0) 149 from += len; 150 151 for (; from < len; from++) 152 { 153 if (from in this && 154 this[from] === elt) 155 return from; 156 } 157 return -1; 158 }; 159 } 160 161 function parse_date(str) { 162 var match = str.match(/^[0-9]{4}-[0-9]{2}-[0-9]{2}\s[0-9]{1,2}:[0-9]{2}:[0-9]{2}$/); 163 if (match !== null && match.length > 0) { 164 var parts = str.split(" "); 165 var date = parts[0].split("-"); 166 var time = parts[1].split(":"); 167 return new Date(date[0], date[1] - 1, date[2], time[0], time[1], time[2]); 168 } 169 // Fallback for different date formats 170 var d = Date.parse(str); 171 if (!isNaN(d)) 172 return d; 173 d = Date.parse(str.replace(/-/g, '/').replace('T', ' ')); 174 if (!isNaN(d)) 175 return d; 176 // Cant find anything 177 return new Date(); 178 } 179 180 function parse_times(diff, old_diff, total_duration, units, floor) { 181 var raw_time = {}; 182 var raw_old_time = {}; 183 var time = {}; 184 var pct = {}; 185 var old_pct = {}; 186 var old_time = {}; 187 188 var greater_unit = null; 189 for(var i = 0; i < units.length; i++) { 190 var unit = units[i]; 191 var maxUnits; 192 193 if (greater_unit === null) { 194 maxUnits = total_duration / secondsIn[unit]; 195 } 196 else { 197 maxUnits = secondsIn[greater_unit] / secondsIn[unit]; 198 } 199 200 var curUnits = (diff / secondsIn[unit]); 201 var oldUnits = (old_diff / secondsIn[unit]); 202 203 if(floor) { 204 if(curUnits > 0) curUnits = Math.floor(curUnits); 205 else curUnits = Math.ceil(curUnits); 206 if(oldUnits > 0) oldUnits = Math.floor(oldUnits); 207 else oldUnits = Math.ceil(oldUnits); 208 } 209 210 if (unit !== "Days") { 211 curUnits = curUnits % maxUnits; 212 oldUnits = oldUnits % maxUnits; 213 } 214 215 raw_time[unit] = curUnits; 216 time[unit] = Math.abs(curUnits); 217 raw_old_time[unit] = oldUnits; 218 old_time[unit] = Math.abs(oldUnits); 219 pct[unit] = Math.abs(curUnits) / maxUnits; 220 old_pct[unit] = Math.abs(oldUnits) / maxUnits; 221 222 greater_unit = unit; 223 } 224 225 return { 226 raw_time: raw_time, 227 raw_old_time: raw_old_time, 228 time: time, 229 old_time: old_time, 230 pct: pct, 231 old_pct: old_pct 232 }; 233 } 234 235 var TC_Instance_List = {}; 236 function updateUsedWindow() { 237 if(typeof useWindow.TC_Instance_List !== "undefined") { 238 TC_Instance_List = useWindow.TC_Instance_List; 239 } 240 else { 241 useWindow.TC_Instance_List = TC_Instance_List; 242 } 243 initializeAnimationFrameHandler(useWindow); 244 }; 245 246 function initializeAnimationFrameHandler(w) { 247 var vendors = ['webkit', 'moz']; 248 for (var x = 0; x < vendors.length && !w.requestAnimationFrame; ++x) { 249 w.requestAnimationFrame = w[vendors[x] + 'RequestAnimationFrame']; 250 w.cancelAnimationFrame = w[vendors[x] + 'CancelAnimationFrame']; 251 } 252 253 if (!w.requestAnimationFrame || !w.cancelAnimationFrame) { 254 w.requestAnimationFrame = function(callback, element, instance) { 255 if (typeof instance === "undefined") 256 instance = {data: {last_frame: 0}}; 257 var currTime = new Date().getTime(); 258 var timeToCall = Math.max(0, 16 - (currTime - instance.data.last_frame)); 259 var id = w.setTimeout(function() { 260 callback(currTime + timeToCall); 261 }, timeToCall); 262 instance.data.last_frame = currTime + timeToCall; 263 return id; 264 }; 265 w.cancelAnimationFrame = function(id) { 266 clearTimeout(id); 267 }; 268 } 269 }; 270 271 272 var TC_Instance = function(element, options) { 273 this.element = element; 274 this.container; 275 this.listeners = null; 276 this.data = { 277 paused: false, 278 last_frame: 0, 279 animation_frame: null, 280 interval_fallback: null, 281 timer: false, 282 total_duration: null, 283 prev_time: null, 284 drawn_units: [], 285 text_elements: { 286 Days: null, 287 Hours: null, 288 Minutes: null, 289 Seconds: null 290 }, 291 attributes: { 292 canvas: null, 293 context: null, 294 item_size: null, 295 line_width: null, 296 radius: null, 297 outer_radius: null 298 }, 299 state: { 300 fading: { 301 Days: false, 302 Hours: false, 303 Minutes: false, 304 Seconds: false 305 } 306 } 307 }; 308 309 this.config = null; 310 this.setOptions(options); 311 this.initialize(); 312 }; 313 314 TC_Instance.prototype.clearListeners = function() { 315 this.listeners = { all: [], visible: [] }; 316 }; 317 318 TC_Instance.prototype.addTime = function(seconds_to_add) { 319 if(this.data.attributes.ref_date instanceof Date) { 320 var d = this.data.attributes.ref_date; 321 d.setSeconds(d.getSeconds() + seconds_to_add); 322 } 323 else if(!isNaN(this.data.attributes.ref_date)) { 324 this.data.attributes.ref_date += (seconds_to_add * 1000); 325 } 326 }; 327 328 TC_Instance.prototype.initialize = function(clear_listeners) { 329 // Initialize drawn units 330 this.data.drawn_units = []; 331 for(var i = 0; i < Object.keys(this.config.time).length; i++) { 332 var unit = Object.keys(this.config.time)[i]; 333 if (this.config.time[unit].show) { 334 this.data.drawn_units.push(unit); 335 } 336 } 337 338 // Avoid stacking 339 $(this.element).children('div.time_circles').remove(); 340 341 if (typeof clear_listeners === "undefined") 342 clear_listeners = true; 343 if (clear_listeners || this.listeners === null) { 344 this.clearListeners(); 345 } 346 this.container = $("<div>"); 347 this.container.addClass('time_circles'); 348 this.container.appendTo(this.element); 349 350 // Determine the needed width and height of TimeCircles 351 var height = this.element.offsetHeight; 352 var width = this.element.offsetWidth; 353 if (height === 0) 354 height = $(this.element).height(); 355 if (width === 0) 356 width = $(this.element).width(); 357 358 if (height === 0 && width > 0) 359 height = width / this.data.drawn_units.length; 360 else if (width === 0 && height > 0) 361 width = height * this.data.drawn_units.length; 362 363 // Create our canvas and set it to the appropriate size 364 var canvasElement = document.createElement('canvas'); 365 canvasElement.width = width; 366 canvasElement.height = height; 367 368 // Add canvas elements 369 this.data.attributes.canvas = $(canvasElement); 370 this.data.attributes.canvas.appendTo(this.container); 371 372 // Check if the browser has browser support 373 var canvasSupported = isCanvasSupported(); 374 // If the browser doesn't have browser support, check if explorer canvas is loaded 375 // (A javascript library that adds canvas support to browsers that don't have it) 376 if(!canvasSupported && typeof G_vmlCanvasManager !== "undefined") { 377 G_vmlCanvasManager.initElement(canvasElement); 378 limited_mode = true; 379 canvasSupported = true; 380 } 381 if(canvasSupported) { 382 this.data.attributes.context = canvasElement.getContext('2d'); 383 } 384 385 this.data.attributes.item_size = Math.min(width / this.data.drawn_units.length, height); 386 this.data.attributes.line_width = this.data.attributes.item_size * this.config.fg_width; 387 this.data.attributes.radius = ((this.data.attributes.item_size * 0.8) - this.data.attributes.line_width) / 2; 388 this.data.attributes.outer_radius = this.data.attributes.radius + 0.5 * Math.max(this.data.attributes.line_width, this.data.attributes.line_width * this.config.bg_width); 389 390 // Prepare Time Elements 391 var i = 0; 392 for (var key in this.data.text_elements) { 393 if (!this.config.time[key].show) 394 continue; 395 396 var textElement = $("<div>"); 397 textElement.addClass('textDiv_' + key); 398 textElement.css("top", Math.round(0.35 * this.data.attributes.item_size)); 399 textElement.css("left", Math.round(i++ * this.data.attributes.item_size)); 400 textElement.css("width", this.data.attributes.item_size); 401 textElement.appendTo(this.container); 402 403 var headerElement = $("<h4>"); 404 headerElement.text(this.config.time[key].text); // Options 405 headerElement.css("font-size", Math.round(this.config.text_size * this.data.attributes.item_size)); 406 headerElement.css("line-height", Math.round(this.config.text_size * this.data.attributes.item_size) + "px"); 407 headerElement.appendTo(textElement); 408 409 var numberElement = $("<span>"); 410 numberElement.css("font-size", Math.round(3 * this.config.text_size * this.data.attributes.item_size)); 411 numberElement.css("line-height", Math.round(this.config.text_size * this.data.attributes.item_size) + "px"); 412 numberElement.appendTo(textElement); 413 414 this.data.text_elements[key] = numberElement; 415 } 416 417 this.start(); 418 if (!this.config.start) { 419 this.data.paused = true; 420 } 421 422 // Set up interval fallback 423 var _this = this; 424 this.data.interval_fallback = useWindow.setInterval(function(){ 425 _this.update.call(_this, true); 426 }, 100); 427 }; 428 429 TC_Instance.prototype.update = function(nodraw) { 430 if(typeof nodraw === "undefined") { 431 nodraw = false; 432 } 433 else if(nodraw && this.data.paused) { 434 return; 435 } 436 437 if(limited_mode) { 438 //Per unit clearing doesn't work in IE8 using explorer canvas, so do it in one time. The downside is that radial fade cant be used 439 this.data.attributes.context.clearRect(0, 0, this.data.attributes.canvas[0].width, this.data.attributes.canvas[0].hright); 440 } 441 var diff, old_diff; 442 443 var prevDate = this.data.prev_time; 444 var curDate = new Date(); 445 this.data.prev_time = curDate; 446 447 if (prevDate === null) 448 prevDate = curDate; 449 450 // If not counting past zero, and time < 0, then simply draw the zero point once, and call stop 451 if (!this.config.count_past_zero) { 452 if (curDate > this.data.attributes.ref_date) { 453 for(var i = 0; i < this.data.drawn_units.length; i++) { 454 var key = this.data.drawn_units[i]; 455 456 // Set the text value 457 this.data.text_elements[key].text("0"); 458 var x = (i * this.data.attributes.item_size) + (this.data.attributes.item_size / 2); 459 var y = this.data.attributes.item_size / 2; 460 var color = this.config.time[key].color; 461 this.drawArc(x, y, color, 0); 462 } 463 this.stop(); 464 return; 465 } 466 } 467 468 // Compare current time with reference 469 diff = (this.data.attributes.ref_date - curDate) / 1000; 470 old_diff = (this.data.attributes.ref_date - prevDate) / 1000; 471 472 var floor = this.config.animation !== "smooth"; 473 474 var visible_times = parse_times(diff, old_diff, this.data.total_duration, this.data.drawn_units, floor); 475 var all_times = parse_times(diff, old_diff, secondsIn["Years"], allUnits, floor); 476 477 var i = 0; 478 var j = 0; 479 var lastKey = null; 480 481 var cur_shown = this.data.drawn_units.slice(); 482 for (var i in allUnits) { 483 var key = allUnits[i]; 484 485 // Notify (all) listeners 486 if (Math.floor(all_times.raw_time[key]) !== Math.floor(all_times.raw_old_time[key])) { 487 this.notifyListeners(key, Math.floor(all_times.time[key]), Math.floor(diff), "all"); 488 } 489 490 if (cur_shown.indexOf(key) < 0) 491 continue; 492 493 // Notify (visible) listeners 494 if (Math.floor(visible_times.raw_time[key]) !== Math.floor(visible_times.raw_old_time[key])) { 495 this.notifyListeners(key, Math.floor(visible_times.time[key]), Math.floor(diff), "visible"); 496 } 497 498 if(!nodraw) { 499 // Set the text value 500 this.data.text_elements[key].text(Math.floor(Math.abs(visible_times.time[key]))); 501 502 var x = (j * this.data.attributes.item_size) + (this.data.attributes.item_size / 2); 503 var y = this.data.attributes.item_size / 2; 504 var color = this.config.time[key].color; 505 506 if (this.config.animation === "smooth") { 507 if (lastKey !== null && !limited_mode) { 508 if (Math.floor(visible_times.time[lastKey]) > Math.floor(visible_times.old_time[lastKey])) { 509 this.radialFade(x, y, color, 1, key); 510 this.data.state.fading[key] = true; 511 } 512 else if (Math.floor(visible_times.time[lastKey]) < Math.floor(visible_times.old_time[lastKey])) { 513 this.radialFade(x, y, color, 0, key); 514 this.data.state.fading[key] = true; 515 } 516 } 517 if (!this.data.state.fading[key]) { 518 this.drawArc(x, y, color, visible_times.pct[key]); 519 } 520 } 521 else { 522 this.animateArc(x, y, color, visible_times.pct[key], visible_times.old_pct[key], (new Date()).getTime() + tick_duration); 523 } 524 } 525 lastKey = key; 526 j++; 527 } 528 529 // Dont request another update if we should be paused 530 if(this.data.paused || nodraw) { 531 return; 532 } 533 534 // We need this for our next frame either way 535 var _this = this; 536 var update = function() { 537 _this.update.call(_this); 538 }; 539 540 // Either call next update immediately, or in a second 541 if (this.config.animation === "smooth") { 542 // Smooth animation, Queue up the next frame 543 this.data.animation_frame = useWindow.requestAnimationFrame(update, _this.element, _this); 544 } 545 else { 546 // Tick animation, Don't queue until very slightly after the next second happens 547 var delay = (diff % 1) * 1000; 548 if (delay < 0) 549 delay = 1000 + delay; 550 delay += 50; 551 552 _this.data.animation_frame = useWindow.setTimeout(function() { 553 _this.data.animation_frame = useWindow.requestAnimationFrame(update, _this.element, _this); 554 }, delay); 555 } 556 }; 557 558 TC_Instance.prototype.animateArc = function(x, y, color, target_pct, cur_pct, animation_end) { 559 if (this.data.attributes.context === null) 560 return; 561 562 var diff = cur_pct - target_pct; 563 if (Math.abs(diff) > 0.5) { 564 if (target_pct === 0) { 565 this.radialFade(x, y, color, 1); 566 } 567 else { 568 this.radialFade(x, y, color, 0); 569 } 570 } 571 else { 572 var progress = (tick_duration - (animation_end - (new Date()).getTime())) / tick_duration; 573 if (progress > 1) 574 progress = 1; 575 576 var pct = (cur_pct * (1 - progress)) + (target_pct * progress); 577 this.drawArc(x, y, color, pct); 578 579 //var show_pct = 580 if (progress >= 1) 581 return; 582 var _this = this; 583 useWindow.requestAnimationFrame(function() { 584 _this.animateArc(x, y, color, target_pct, cur_pct, animation_end); 585 }, this.element); 586 } 587 }; 588 589 TC_Instance.prototype.drawArc = function(x, y, color, pct) { 590 if (this.data.attributes.context === null) 591 return; 592 593 var clear_radius = Math.max(this.data.attributes.outer_radius, this.data.attributes.item_size / 2); 594 if(!limited_mode) { 595 this.data.attributes.context.clearRect( 596 x - clear_radius, 597 y - clear_radius, 598 clear_radius * 2, 599 clear_radius * 2 600 ); 601 } 602 603 if (this.config.use_background) { 604 this.data.attributes.context.beginPath(); 605 this.data.attributes.context.arc(x, y, this.data.attributes.radius, 0, 2 * Math.PI, false); 606 this.data.attributes.context.lineWidth = this.data.attributes.line_width * this.config.bg_width; 607 608 // line color 609 this.data.attributes.context.strokeStyle = this.config.circle_bg_color; 610 this.data.attributes.context.stroke(); 611 } 612 613 // Direction 614 var startAngle, endAngle, counterClockwise; 615 var defaultOffset = (-0.5 * Math.PI); 616 var fullCircle = 2 * Math.PI; 617 startAngle = defaultOffset + (this.config.start_angle / 360 * fullCircle); 618 var offset = (2 * pct * Math.PI); 619 620 if (this.config.direction === "Both") { 621 counterClockwise = false; 622 startAngle -= (offset / 2); 623 endAngle = startAngle + offset; 624 } 625 else { 626 if (this.config.direction === "Clockwise") { 627 counterClockwise = false; 628 endAngle = startAngle + offset; 629 } 630 else { 631 counterClockwise = true; 632 endAngle = startAngle - offset; 633 } 634 } 635 636 this.data.attributes.context.beginPath(); 637 this.data.attributes.context.arc(x, y, this.data.attributes.radius, startAngle, endAngle, counterClockwise); 638 this.data.attributes.context.lineWidth = this.data.attributes.line_width; 639 640 // line color 641 this.data.attributes.context.strokeStyle = color; 642 this.data.attributes.context.stroke(); 643 }; 644 645 TC_Instance.prototype.radialFade = function(x, y, color, from, key) { 646 // TODO: Make fade_time option 647 var rgb = hexToRgb(color); 648 var _this = this; // We have a few inner scopes here that will need access to our instance 649 650 var step = 0.2 * ((from === 1) ? -1 : 1); 651 var i; 652 for (i = 0; from <= 1 && from >= 0; i++) { 653 // Create inner scope so our variables are not changed by the time the Timeout triggers 654 (function() { 655 var delay = 50 * i; 656 var rgba = "rgba(" + rgb.r + ", " + rgb.g + ", " + rgb.b + ", " + (Math.round(from * 10) / 10) + ")"; 657 useWindow.setTimeout(function() { 658 _this.drawArc(x, y, rgba, 1); 659 }, delay); 660 }()); 661 from += step; 662 } 663 if (typeof key !== undefined) { 664 useWindow.setTimeout(function() { 665 _this.data.state.fading[key] = false; 666 }, 50 * i); 667 } 668 }; 669 670 TC_Instance.prototype.timeLeft = function() { 671 if (this.data.paused && typeof this.data.timer === "number") { 672 return this.data.timer; 673 } 674 var now = new Date(); 675 return ((this.data.attributes.ref_date - now) / 1000); 676 }; 677 678 TC_Instance.prototype.start = function() { 679 useWindow.cancelAnimationFrame(this.data.animation_frame); 680 useWindow.clearTimeout(this.data.animation_frame) 681 682 // Check if a date was passed in html attribute or jquery data 683 var attr_data_date = $(this.element).data('date'); 684 if (typeof attr_data_date === "undefined") { 685 attr_data_date = $(this.element).attr('data-date'); 686 } 687 if (typeof attr_data_date === "string") { 688 this.data.attributes.ref_date = parse_date(attr_data_date); 689 } 690 // Check if this is an unpause of a timer 691 else if (typeof this.data.timer === "number") { 692 if (this.data.paused) { 693 this.data.attributes.ref_date = (new Date()).getTime() + (this.data.timer * 1000); 694 } 695 } 696 else { 697 // Try to get data-timer 698 var attr_data_timer = $(this.element).data('timer'); 699 if (typeof attr_data_timer === "undefined") { 700 attr_data_timer = $(this.element).attr('data-timer'); 701 } 702 if (typeof attr_data_timer === "string") { 703 attr_data_timer = parseFloat(attr_data_timer); 704 } 705 if (typeof attr_data_timer === "number") { 706 this.data.timer = attr_data_timer; 707 this.data.attributes.ref_date = (new Date()).getTime() + (attr_data_timer * 1000); 708 } 709 else { 710 // data-timer and data-date were both not set 711 // use config date 712 this.data.attributes.ref_date = this.config.ref_date; 713 } 714 } 715 716 // Start running 717 this.data.paused = false; 718 this.update.call(this); 719 }; 720 721 TC_Instance.prototype.restart = function() { 722 this.data.timer = false; 723 this.start(); 724 }; 725 726 TC_Instance.prototype.stop = function() { 727 if (typeof this.data.timer === "number") { 728 this.data.timer = this.timeLeft(this); 729 } 730 // Stop running 731 this.data.paused = true; 732 useWindow.cancelAnimationFrame(this.data.animation_frame); 733 }; 734 735 TC_Instance.prototype.destroy = function() { 736 this.clearListeners(); 737 this.stop(); 738 useWindow.clearInterval(this.data.interval_fallback); 739 this.data.interval_fallback = null; 740 741 this.container.remove(); 742 $(this.element).removeAttr('data-tc-id'); 743 $(this.element).removeData('tc-id'); 744 }; 745 746 TC_Instance.prototype.setOptions = function(options) { 747 if (this.config === null) { 748 this.default_options.ref_date = new Date(); 749 this.config = $.extend(true, {}, this.default_options); 750 } 751 $.extend(true, this.config, options); 752 753 // Use window.top if use_top_frame is true 754 if(this.config.use_top_frame) { 755 useWindow = window.top; 756 } 757 else { 758 useWindow = window; 759 } 760 updateUsedWindow(); 761 762 this.data.total_duration = this.config.total_duration; 763 if (typeof this.data.total_duration === "string") { 764 if (typeof secondsIn[this.data.total_duration] !== "undefined") { 765 // If set to Years, Months, Days, Hours or Minutes, fetch the secondsIn value for that 766 this.data.total_duration = secondsIn[this.data.total_duration]; 767 } 768 else if (this.data.total_duration === "Auto") { 769 // If set to auto, total_duration is the size of 1 unit, of the unit type bigger than the largest shown 770 for(var i = 0; i < Object.keys(this.config.time).length; i++) { 771 var unit = Object.keys(this.config.time)[i]; 772 if (this.config.time[unit].show) { 773 this.data.total_duration = secondsIn[nextUnits[unit]]; 774 break; 775 } 776 } 777 } 778 else { 779 // If it's a string, but neither of the above, user screwed up. 780 this.data.total_duration = secondsIn["Years"]; 781 console.error("Valid values for TimeCircles config.total_duration are either numeric, or (string) Years, Months, Days, Hours, Minutes, Auto"); 782 } 783 } 784 }; 785 786 TC_Instance.prototype.addListener = function(f, context, type) { 787 if (typeof f !== "function") 788 return; 789 if (typeof type === "undefined") 790 type = "visible"; 791 this.listeners[type].push({func: f, scope: context}); 792 }; 793 794 TC_Instance.prototype.notifyListeners = function(unit, value, total, type) { 795 for (var i = 0; i < this.listeners[type].length; i++) { 796 var listener = this.listeners[type][i]; 797 listener.func.apply(listener.scope, [unit, value, total]); 798 } 799 }; 800 801 TC_Instance.prototype.default_options = { 802 ref_date: new Date(), 803 start: true, 804 animation: "smooth", 805 count_past_zero: true, 806 circle_bg_color: "#60686F", 807 use_background: true, 808 fg_width: 0.1, 809 bg_width: 1.2, 810 text_size: 0.07, 811 total_duration: "Auto", 812 direction: "Clockwise", 813 use_top_frame: false, 814 start_angle: 0, 815 time: { 816 Days: { 817 show: true, 818 text: "Days", 819 color: "#FC6" 820 }, 821 Hours: { 822 show: true, 823 text: "Hours", 824 color: "#9CF" 825 }, 826 Minutes: { 827 show: true, 828 text: "Minutes", 829 color: "#BFB" 830 }, 831 Seconds: { 832 show: true, 833 text: "Seconds", 834 color: "#F99" 835 } 836 } 837 }; 838 839 // Time circle class 840 var TC_Class = function(elements, options) { 841 this.elements = elements; 842 this.options = options; 843 this.foreach(); 844 }; 845 846 TC_Class.prototype.getInstance = function(element) { 847 var instance; 848 849 var cur_id = $(element).data("tc-id"); 850 if (typeof cur_id === "undefined") { 851 cur_id = guid(); 852 $(element).attr("data-tc-id", cur_id); 853 } 854 if (typeof TC_Instance_List[cur_id] === "undefined") { 855 var options = this.options; 856 var element_options = $(element).data('options'); 857 if (typeof element_options === "string") { 858 element_options = JSON.parse(element_options); 859 } 860 if (typeof element_options === "object") { 861 options = $.extend(true, {}, this.options, element_options); 862 } 863 instance = new TC_Instance(element, options); 864 TC_Instance_List[cur_id] = instance; 865 } 866 else { 867 instance = TC_Instance_List[cur_id]; 868 if (typeof this.options !== "undefined") { 869 instance.setOptions(this.options); 870 } 871 } 872 return instance; 873 }; 874 875 TC_Class.prototype.addTime = function(seconds_to_add) { 876 this.foreach(function(instance) { 877 instance.addTime(seconds_to_add); 878 }); 879 }; 880 881 TC_Class.prototype.foreach = function(callback) { 882 var _this = this; 883 this.elements.each(function() { 884 var instance = _this.getInstance(this); 885 if (typeof callback === "function") { 886 callback(instance); 887 } 888 }); 889 return this; 890 }; 891 892 TC_Class.prototype.start = function() { 893 this.foreach(function(instance) { 894 instance.start(); 895 }); 896 return this; 897 }; 898 899 TC_Class.prototype.stop = function() { 900 this.foreach(function(instance) { 901 instance.stop(); 902 }); 903 return this; 904 }; 905 906 TC_Class.prototype.restart = function() { 907 this.foreach(function(instance) { 908 instance.restart(); 909 }); 910 return this; 911 }; 912 913 TC_Class.prototype.rebuild = function() { 914 this.foreach(function(instance) { 915 instance.initialize(false); 916 }); 917 return this; 918 }; 919 920 TC_Class.prototype.getTime = function() { 921 return this.getInstance(this.elements[0]).timeLeft(); 922 }; 923 924 TC_Class.prototype.addListener = function(f, type) { 925 if (typeof type === "undefined") 926 type = "visible"; 927 var _this = this; 928 this.foreach(function(instance) { 929 instance.addListener(f, _this.elements, type); 930 }); 931 return this; 932 }; 933 934 TC_Class.prototype.destroy = function() { 935 this.foreach(function(instance) { 936 instance.destroy(); 937 }); 938 return this; 939 }; 940 941 TC_Class.prototype.end = function() { 942 return this.elements; 943 }; 944 945 $.fn.TimeCircles = function(options) { 946 return new TC_Class(this, options); 947 }; 948 }(jQuery)); -
_plugins_/timecircles/branches/v1.5.3/paquet.xml
r112669 r113803 2 2 prefix="timecircles" 3 3 categorie="squelette" 4 version="1.5.3.2 2"4 version="1.5.3.23" 5 5 etat="test" 6 6 compatibilite="[3.1.0;3.3.*]" -
_plugins_/timecircles/branches/v1.5.3/timecircles_pipelines.php
r112669 r113803 33 33 **/ 34 34 function timecircles_insert_head($flux){ 35 $flux .= '<script src="'.generer_url_public('lib/timecircles.js').'" type="text/javascript"></script>' 36 . '<script src="'.find_in_path('js/timecircles.js').'" type="text/javascript"></script>'; 35 $flux .= '<script src="'.find_in_path('js/timecircles.js').'" type="text/javascript"></script>' 36 .<<<EOF 37 <script type="text/javascript"> 38 <!-- 39 jQuery(document).ready(function(){ 40 $(".DateCountdown").TimeCircles(); 41 $(".CountDownTimer").TimeCircles({ time: { Days: { show: false }, Hours: { show: false } }}); 42 $(".PageOpenTimer").TimeCircles(); 43 var updateTime = function(){ 44 var date = $("#date").val(); 45 var time = $("#time").val(); 46 var datetime = date + ' ' + time + ':00'; 47 $(".DateCountdown").data('date', datetime).TimeCircles().start(); 48 } 49 $("#date").change(updateTime).keyup(updateTime); 50 $("#time").change(updateTime).keyup(updateTime); 51 /* Start and stop are methods applied on the public TimeCircles instance */ 52 $(".startTimer").click(function() { 53 $(".CountDownTimer").TimeCircles().start(); 54 }); 55 $(".stopTimer").click(function() { 56 $(".CountDownTimer").TimeCircles().stop(); 57 }); 58 /* Fade in and fade out are examples of how chaining can be done with TimeCircles */ 59 $(".fadeIn").click(function() { 60 $(".PageOpenTimer").fadeIn(); 61 }); 62 $(".fadeOut").click(function() { 63 $(".PageOpenTimer").fadeOut(); 64 }); 65 $(window).on('resize', function(){ 66 $('.DateCountdown').TimeCircles().rebuild(); 67 $('.CountDownTimer').TimeCircles().rebuild(); 68 $('.PageOpenTimer').TimeCircles().rebuild(); 69 }); 70 }); 71 --> 72 </script> 73 EOF; 74 37 75 return $flux; 38 76 }
Note: See TracChangeset
for help on using the changeset viewer.