Skip to content

Commit

Permalink
Added api documentation using jsdoc. Updated the README.
Browse files Browse the repository at this point in the history
  • Loading branch information
dansterrett committed Jan 14, 2013
1 parent a733d81 commit b06946d
Show file tree
Hide file tree
Showing 9 changed files with 2,530 additions and 86 deletions.
Binary file added .DS_Store
Binary file not shown.
42 changes: 41 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,44 @@
closed-caption.js
=================

A simple way to overlay 'closed caption' like captions over top a video. Look at the demo/index.html for an example of how to use it.
A simple way to overlay closed captions over top a video. View demo/index.html for an example of how to use it.

The HTML should be structured like this:

<div class="cc-area">
<span id="cc-text" class="cc-text"></span>
</div>

The parent container of `cc-area` must have `position` set to `relative`, `absolute`, or `fixed` for the captions to display properly.

To initialize a new ClosedCaption object, pass the `cc-text` element:

var closedCaption = new ClosedCaption($('#cc-text')[0]);

Set the caption text:

closedCaption.setCaptions([
{ html: 'This is caption 1.', startTime: 0, endTime: 1000 },
{ html: 'This is caption 2.', startTime: 2000 },
{ html: 'This is caption 3.', startTime: 4000, endTime: 5000 },
{ html: 'This is caption 4.', startTime: 6000, endTime: 7000 },
{ html: 'This is caption 5.', startTime: 8000, endTime: 9000 }
]);

A "caption" object consists of three properties: `html`, `startTime`, and `endTime` (optional). If no `endTime` is set, then the caption will remain visible until the next caption displays.

To play:

closedCaption.play();

To pause:

closedCaption.pause();

To stop:

closedCaption.stop();

To toggle play:

closedCaption.togglePlay();
7 changes: 6 additions & 1 deletion closed-caption.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,16 @@
left: 0;
text-align: center;
padding: 10px;
visibility: hidden;
}

.cc-text {
background-color: #555;
padding: 4px;
color: #fff;
visibility: hidden;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}
198 changes: 114 additions & 84 deletions closed-caption.js
Original file line number Diff line number Diff line change
@@ -1,101 +1,131 @@
;'use strict';

var ClosedCaption = function(element) {
/**
Creates a new ClosedCaption.
@param {HTMLSpanElement} element The SPAN element to initialize as a new ClosedCaption.
@constructor
*/
var ClosedCaption = function ClosedCaption(element) {
this.element = element;
element.closedCaption = this;
var $element = this.$element = $(element);
this.clearCurrentState();
};

ClosedCaption.prototype.clearCurrentState = function() {
this.currentState = {
timeouts: [],
elapsedTime: 0,
totalElapsedTime: 0
};
};

/**
Sets the captions.
@param {Array} captions Each caption object should have a 'startTime' and 'html' properties,
and an optional 'endTime' property.
*/
ClosedCaption.prototype.setCaptions = function(captions) {
this.captions = captions;
};

ClosedCaption.prototype.togglePlay = function() {
if (this.isPlaying) {
ClosedCaption.prototype = {
/**
Clears the ClosedCaption's currentState. The currentState is used to
keep track of when each closed caption text is supposed to be shown.
*/
clearCurrentState: function() {
this.currentState = {
timeouts: [],
elapsedTime: 0,
totalElapsedTime: 0
};
},

/**
Sets the captions.
@param {Array} captions Each caption object should have a 'startTime' and 'html' properties,
and an optional 'endTime' property.
*/
setCaptions: function(captions) {
this.captions = captions;
},

/**
Toggles the play of the closed captions. It is used to either pause or play the captions.
*/
togglePlay: function() {
if (this.isPlaying) {
this.pause();
} else {
this.play();
}
},

/**
Plays the captions.
*/
play: function() {
if (!this.captions.length) return;

this.isPlaying = true;
this.currentState.startTime = Date.now();

// Set a timeout for each caption
var captions = this.captions;
for (var i = 0, length = captions.length; i < length; i++) {
this.setTimeoutForCaption(captions[i]);
}
},

/**
Sets a timeout to show the caption.
*/
setTimeoutForCaption: function(caption) {
var startTime = caption.startTime - (this.currentState.elapsedTime || 0);
var endTime = (caption.endTime ? caption.endTime - (this.currentState.elapsedTime || 0) : null);

var self = this;

// Set a timeout to show the caption
if (startTime >= 0) {
this.currentState.timeouts.push({
time: caption.startTime,
timeout: window.setTimeout(function() {
self.$element.html(caption.html);
self.$element.css('visibility','visible');
}, startTime)
});
}

// Set a timeout to hide the caption
if (endTime && endTime >= 0) {
this.currentState.timeouts.push({
time: caption.endTime,
timeout: window.setTimeout(function() {
self.$element.css('visibility','hidden');
}, endTime)
});
}
},

/**
Pauses the captions.
*/
pause: function() {
if (!this.isPlaying) return;
this.isPlaying = false;

var currentState = this.currentState;
currentState.elapsedTime = Date.now() - currentState.startTime + (currentState.elapsedTime || 0);

var timeouts = currentState.timeouts;
for (var i = 0, length = timeouts.length; i < length; i++) {
window.clearTimeout(timeouts[i].timeout);
}

currentState.timeouts = [];
},

/**
Stops playing the captions.
*/
stop: function() {
this.pause();
} else {
this.play();
this.clearCurrentState();
this.$element.css('visibility','hidden');
}
};

ClosedCaption.prototype.play = function() {
if (!this.captions.length) return;

this.isPlaying = true;
this.currentState.startTime = Date.now();

// Set a timeout for each caption
var captions = this.captions;
for (var i = 0, length = captions.length; i < length; i++) {
this.setTimeoutForCaption(captions[i]);
}
};

ClosedCaption.prototype.setTimeoutForCaption = function(caption) {
var startTime = caption.startTime - (this.currentState.elapsedTime || 0);
var endTime = (caption.endTime ? caption.endTime - (this.currentState.elapsedTime || 0) : null);

var self = this;

// Set a timeout to show the caption
if (startTime >= 0) {
this.currentState.timeouts.push({
time: caption.startTime,
timeout: window.setTimeout(function() {
self.$element.html(caption.html);
self.$element.css('visibility','visible');
}, startTime)
});
}

// Set a timeout to hide the caption
if (endTime && endTime >= 0) {
this.currentState.timeouts.push({
time: caption.endTime,
timeout: window.setTimeout(function() {
self.$element.css('visibility','hidden');
}, endTime)
});
}
};

ClosedCaption.prototype.pause = function() {
if (!this.isPlaying) return;
this.isPlaying = false;

var currentState = this.currentState;
currentState.elapsedTime = Date.now() - currentState.startTime + (currentState.elapsedTime || 0);

var timeouts = currentState.timeouts;
for (var i = 0, length = timeouts.length; i < length; i++) {
window.clearTimeout(timeouts[i].timeout);
}

currentState.timeouts = [];
};

ClosedCaption.prototype.stop = function() {
this.pause();
this.clearCurrentState();
this.$element.css('visibility','hidden');
};
}

// For IE8 and earlier.
if (!Date.now) {
/**
Defines the Date.now method if the browser does not already support it (IE8 and below).
*/
Date.now = function() {
return new Date().valueOf();
}
Expand Down
Loading

0 comments on commit b06946d

Please sign in to comment.