You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
446 lines
15 KiB
JavaScript
446 lines
15 KiB
JavaScript
// thooClock, a jQuery Clock with alarm function
|
|
// by Thomas Haaf aka thooyork, http://www.smart-sign.com
|
|
// Twitter: @thooyork
|
|
// Version 0.9.20
|
|
// Copyright (c) 2013 thooyork
|
|
|
|
// MIT License, http://opensource.org/licenses/MIT
|
|
|
|
|
|
(function( $ ) {
|
|
|
|
$.fn.thooClock = function(options) {
|
|
|
|
this.each(function() {
|
|
|
|
var cnv,
|
|
ctx,
|
|
el,
|
|
defaults,
|
|
settings,
|
|
radius,
|
|
dialColor,
|
|
dialBackgroundColor,
|
|
secondHandColor,
|
|
minuteHandColor,
|
|
hourHandColor,
|
|
alarmHandColor,
|
|
alarmHandTipColor,
|
|
hourCorrection,
|
|
x,
|
|
y;
|
|
|
|
defaults = {
|
|
size:250,
|
|
dialColor:'#000000',
|
|
dialBackgroundColor:'transparent',
|
|
secondHandColor:'#F3A829',
|
|
minuteHandColor:'#222222',
|
|
hourHandColor:'#222222',
|
|
alarmHandColor:'#FFFFFF',
|
|
alarmHandTipColor:'#026729',
|
|
hourCorrection:'+0',
|
|
alarmCount:1,
|
|
showNumerals:true
|
|
};
|
|
|
|
settings = $.extend({}, defaults, options);
|
|
|
|
el = this;
|
|
|
|
el.size = settings.size;
|
|
el.dialColor = settings.dialColor;
|
|
el.dialBackgroundColor = settings.dialBackgroundColor;
|
|
el.secondHandColor = settings.secondHandColor;
|
|
el.minuteHandColor = settings.minuteHandColor;
|
|
el.hourHandColor = settings.hourHandColor;
|
|
el.alarmHandColor = settings.alarmHandColor;
|
|
el.alarmHandTipColor = settings.alarmHandTipColor;
|
|
el.hourCorrection = settings.hourCorrection;
|
|
el.showNumerals = settings.showNumerals;
|
|
|
|
el.brandText = settings.brandText;
|
|
el.brandText2 = settings.brandText2;
|
|
|
|
el.alarmCount = settings.alarmCount;
|
|
el.alarmTime = settings.alarmTime;
|
|
el.onAlarm = settings.onAlarm;
|
|
el.offAlarm = settings.offAlarm;
|
|
|
|
el.onEverySecond = settings.onEverySecond;
|
|
|
|
x=0; //loopCounter for Alarm
|
|
|
|
cnv = document.createElement('canvas');
|
|
ctx = cnv.getContext('2d');
|
|
|
|
cnv.width = this.size;
|
|
cnv.height = this.size;
|
|
//append canvas to element
|
|
$(cnv).appendTo(el);
|
|
|
|
radius = parseInt(el.size/2, 10);
|
|
//translate 0,0 to center of circle:
|
|
ctx.translate(radius, radius);
|
|
|
|
//set alarmtime from outside:
|
|
|
|
$.fn.thooClock.setAlarm = function(newtime){
|
|
var thedate;
|
|
if(newtime instanceof Date){
|
|
//keep date object
|
|
thedate=newtime;
|
|
}
|
|
else{
|
|
//convert from string formatted like hh[:mm[:ss]]]
|
|
var arr = newtime.split(':');
|
|
thedate=new Date();
|
|
for(var i= 0; i <3 ; i++){
|
|
//force to int
|
|
arr[i]=Math.floor(arr[i]);
|
|
//check if NaN or invalid min/sec
|
|
if( arr[i] !==arr[i] || arr[i] > 59) arr[i]=0 ;
|
|
//no more than 24h
|
|
if( i==0 && arr[i] > 23) arr[i]=0 ;
|
|
}
|
|
thedate.setHours(arr[0],arr[1],arr[2]);
|
|
}
|
|
//alert(el.id);
|
|
el.alarmTime = thedate;
|
|
};
|
|
|
|
$.fn.thooClock.clearAlarm = function(){
|
|
el.alarmTime = undefined;
|
|
startClock(0,0);
|
|
$(el).trigger('offAlarm');
|
|
};
|
|
|
|
|
|
function toRadians(deg){
|
|
return ( Math.PI / 180 ) * deg;
|
|
}
|
|
|
|
function drawDial(color, bgcolor){
|
|
var dialRadius,
|
|
dialBackRadius,
|
|
i,
|
|
ang,
|
|
sang,
|
|
cang,
|
|
sx,
|
|
sy,
|
|
ex,
|
|
ey,
|
|
nx,
|
|
ny,
|
|
text,
|
|
textSize,
|
|
textWidth,
|
|
brandtextWidth,
|
|
brandtextWidth2;
|
|
|
|
dialRadius = parseInt(radius-(el.size/50), 10);
|
|
dialBackRadius = radius-(el.size/400);
|
|
|
|
ctx.beginPath();
|
|
ctx.arc(0,0,dialBackRadius,0,360,false);
|
|
ctx.fillStyle = bgcolor;
|
|
ctx.fill();
|
|
|
|
|
|
for (i=1; i<=60; i+=1) {
|
|
ang=Math.PI/30*i;
|
|
sang=Math.sin(ang);
|
|
cang=Math.cos(ang);
|
|
//hour marker/numeral
|
|
if (i % 5 === 0) {
|
|
ctx.lineWidth = parseInt(el.size/50,10);
|
|
sx = sang * (dialRadius - dialRadius/9);
|
|
sy = cang * -(dialRadius - dialRadius/9);
|
|
ex = sang * dialRadius;
|
|
ey = cang * - dialRadius;
|
|
nx = sang * (dialRadius - dialRadius/4.2);
|
|
ny = cang * -(dialRadius - dialRadius/4.2);
|
|
text = i/5;
|
|
ctx.textBaseline = 'middle';
|
|
textSize = parseInt(el.size/13,10);
|
|
ctx.font = '100 ' + textSize + 'px helvetica';
|
|
textWidth = ctx.measureText (text).width;
|
|
ctx.beginPath();
|
|
ctx.fillStyle = color;
|
|
|
|
if(el.showNumerals){
|
|
ctx.fillText(text,nx-(textWidth/2),ny);
|
|
}
|
|
//minute marker
|
|
} else {
|
|
ctx.lineWidth = parseInt(el.size/100,10);
|
|
sx = sang * (dialRadius - dialRadius/20);
|
|
sy = cang * -(dialRadius - dialRadius/20);
|
|
ex = sang * dialRadius;
|
|
ey = cang * - dialRadius;
|
|
}
|
|
|
|
ctx.beginPath();
|
|
ctx.strokeStyle = color;
|
|
ctx.lineCap = "round";
|
|
ctx.moveTo(sx,sy);
|
|
ctx.lineTo(ex,ey);
|
|
ctx.stroke();
|
|
}
|
|
|
|
if(el.brandText !== undefined){
|
|
ctx.font = '100 ' + parseInt(el.size/28,10) + 'px helvetica';
|
|
brandtextWidth = ctx.measureText (el.brandText).width;
|
|
ctx.fillText(el.brandText,-(brandtextWidth/2),(el.size/6));
|
|
}
|
|
|
|
if(el.brandText2 !== undefined){
|
|
ctx.textBaseline = 'middle';
|
|
ctx.font = '100 ' + parseInt(el.size/44,10) + 'px helvetica';
|
|
brandtextWidth2 = ctx.measureText (el.brandText2).width;
|
|
ctx.fillText(el.brandText2,-(brandtextWidth2/2),(el.size/5));
|
|
}
|
|
|
|
}
|
|
|
|
|
|
function twelvebased(hour){
|
|
if(hour >= 12){
|
|
hour = hour - 12;
|
|
}
|
|
return hour;
|
|
}
|
|
|
|
|
|
|
|
function drawHand(length){
|
|
ctx.beginPath();
|
|
ctx.moveTo(0,0);
|
|
ctx.lineTo(0, length * -1);
|
|
ctx.stroke();
|
|
}
|
|
|
|
|
|
function drawSecondHand(seconds, color){
|
|
var shlength = (radius)-(el.size/40);
|
|
|
|
ctx.save();
|
|
ctx.lineWidth = parseInt(el.size/150,10);
|
|
ctx.lineCap = "round";
|
|
ctx.strokeStyle = color;
|
|
ctx.rotate( toRadians(seconds * 6));
|
|
|
|
ctx.shadowColor = 'rgba(0,0,0,.5)';
|
|
ctx.shadowBlur = parseInt(el.size/80,10);
|
|
ctx.shadowOffsetX = parseInt(el.size/200,10);
|
|
ctx.shadowOffsetY = parseInt(el.size/200,10);
|
|
|
|
drawHand(shlength);
|
|
|
|
//tail of secondhand
|
|
ctx.beginPath();
|
|
ctx.moveTo(0,0);
|
|
ctx.lineTo(0, shlength/15);
|
|
ctx.lineWidth = parseInt(el.size/30,10);
|
|
ctx.stroke();
|
|
|
|
//round center
|
|
ctx.beginPath();
|
|
ctx.arc(0, 0, parseInt(el.size/30,10), 0, 360, false);
|
|
ctx.fillStyle = color;
|
|
|
|
ctx.fill();
|
|
ctx.restore();
|
|
}
|
|
|
|
function drawMinuteHand(minutes, color){
|
|
var mhlength = el.size/2.2;
|
|
ctx.save();
|
|
ctx.lineWidth = parseInt(el.size/50,10);
|
|
ctx.lineCap = "round";
|
|
ctx.strokeStyle = color;
|
|
ctx.rotate( toRadians(minutes * 6));
|
|
|
|
ctx.shadowColor = 'rgba(0,0,0,.5)';
|
|
ctx.shadowBlur = parseInt(el.size/50,10);
|
|
ctx.shadowOffsetX = parseInt(el.size/250,10);
|
|
ctx.shadowOffsetY = parseInt(el.size/250,10);
|
|
|
|
drawHand(mhlength);
|
|
ctx.restore();
|
|
}
|
|
|
|
function drawHourHand(hours, color){
|
|
var hhlength = el.size/3;
|
|
ctx.save();
|
|
ctx.lineWidth = parseInt(el.size/25, 10);
|
|
ctx.lineCap = "round";
|
|
ctx.strokeStyle = color;
|
|
ctx.rotate( toRadians(hours * 30));
|
|
|
|
ctx.shadowColor = 'rgba(0,0,0,.5)';
|
|
ctx.shadowBlur = parseInt(el.size/50, 10);
|
|
ctx.shadowOffsetX = parseInt(el.size/300, 10);
|
|
ctx.shadowOffsetY = parseInt(el.size/300, 10);
|
|
|
|
drawHand(hhlength);
|
|
ctx.restore();
|
|
}
|
|
|
|
function timeToDecimal(time){
|
|
var h,
|
|
m;
|
|
if(time !== undefined){
|
|
h = twelvebased(time.getHours());
|
|
m = time.getMinutes();
|
|
}
|
|
return parseInt(h,10) + (m/60);
|
|
}
|
|
|
|
function drawAlarmHand(alarm, color, tipcolor){
|
|
|
|
var ahlength = el.size/2.4;
|
|
|
|
ctx.save();
|
|
ctx.lineWidth = parseInt(el.size/30, 10);
|
|
ctx.lineCap = "butt";
|
|
ctx.strokeStyle = color;
|
|
|
|
//decimal equivalent to hh:mm
|
|
alarm = timeToDecimal(alarm);
|
|
ctx.rotate( toRadians(alarm * 30));
|
|
|
|
ctx.shadowColor = 'rgba(0,0,0,.5)';
|
|
ctx.shadowBlur = parseInt(el.size/55, 10);
|
|
ctx.shadowOffsetX = parseInt(el.size/300, 10);
|
|
ctx.shadowOffsetY = parseInt(el.size/300, 10);
|
|
|
|
//drawHand(ahlength);
|
|
|
|
ctx.beginPath();
|
|
ctx.moveTo(0,0);
|
|
ctx.lineTo(0, (ahlength-(el.size/10)) * -1);
|
|
ctx.stroke();
|
|
|
|
ctx.beginPath();
|
|
ctx.strokeStyle = tipcolor;
|
|
ctx.moveTo(0, (ahlength-(el.size/10)) * -1);
|
|
ctx.lineTo(0, (ahlength) * -1);
|
|
ctx.stroke();
|
|
|
|
//round center
|
|
ctx.beginPath();
|
|
ctx.arc(0, 0, parseInt(el.size/24, 10), 0, 360, false);
|
|
ctx.fillStyle = color;
|
|
ctx.fill();
|
|
ctx.restore();
|
|
}
|
|
|
|
function numberCorrection(num){
|
|
if(num !== '+0' && num !== ''){
|
|
if(num.charAt(0) === '+'){
|
|
//addNum
|
|
return + num.charAt(1);
|
|
}
|
|
else{
|
|
//subNum
|
|
return - num.charAt(1);
|
|
}
|
|
}
|
|
else{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
//listener
|
|
if(el.onAlarm !== undefined){
|
|
$(el).on('onAlarm', function(e){
|
|
el.onAlarm();
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
});
|
|
}
|
|
|
|
if(el.onEverySecond !== undefined){
|
|
$(el).on('onEverySecond', function(e){
|
|
el.onEverySecond();
|
|
e.preventDefault();
|
|
});
|
|
}
|
|
|
|
if(el.offAlarm !== undefined){
|
|
$(el).on('offAlarm', function(e){
|
|
el.offAlarm();
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
});
|
|
}
|
|
|
|
y=0;
|
|
|
|
function startClock(x,y){
|
|
var theDate,
|
|
s,
|
|
m,
|
|
hours,
|
|
mins,
|
|
h,
|
|
exth,
|
|
extm,
|
|
allExtM,
|
|
allAlarmM,
|
|
atime;
|
|
|
|
theDate = new Date();
|
|
s = theDate.getSeconds();
|
|
mins = theDate.getMinutes();
|
|
m = mins + (s/60);
|
|
hours = theDate.getHours();
|
|
h = twelvebased(hours + numberCorrection(el.hourCorrection)) + (m/60);
|
|
|
|
ctx.clearRect(-radius,-radius,el.size,el.size);
|
|
|
|
drawDial(el.dialColor, el.dialBackgroundColor);
|
|
|
|
if(el.alarmTime !== undefined){
|
|
drawAlarmHand(el.alarmTime, el.alarmHandColor, el.alarmHandTipColor);
|
|
}
|
|
drawHourHand(h, el.hourHandColor);
|
|
drawMinuteHand(m, el.minuteHandColor);
|
|
drawSecondHand(s, el.secondHandColor);
|
|
|
|
//trigger every second custom event
|
|
y+=1;
|
|
if(y===1){
|
|
$(el).trigger('onEverySecond');
|
|
y=0;
|
|
}
|
|
|
|
if(el.alarmTime !== undefined){
|
|
allExtM = (el.alarmTime.getHours()*60*60) + (el.alarmTime.getMinutes() *60) + el.alarmTime.getSeconds();
|
|
}
|
|
|
|
allAlarmM = (hours*60*60) + (mins*60) + s;
|
|
|
|
//set alarm loop counter
|
|
//if(h >= timeToDecimal(twelvebased(el.alarmTime)){
|
|
|
|
//alarmMinutes greater than passed Minutes;
|
|
if(allAlarmM >= allExtM){
|
|
x+=1;
|
|
}
|
|
//trigger alarm for as many times as i < alarmCount
|
|
if(x <= el.alarmCount && x !== 0){
|
|
$(el).trigger('onAlarm');
|
|
}
|
|
var synced_delay= 1000 - ((new Date().getTime()) % 1000);
|
|
setTimeout(function(){startClock(x,y);},synced_delay);
|
|
}
|
|
|
|
startClock(x,y);
|
|
|
|
});//return each this;
|
|
};
|
|
|
|
}(jQuery)); |