Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Slider updates - "separate" handle logic from the slider and allow for vertical or horizontal orientation #1816

Closed
wants to merge 4 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 72 additions & 27 deletions src/js/slider.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ vjs.Slider = vjs.Component.extend({
this.bar = this.getChild(this.options_['barName']);
this.handle = this.getChild(this.options_['handleName']);

// Set a horizontal or vertical class on the slider depending on the slider type
this.vertical(!!this.options()['vertical']);

this.on('mousedown', this.onMouseDown);
this.on('touchstart', this.onMouseDown);
this.on('focus', this.onFocus);
Expand Down Expand Up @@ -78,11 +81,11 @@ vjs.Slider.prototype.update = function(){
// If scrubbing, we could use a cached value to make the handle keep up with the user's mouse.
// On HTML5 browsers scrubbing is really smooth, but some flash players are slow, so we might want to utilize this later.
// var progress = (this.player_.scrubbing) ? this.player_.getCache().currentTime / this.player_.duration() : this.player_.currentTime() / this.player_.duration();
var progress = this.getPercent();
var bar = this.bar;

var barProgress,
progress = this.getPercent(),
handle = this.handle,
bar = this.bar;
// If there's no bar...
if (!bar) return;

// Protect against no duration and other division issues
if (typeof progress !== 'number' ||
Expand All @@ -92,47 +95,72 @@ vjs.Slider.prototype.update = function(){
progress = 0;
}

barProgress = progress;

// If there is a handle, we need to account for the handle in our calculation for progress bar
// so that it doesn't fall short of or extend past the handle.
if (handle) {
var barProgress = this.updateHandlePosition(progress);

// Convert to a percentage for setting
var percentage = vjs.round(barProgress * 100, 2) + '%';

var box = this.el_,
boxWidth = box.offsetWidth,
// Set the new bar width or height
if (this.vertical()) {
bar.el().style.height = percentage;
} else {
bar.el().style.width = percentage;
}
};

handleWidth = handle.el().offsetWidth,
/**
* Update the handle position.
*/
vjs.Slider.prototype.updateHandlePosition = function(progress) {
var handle = this.handle;
if (!handle) return;

var vertical = this.vertical();
var box = this.el_;

var boxSize, handleSize;
if (vertical) {
boxSize = box.offsetHeight;
handleSize = handle.el().offsetHeight;
} else {
boxSize = box.offsetWidth;
handleSize = handle.el().offsetWidth;
}

// The width of the handle in percent of the containing box
// In IE, widths may not be ready yet causing NaN
handlePercent = (handleWidth) ? handleWidth / boxWidth : 0,
// The width of the handle in percent of the containing box
// In IE, widths may not be ready yet causing NaN
var handlePercent = (handleSize) ? handleSize / boxSize : 0,

// Get the adjusted size of the box, considering that the handle's center never touches the left or right side.
// There is a margin of half the handle's width on both sides.
boxAdjustedPercent = 1 - handlePercent,
// Get the adjusted size of the box, considering that the handle's center never touches the left or right side.
// There is a margin of half the handle's width on both sides.
boxAdjustedPercent = 1 - handlePercent,

// Adjust the progress that we'll use to set widths to the new adjusted box width
adjustedProgress = progress * boxAdjustedPercent;
// Adjust the progress that we'll use to set widths to the new adjusted box width
adjustedProgress = progress * boxAdjustedPercent;

// The bar does reach the left side, so we need to account for this in the bar's width
barProgress = adjustedProgress + (handlePercent / 2);
// The bar does reach the left side, so we need to account for this in the bar's width
var barProgress = adjustedProgress + (handlePercent / 2);

// Move the handle from the left based on the adjected progress
handle.el().style.left = vjs.round(adjustedProgress * 100, 2) + '%';
}
var percentage = vjs.round(adjustedProgress * 100, 2) + '%';

// Set the new bar width
if (bar) {
bar.el().style.width = vjs.round(barProgress * 100, 2) + '%';
if (vertical) {
handle.el().style.bottom = percentage;
} else {
handle.el().style.left = percentage;
}

return barProgress;
};

vjs.Slider.prototype.calculateDistance = function(event){
var el, box, boxX, boxY, boxW, boxH, handle, pageX, pageY;

el = this.el_;
box = vjs.findPosition(el);
boxW = boxH = el.offsetWidth;
boxW = el.offsetWidth;
boxH = el.offsetHeight;
handle = this.handle;

if (this.options()['vertical']) {
Expand Down Expand Up @@ -204,6 +232,23 @@ vjs.Slider.prototype.onClick = function(event){
event.preventDefault();
};

vjs.Slider.prototype.vertical_ = false;
vjs.Slider.prototype.vertical = function(bool) {
if (bool === undefined) {
return this.vertical_;
}

this.vertical_ = !!bool;

if (this.vertical_) {
this.addClass('vjs-slider-vertical');
} else {
this.addClass('vjs-slider-horizontal');
}

return this;
};

/**
* SeekBar Behavior includes play progress bar, and seek handle
* Needed so it can determine seek position based on handle position/size
Expand Down