View source
<?php
define('DEFAULT_CLOCK_TYPE', '0');
function jst_clock_jstwidget() {
$mod_path = drupal_get_path('module', 'jst_clock');
$svg_file = variable_get('jst_clock_sva_file', 'sleek1.svg');
$ret = new stdClass();
$ret->name = 'jst_clock';
$ret->label = t('Clock');
$ret->theme_function = 'jst_clock_show';
$ret->js_name = 'Drupal.jstimer.jst_clock';
$clock_type = "'" . variable_get('jstimer_jst_clock_type', DEFAULT_CLOCK_TYPE) . "'";
$ret->js_code = <<<JAVASCRIPT_CODE
/*
* Clock widget
*/
Drupal.jstimer.jst_clock = function() {
this.selector = ".jst_clock";
this.attach = function() {
jQuery(this.selector).each(
function(i) {
var t = new Drupal.jstimer.jst_clock_item(jQuery(this));
Drupal.jstimer.timer_stack[Drupal.jstimer.timer_stack.length] = t;
}
);
}
}
Drupal.jstimer.jst_clock_item = function(ele) {
// class methods first so you can use them in the constructor.
this.loadProps = function() {
for (var prop in this.props) {
var prop_selector = "span[class="+prop+"]";
if ( this.element.children(prop_selector).length > 0 ) {
this.props[prop] = this.element.children(prop_selector).html();
}
}
// If browser doesn't support the html canvas element, default to 12-hour clock.
if ( !supports_canvas() && this.props['clock_type'] == 2 ) {
this.props['clock_type'] = 0;
}
}
this.update = function() {
var timenow = new Date();
var hr = timenow.getHours();
var min = timenow.getMinutes();
var sec = timenow.getSeconds();
if ( this.props['clock_type'] == 0 ) {
var am_pm = ""
if ( hr <= 12 ) {
am_pm = "am";
} else {
am_pm = "pm";
hr = hr - 12;
}
this.element.html(hr + ":" + LZ(min) + ":" + LZ(sec) + am_pm);
} else if ( this.props['clock_type'] == 1 ) {
this.element.html(hr + ":" + LZ(min) + ":" + LZ(sec));
} else if ( this.props['clock_type'] == 2 ) {
if ( this.canvas ) {
var ctx = this.canvas[0].getContext("2d");
// save original context
ctx.save(); // 1
// clear and set defaults.
ctx.clearRect(0,0,this.props['size'],this.props['size']);
ctx.translate((this.props['size']/2),(this.props['size']/2));
ctx.scale(0.4,0.4);
ctx.rotate(-Math.PI/2);
ctx.strokeStyle = "black";
ctx.fillStyle = "white";
ctx.lineWidth = 8;
ctx.lineCap = "round";
ctx.save(); // 2
// render hour tick marks
for (var i=0;i<12;i++){
ctx.beginPath();
ctx.rotate(Math.PI/6);
ctx.moveTo(this.props['size']-20,0);
ctx.lineTo(this.props['size'],0);
ctx.stroke();
}
ctx.restore(); // 1
ctx.fillStyle = "black";
// render hour hand
ctx.save(); // 3
var hr_hand_size = 0.4 * this.props['size'];
ctx.rotate( hr*(Math.PI/6) + (Math.PI/360)*min + (Math.PI/21600)*sec )
ctx.lineWidth = 14;
ctx.beginPath();
ctx.moveTo(-20,0);
ctx.lineTo(hr_hand_size, 0);
ctx.stroke();
ctx.restore(); // 2
// render minute hand
var min_hand_size = 0.85 * this.props['size'];
ctx.save(); // 4
ctx.rotate( (Math.PI/30)*min + (Math.PI/1800)*sec )
ctx.lineWidth = 10;
ctx.beginPath();
ctx.moveTo(-28,0);
ctx.lineTo(min_hand_size, 0);
ctx.stroke();
ctx.restore(); // 3
// render second hand
ctx.save(); // 5
var sec_hand_size = 0.85 * this.props['size'];
ctx.rotate(sec * Math.PI/30);
ctx.strokeStyle = "#D40000";
ctx.fillStyle = "#D40000";
ctx.lineWidth = 6;
ctx.beginPath();
ctx.moveTo(-30,0);
ctx.lineTo(sec_hand_size, 0);
ctx.stroke();
ctx.beginPath();
ctx.arc(0,0,10,0,Math.PI*2,true);
ctx.fill();
ctx.beginPath();
ctx.arc(sec_hand_size, 0, 10, 0, Math.PI*2, true);
ctx.stroke();
ctx.fillStyle = "#555";
ctx.arc(0,0,3,0,Math.PI*2,true);
ctx.fill();
ctx.restore(); // 4
// render clock face circle
ctx.save(); // 6
ctx.beginPath();
ctx.lineWidth = 14;
ctx.strokeStyle = '#325FA2';
ctx.arc(0,0,this.props['size'],0,Math.PI*2,true);
ctx.stroke();
ctx.restore(); // 5
// Days box
//ctx.save(); // 7
//ctx.rotate(90 * Math.PI / 180);
//ctx.fillStyle = '#FFFFFF';
//ctx.fillRect(0, this.props['size']/3, 100, 60);
//ctx.strokeStyle = '#325FA2';
//ctx.strokeRect(0, this.props['size']/3, 100, 60);
//ctx.restore(); // 6
// days text
//ctx.rotate(90 * Math.PI / 180);
//ctx.fillStyle = '#0000FF';
//ctx.font = 'courier-new 30px';
//ctx.fillText ('Days', 110, (this.props['size']/3)+50);
ctx.restore(); // 7
}
}
// SVG Clock
else if ( this.props['clock_type'] == 3 ) {
if (this.clock && !this.clockSvgWin) {
this.clockSvgWin = getSvgWindow(clock);
}
if (this.clock && this.clockSvgWin) {
try{
this.clockSvgWin.animate();
}
catch(err) {
//Some browsers will have a timing error and require one more iteration.
}
}
}
return true;
}
// begin constructor
this.element = ele; // jquery ele
this.props = {clock_type:{<span class="php-variable">$clock_type</span>}, size:200};
this.loadProps();
// add canvas if analog.
if ( this.props['clock_type'] == 2 ) {
this.canvas = jQuery('<canvas class="ct_clock_canvas"><p>Your browser doesn\\'t support canvas.</p></canvas>');
this.canvas.attr("width",this.props['size']);
this.canvas.attr("height",this.props['size']);
this.element.append(this.canvas);
}
else if ( this.props['clock_type'] == 3 ) {
var clock = jQuery('<object data="/{<span class="php-variable">$mod_path</span>}/clocks/{<span class="php-variable">$svg_file</span>}" type="image/svg+xml"></object>');
clock.attr('width',this.props['size']);
clock.attr('height',this.props['size']);
this.element.html('');
this.element.append(clock);
this.clock = clock;
}
}
function supports_canvas() {
return !!document.createElement('canvas').getContext;
}
function getSvgWindow(clock) {
var svgDoc;
var svgWin;
var jsClock = clock.get(0);
if (jsClock.contentDocument) {
svgDoc = jsClock.contentDocument; //get the inner DOM of alpha.svg
}
else {
try {
svgDoc = jsClock.getSVGDocument();
}
catch(exception) {
// Ignore errors, this exception will fire if the DOM is not loaded yet.
}
}
if (svgDoc && svgDoc.defaultView) {
svgWin = svgDoc.defaultView;
}
else if (jsClock.window) {
svgWin = jsClock.window;
}
else try {
svgWin = jsClock.getWindow();
}
catch(exception) {
// Ignore errors, this exception will fire if the DOM is not loaded yet.
}
return svgWin;
}
// End of clock widget.
JAVASCRIPT_CODE;
return $ret;
}
function jst_clock_form_alter(&$form, $form_state, $form_id) {
switch ($form_id) {
case 'jstimer_admin_settings':
$form['jst_clock'] = array(
'#type' => 'fieldset',
'#title' => t('Clock widget'),
'#description' => '<span class="jst_clock"></span><br/>' . t('After saving, you need to reload the page to see the new clock.'),
'#weight' => 1,
);
$form['jst_clock']['jstimer_jst_clock_type'] = array(
'#type' => 'radios',
'#title' => t('Clock type'),
'#default_value' => variable_get('jstimer_jst_clock_type', DEFAULT_CLOCK_TYPE),
'#options' => array(
0 => t('12-hour plain text'),
1 => t('24-hour plain text'),
2 => t('Analog canvas'),
3 => t('Analog SVG'),
),
'#description' => t("The analog clocks are experimental and only works on Firefox, Opera, and Safari and IE9."),
);
$form['jst_clock']['jst_clock_sva_file'] = array(
'#type' => 'textfield',
'#title' => t('Clock svg file'),
'#default_value' => variable_get('jst_clock_sva_file', 'sleek1.svg'),
'#description' => t('The name of the svg file to use for the SVG clock. They are stored in the widgets/clocks sub directory.'),
);
$form['buttons']['#weight'] = 2;
break;
}
}
function jst_clock_show($widget_args) {
$output = '<span class="jst_clock">';
$valid_atts = array(
'clock_type',
'size',
);
foreach ($valid_atts as $att) {
if (isset($widget_args[$att])) {
$output .= '<span style="display:none" class="' . $att . '">' . $widget_args[$att] . '</span>';
}
}
$output .= '</span>';
return $output;
}
function jst_clock_enable() {
jstimer_build_js_cache();
}