I recently wrote a Toastmasters Timer in TypeScript for two reasons:
I was looking for something that would should the time in a large font on the page and change the color of a large portion of the page at each stage. I needed this to be able to constantly monitor the time and color from a distance while I am pacing around the room practicing a speech. I didn't want to have to lean forward to see the time. This is the final result: Toastmasters Timer
Here is the TypeScript source code for that timer (the compiled JS, HTML and CSS can be pulled from the page):
- The other timers that I found out on the web didn't quite do what I wanted them to do and
- I needed a small project to learn TypeScript
I was looking for something that would should the time in a large font on the page and change the color of a large portion of the page at each stage. I needed this to be able to constantly monitor the time and color from a distance while I am pacing around the room practicing a speech. I didn't want to have to lean forward to see the time. This is the final result: Toastmasters Timer
Here is the TypeScript source code for that timer (the compiled JS, HTML and CSS can be pulled from the page):
/// <reference path="jquery.d.ts" />
class SpeechType {
constructor (public name: string, public greenTime: string, public yellowTime: string, public redTime: string, public id: string) {
}
}
class TSTimer {
timerToken: number;
speeches: SpeechType[];
started: bool;
startTime: Date;
stopTime: Date;
green: number;
yellow: number;
red: number;
constructor (speeches: SpeechType[]) {
this.started = false;
this.speeches = speeches;
$.each(this.speeches, (indexInArray: number, valueOfElement: SpeechType) => {
var newButton = $('<span>')
.attr('id', valueOfElement.id)
.addClass('speech-type')
.html(valueOfElement.name);
newButton.click( (event) => {
this.activateSpeech($(event.target).attr('id'));
});
newButton.appendTo('#buttons');
});
$(window).resize( () => {
this.resizeTime();
});
// call on initialization in case the browser starts off narrow
this.resizeTime();
$('#btnReset').click( () => {
this.resetButton();
});
$('#btnStart').click(() => {
this.startButton();
});
}
resetButton() {
this.stop();
$('#trafficlight').text('0:00');
$('#body').css('background-color', '#EFEEEF');
this.startTime = null;
}
startButton() {
if (this.started) {
this.stop();
} else {
this.start();
}
};
resizeTime() {
var width = $(window).width();
var x: number = Math.floor((width < 900) ? (width / 900) * 28 : 28);
$('#trafficlight').css('font-size', x + 'em');
}
setElementText(elapsedSeconds: number) {
$('#trafficlight').text(this.formatTime(elapsedSeconds));
if (elapsedSeconds >= this.red) {
$('#body').css('background-color', '#FF4040');
} else if (elapsedSeconds >= this.yellow) {
$('#body').css('background-color', '#FCDC3B');
} else if (elapsedSeconds >= this.green) {
$('#body').css('background-color', '#A7DA7E');
}
}
timerEvent() {
if (!this.startTime) {
this.startTime = new Date();
}
var timeNow = new Date();
var elapsedSeconds: number = this.timeDiffInSeconds(this.startTime, timeNow);
this.setElementText(elapsedSeconds);
}
// Returns the difference in seconds between
timeDiffInSeconds(earlyTime: Date, lateTime: Date): number {
var diff: number = lateTime.getTime() - earlyTime.getTime();
return Math.floor(diff / 1000);
}
formatTime(elapsedSeconds: number) {
var minutes: number = Math.floor(elapsedSeconds / 60);
var seconds: number = elapsedSeconds % 60;
return minutes + ":" + ((seconds < 10) ? "0" + seconds.toString() : seconds.toString());
}
start() {
$('#btnStart').val('Stop');
this.started = true;
if (this.startTime) {
// i.e. no reset since the last time it was started so adjust the start time
// to reflect the time that's elapsed since it was stopped.
var newStartTime = new Date().getTime() - (this.stopTime.getTime() - this.startTime.getTime());
this.startTime.setTime(newStartTime);
}
this.green = this.getSecondsFromTextBox('#green-light');
this.yellow = this.getSecondsFromTextBox('#yellow-light');
this.red = this.getSecondsFromTextBox('#red-light');
this.timerToken = setInterval(() => this.timerEvent(), 1000);
}
stop() {
$('#btnStart').val('Start');
this.started = false;
this.stopTime = new Date();
clearTimeout(this.timerToken);
}
getSecondsFromTextBox(id: string): number {
var greenLight: string = $(id).val();
return parseInt(greenLight.split(':')[0]) * 60 + parseInt(greenLight.split(':')[1]);
}
setDefault() {
this.activateSpeech('st-standard');
}
activateSpeech(speechId: string) {
$.each(this.speeches, function (indexInArray: number, valueOfElement: SpeechType) {
if (valueOfElement.id === speechId) {
$('#green-light').val(valueOfElement.greenTime);
$('#yellow-light').val(valueOfElement.yellowTime);
$('#red-light').val(valueOfElement.redTime);
}
});
$('.active-speech').removeClass('active-speech');
$('#' + speechId).addClass('active-speech');
}
}
$(document).ready(function () {
var speeches = [];
speeches.push(new SpeechType("Table Topics", "1:00", "1:30", "2:00", "st-table-topics"));
speeches.push(new SpeechType("Evaluation", "2:00", "2:30", "3:00", "st-evaluation"));
speeches.push(new SpeechType("Icebreaker", "4:00", "5:00", "6:00", "st-icebreaker"));
speeches.push(new SpeechType("Standard", "5:00", "6:00", "7:00", "st-standard"));
speeches.push(new SpeechType("Advanced", "8:00", "9:00", "10:00", "st-advanced"));
speeches.push(new SpeechType("Test", "0:02", "0:04", "0:06", "st-test"));
var timer = new TSTimer(speeches);
timer.setDefault();
});
No comments:
Post a Comment