You are here

function jst_clock_jstwidget in Javascript Timer 8

Same name and namespace in other branches
  1. 6 widgets/jst_clock.module \jst_clock_jstwidget()
  2. 7 widgets/jst_clock.module \jst_clock_jstwidget()

Implementation of hook_jstwidget().

@returns stdClass Keys include: ->name, ->theme_function, ->js_name, and ->js_code.

File

widgets/jst_clock.module, line 15
Embeddable clock widget (optional).

Code

function jst_clock_jstwidget() {
  $mod_path = drupal_get_path('module', 'jst_clock');
  $config = \Drupal::config('jstimer.settings');
  $svg_file = $config
    ->get('jst_clock_sva_file');
  $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 = $config
    ->get('jstimer_jst_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) {
        if (!this.getAttribute("jst_clock_attached")) {
            var t = new Drupal.jstimer.jst_clock_item(jQuery(this));
            Drupal.jstimer.timer_stack[Drupal.jstimer.timer_stack.length] = t;
            this.setAttribute("jst_clock_attached", true);
        }
      }
    );
  }
}

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;
}