Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
walsh9 committed Oct 7, 2014
1 parent ae34b0b commit 19edeb5
Show file tree
Hide file tree
Showing 6 changed files with 297 additions and 256 deletions.
2 changes: 1 addition & 1 deletion Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ module.exports = function(grunt) {
'src/options.js',
'src/utils.js',
'src/events.js',
'src/scrollable.js',
'src/scroller.js',
'src/tracklist.js',
'src/widget.js',
'src/main.js',
Expand Down
259 changes: 140 additions & 119 deletions dist/videojs-transcript.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*! videojs-transcript - v0.0.0 - 2014-10-05
/*! videojs-transcript - v0.0.0 - 2014-10-06
* Copyright (c) 2014 Matthew Walsh; Licensed MIT */
(function (window, videojs) {
'use strict';
Expand Down Expand Up @@ -158,131 +158,131 @@ var eventEmitter = {
}
};

/*global my, utils*/
var scrollable = function (plugin) {
'use strict';
var scrollablePrototype = {
easeOut: function (time, start, change, duration) {
return start + change * Math.sin(Math.min(1, time / duration) * (Math.PI / 2));
},
var scrollerProto = function(plugin) {
var initHandlers = function (el) {

// Animate the scrolling.
scrollTo: function (element, newPos, duration) {
var startTime = Date.now();
var startPos = element.scrollTop;

// Don't try to scroll beyond the limits. You won't get there and this will loop forever.
newPos = Math.max(0, newPos);
newPos = Math.min(element.scrollHeight - element.clientHeight, newPos);
var change = newPos - startPos;

// This inner function is called until the elements scrollTop reaches newPos.
var updateScroll = function () {
var now = Date.now();
var time = now - startTime;
this.isAutoScrolling = true;
element.scrollTop = this.easeOut(time, startPos, change, duration);
if (element.scrollTop !== newPos) {
requestAnimationFrame(updateScroll, element);
}
};
requestAnimationFrame(updateScroll, element);
},
// Scroll an element's parent so the element is brought into view.
scrollToElement: function (element) {
var parent = element.parentElement;
var parentOffsetBottom = parent.offsetTop + parent.clientHeight;
var elementOffsetBottom = element.offsetTop + element.clientHeight;
var relPos = (element.offsetTop + element.clientHeight) - parent.offsetTop;
var newPos;

// If the line is above the top of the parent view, were scrolling up,
// so we want to move the top of the element downwards to match the top of the parent.
if (relPos < parent.scrollTop) {
newPos = element.offsetTop - parent.offsetTop;

// If the line is below the parent view, we're scrolling down, so we want the
// bottom edge of the line to move up to meet the bottom edge of the parent.
} else if (relPos > (parent.scrollTop + parent.clientHeight)) {
newPos = elementOffsetBottom - parentOffsetBottom;
}
// The scroll event. We want to keep track of when the user is scrolling the transcript.
el.addEventListener('scroll', function () {
if (this.isAutoScrolling) {

// If isAutoScrolling was set to true, we can set it to false and then ignore this event.
this.isAutoScrolling = false; // event handled
} else {

// We only care about when the user scrolls. Set userIsScrolling to true and add a nice class.
this.userIsScrolling = true;
el.classList.add('is-inuse');
}
});

// The mouseover event.
el.addEventListener('mouseover', function () {
this.mouseIsOverTranscript = true;
});
el.addEventListener('mouseout', function () {
this.mouseIsOverTranscript = false;

// Have a small delay before deciding user as done interacting.
setTimeout(function () {

// Don't try to scroll if we haven't set a new position. If we didn't
// set a new position the line is already in view (i.e. It's not above
// or below the view)
// And don't try to scroll when the element is already in position.
if (newPos !== undefined && parent.scrollTop !== newPos) {
scrollTo(parent, newPos, 400);
// Make sure the user didn't move the pointer back in.
if (!this.mouseIsOverTranscript) {
this.userIsScrolling = false;
el.classList.remove('is-inuse');
}
},
}, 1000);
});
};

// Init instance variables
var init = function (element, plugin) {
this.element = element;
this.userIsScrolling = false;
this.mouseIsOver = false;
this.isAutoScrolling = true;
initHandlers(this.element);
return this;
};

initHandlers: function () {
var el = this.element;
// The scroll event. We want to keep track of when the user is scrolling the transcript.
el.addEventListener('scroll', function () {
if (this.isAutoScrolling) {
// Easing function for smoothness.
var easeOut = function (time, start, change, duration) {
return start + change * Math.sin(Math.min(1, time / duration) * (Math.PI / 2));
};

// If isAutoScrolling was set to true, we can set it to false and then ignore this event.
this.isAutoScrolling = false; // event handled
} else {
// Animate the scrolling.
var scrollTo = function (element, newPos, duration) {
var startTime = Date.now();
var startPos = element.scrollTop;

// We only care about when the user scrolls. Set userIsScrolling to true and add a nice class.
this.userIsScrolling = true;
el.classList.add('is-inuse');
}
});

// The mouseover event.
el.addEventListener('mouseover', function () {
this.mouseIsOverTranscript = true;
});
el.addEventListener('mouseout', function () {
this.mouseIsOverTranscript = false;

// Have a small delay before deciding user as done interacting.
setTimeout(function () {

// Make sure the user didn't move the pointer back in.
if (!this.mouseIsOverTranscript) {
this.userIsScrolling = false;
el.classList.remove('is-inuse');
}
}, 1000);
});
},

// Return whether the element is scrollable.
canScroll: function () {
var el = this.element;
return el.scrollHeight > el.offsetHeight;
},

// Return whether the user is interacting with the transcript.
inUse: function () {
return this.userIsScrolling;
},
el: function () {
return this.element;
},
// Don't try to scroll beyond the limits. You won't get there and this will loop forever.
newPos = Math.max(0, newPos);
newPos = Math.min(element.scrollHeight - element.clientHeight, newPos);
var change = newPos - startPos;

// This inner function is called until the elements scrollTop reaches newPos.
var updateScroll = function () {
var now = Date.now();
var time = now - startTime;
this.isAutoScrolling = true;
element.scrollTop = easeOut(time, startPos, change, duration);
if (element.scrollTop !== newPos) {
requestAnimationFrame(updateScroll, element);
}
};
requestAnimationFrame(updateScroll, element);
};
//Factory function
var createScrollable = function (element) {
var ob = Object.create(scrollablePrototype)
console.log(ob);
utils.extend(ob, {
element: element,
userIsScrolling : false,
mouseIsOver: false,
isAutoScrolling: true,
});
console.log(ob);
return ob;

// Scroll an element's parent so the element is brought into view.
var scrollToElement = function (element) {
var parent = element.parentElement;
var parentOffsetBottom = parent.offsetTop + parent.clientHeight;
var elementOffsetBottom = element.offsetTop + element.clientHeight;
var relPos = (element.offsetTop + element.clientHeight) - parent.offsetTop;
var newPos;

// If the line is above the top of the parent view, were scrolling up,
// so we want to move the top of the element downwards to match the top of the parent.
if (relPos < parent.scrollTop) {
newPos = element.offsetTop - parent.offsetTop;

// If the line is below the parent view, we're scrolling down, so we want the
// bottom edge of the line to move up to meet the bottom edge of the parent.
} else if (relPos > (parent.scrollTop + parent.clientHeight)) {
newPos = elementOffsetBottom - parentOffsetBottom;
}

// Don't try to scroll if we haven't set a new position. If we didn't
// set a new position the line is already in view (i.e. It's not above
// or below the view)
// And don't try to scroll when the element is already in position.
if (newPos !== undefined && parent.scrollTop !== newPos) {
scrollTo(parent, newPos, 400);
}
};
return {
create: createScrollable

// Return whether the element is scrollable.
var canScroll = function () {
var el = this.element;
return el.scrollHeight > el.offsetHeight;
};

// Return whether the user is interacting with the transcript.
var inUse = function () {
return this.userIsScrolling;
};

return {
init: init,
to : scrollToElement,
canScroll : canScroll,
inUse : inUse
}
}(my);

var scroller = function(element) {
return Object.create(scrollerProto).init(element);
};


/*global my*/
var trackList = function (plugin) {
Expand Down Expand Up @@ -376,6 +376,8 @@ var widget = function (plugin) {
} else {
createTranscript();
}
body.scroll = scroller(body);
console.log(scroller(body));
return body;
};
var create = function () {
Expand All @@ -393,12 +395,31 @@ var widget = function (plugin) {
};
var setTrack = function (track) {
var newBody = createTranscriptBody(track);
my.element.insertBefore(newBody, my.body);
my.element.removeChild(my.body);
my.element.replaceChild(newBody, my.body);
my.body = newBody;
};
var setCue = function () {
//need to implement
var setCue = function (time) {
var active, i, line, begin, end;
var lines = my.body.children;
for (i = 0; i < lines.length; i++) {
line = lines[i];
begin = line.getAttribute('data-begin');
if (i < lines.length - 1) {
end = lines[i + 1].getAttribute('data-begin');
} else {
end = plugin.player.duration() || Infinity;
}
if (time > begin && time < end) {
if (!line.classList.contains('is-active')) { // don't update if it hasn't changed
line.classList.add('is-active');
if (plugin.settings.autoscroll && my.body.scroll.canScroll() && !my.body.scroll.inUse()) {
my.body.scroll.to(line);
}
}
} else {
line.classList.remove('is-active');
}
}
};
var el = function () {
return my.element;
Expand Down
Loading

0 comments on commit 19edeb5

Please sign in to comment.