Fri Oct 19 2018
Copied to clipboard! Copy reply
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
<script>
      // BEGIN RTO CODE
console.log('---')
      // Places RTO on bottom of viewport
      var rtoHeight = document.getElementById('rto-q4').offsetHeight;
      
     
      
      var diff = window.innerHeight - rtoHeight - 94
      
      // Initially position RTO on bottom
      $('#rto-q4').css({top: diff + 'px'})

      var isCollapsed = false
      $('.toggleCollapse').click(function() {
        if (!isCollapsed)
        {
          // Collapse it.
          console.log('Not collapsed. collapse')
          var bodyHeight = document.querySelector('#rto-q4 .rto-body').offsetHeight;
          var diff2 = diff + bodyHeight
          $('#rto-q4').css({top: diff2 + 'px'})
          $(this).addClass('collapsed')
          isCollapsed = true
        }
        else
        {
          // Collapsed. Expand it
          $('#rto-q4').css({top: diff + 'px'})
          $(this).removeClass('collapsed')
          isCollapsed = false
        }      
      })

      var total_time_on_clock_in_ms = 10 * (60*1000); // 10 minutes



	// ****************************
	// Set clock styles here
	// ****************************

	function add_clock_styles(){

		var style_tag = document.createElement('style');
		style_tag.innerHTML = ''
			+ '.clock_arc_svg {'
				+ 'width: 80px;'
				+ 'height: 80px;'
			+ '}'
			+ '.clock_arc {'
				+ 'stroke-width: 0.6;'
				+ 'stroke-linecap: round;'
				+ 'fill: transparent;'
			+ '}'
			+ '.clock_arc_track {'
				+ 'stroke: #1E1E1E;'
			+ '}'
			+ '.clock_arc_fill {'
				+ 'stroke: url(#clock_arc_gradient) #458FCF;'
			+ '}'

			+ '.clock_block {'
				+ 'position: relative;'
				+ 'display: inline-block;'
				+ 'margin: 0px 3px;'
				+ 'line-height: 1;'
			+ '}'

			+ '.clock_time_unit {'
				+ 'text-align: center;'
				+ 'position: absolute;'
				+ 'left: 0px;'
				+ 'top: 20%;'
				+ 'width: 100%;'
			+ '}'
			+ '.clock_time_number {'
				+ 'font-size: 22px;'
			+ '}'
			+ '.clock_time_units {'
				+ 'font-size: 14px;'
			+ '}';
		document.head.appendChild(style_tag);
	}
	add_clock_styles();








	// ********************************
	// From here on, no need to edit
	// ********************************


	function _$(selector){
		var elems = Array.prototype.slice.call(document.querySelectorAll(selector));
		return {
			elems: elems,
			attr: function(attr, value){
				elems.forEach(function(elem){
					var original_attr = elem.getAttribute(attr);
					var final_value = typeof value === 'function' ? value(original_attr) : value;
					elem.setAttribute(attr, final_value);
				});
				return this;
			},
			show: function(display_property){
				elems.forEach(function(elem){
					elem.style.display = display_property || 'block';
				});
				return this;
			},
			hide: function(){
				elems.forEach(function(elem){
					elem.style.display = 'none';
				});
				return this;
			},
			html: function(inner_html){
				elems.forEach(function(elem){
					elem.innerHTML = inner_html;
				});
				return this;
			},
			on: function(event, fn){
				elems.forEach(function(elem){
					elem.addEventListener(event, fn);
				});
				return this;
			}
		};
	}




	function Timer(container_selector, time_remaining_ms){

		this.svg_gradient = ''
			+ '<svg style="width:0;height:0;position:absolute;" aria-hidden="true" focusable="false">'
				+ '<linearGradient id="clock_arc_gradient" x2="1" y2="1">'
					+ '<stop offset="0%" stop-color="#80E4F9" />'
					+ '<stop offset="50%" stop-color="#458FCF" />'
					+ '<stop offset="100%" stop-color="#0E3FA5" />'
				+ '</linearGradient>'
			+ '</svg>';

		this.generate_arc_svg = function(time_units){
			return ''
				+ '<svg class="clock_arc_svg" data-time_units="'+time_units+'" viewBox="0 0 10 10" xmlns="https://www.w3.org/2000/svg">'
					+ '<path class="clock_arc clock_arc_track"></path>'
					+ '<path class="clock_arc clock_arc_fill"></path>'
				+ '</svg>';
		}

		this.generate_time_holder = function(time_units){
			return ''
				+'<div class="clock_block" data-time_units="'+time_units+'">'
					+ this.generate_arc_svg(time_units)
					+ '<div class="clock_time_unit">'
						+ '<div class="clock_time_number">'+
							+ this.getTime(time_units)
						+'</div>'
						+ '<div class="clock_time_units">'
							+ time_units.charAt(0).toUpperCase() + time_units.slice(1)
						+ '</div>'
					+ '</div>'
				+'</div>';
		}

		this.r = 4.55;
		this.arc_degrees_half = 130;
		this.arc_degrees_full = this.arc_degrees_half * 2;

		this.tick_length_ms = 500;
		this.latest_tick_ms;


		this.time_remaining_ms = time_remaining_ms;

		this.getTime = function(time_units){
			var time_in = {
				seconds: (this.time_remaining_ms/1000) % 60,
				minutes: (this.time_remaining_ms/1000/60) % 60,
				hours: this.time_remaining_ms/(1000*60*60)
			};
			return time_in[time_units];
		}

		this.hasHours = Math.floor(this.getTime('hours')) > 0;


		this.init = function(){
			var self = this;
			_$(container_selector).html(
				(self.hasHours ? self.generate_time_holder('hours') : '')
				+ self.generate_time_holder('minutes')
				+ self.generate_time_holder('seconds')
			);
			document.querySelector(container_selector).innerHTML += this.svg_gradient;

			_$('.clock_arc_track').attr(
				'd', describeArc(5, 5, self.r, -self.arc_degrees_half, self.arc_degrees_half)
			);
		};

		this.set_arc_length = function(time_units, percent_full){
			var self = this;
			var start_angle = this.arc_degrees_half - (this.arc_degrees_full * (percent_full/100));

			_$(container_selector + ' .clock_arc_svg[data-time_units='+time_units+'] .clock_arc_fill').attr(
				'd', describeArc(5, 5, self.r, start_angle, self.arc_degrees_half)
			);
		};


		this.time_now_ms = window.performance.now();
		this.total_seconds = this.getTime('seconds') || 60;
		this.total_minutes = this.hasHours ? 60 : this.getTime('minutes');
		this.total_hours = this.getTime('hours');

		this.t = 60;

		this.raf;

		this.update_clock = (function(timestamp){
			this.raf = window.requestAnimationFrame(this.update_clock);
			this.time_remaining_ms -= (timestamp - this.time_now_ms);
			this.time_now_ms = timestamp;

			// make sure time doesn't go negative (it creates weird rendering)
			if(this.time_remaining_ms <= 0){
				this.time_remaining_ms = 0;
			}

			if( (this.time_now_ms - this.latest_tick_ms) >= this.tick_length_ms ){
				this.latest_tick_ms = this.time_now_ms;

				if(this.hasHours){
					this.update_timer_number('hours', Math.floor(this.getTime('hours')) );
				}
				this.update_timer_number('minutes', Math.floor(this.getTime('minutes')) );
				this.update_timer_number('seconds', Math.floor(this.getTime('seconds')) );
			}

			if(this.hasHours){
				this.set_arc_length('hours', (this.getTime('hours') / this.total_hours) * 100);
			}
			this.set_arc_length('minutes', (this.getTime('minutes') / this.total_minutes) * 100);
			this.set_arc_length('seconds', (this.getTime('seconds') / this.total_seconds) * 100);

			if(this.time_remaining_ms <= 0){
				this.stop();
			}
		}).bind(this);

		this.update_timer_number = function(time_units, number){
			_$('.clock_block[data-time_units='+time_units+'] .clock_time_number').html(number);
		}

		this.start = function(){
			this.time_now_ms = window.performance.now();
			this.latest_tick_ms = this.time_now_ms;
			this.update_clock(this.time_now_ms);
		};

		this.stop = function(){
			window.cancelAnimationFrame(this.raf);
		};
	}

	var timer = new Timer('.clock_container', total_time_on_clock_in_ms);
	timer.init();
	timer.start();



	// credit for polarToCartesian and describeArc functions:
	// https://stackoverflow.com/questions/5736398/how-to-calculate-the-svg-path-for-an-arc-of-a-circle
	function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
		var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0;

		return {
			x: centerX + (radius * Math.cos(angleInRadians)),
			y: centerY + (radius * Math.sin(angleInRadians))
		};
	}
	function describeArc(x, y, radius, startAngle, endAngle){
		var start = polarToCartesian(x, y, radius, endAngle);
		var end = polarToCartesian(x, y, radius, startAngle);

		var arcSweep = endAngle - startAngle <= 180 ? '0' : '1';

		var d = [
				'M', start.x, start.y, 
				'A', radius, radius, 0, arcSweep, 0, end.x, end.y
		].join(' ');

		return d;
	}


  

 // END RTO CODE
</script>