Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
187 lines
5.5 KiB
JavaScript
Executable file
187 lines
5.5 KiB
JavaScript
Executable file
/* exported VideoUtils */
|
|
'use strict';
|
|
|
|
var VideoUtils = {
|
|
/**
|
|
* fit the video player to the container. This function aspects the video
|
|
* ratio and scales video player to fit as large as possible area of
|
|
* container.
|
|
*
|
|
* @param {DOM} |container| the container for displaying this video.
|
|
* @param {DOM} |player| the video element to fit the container.
|
|
* @param {int} |videoRotation| the rotation of video content. (optional)
|
|
*/
|
|
fitContainer: function(container, player, videoRotation) {
|
|
var containerWidth = container.clientWidth;
|
|
var containerHeight = container.clientHeight;
|
|
|
|
// Don't do anything if we don't know our size.
|
|
// This could happen if we get a resize event before our metadata loads
|
|
if (!player.videoWidth || !player.videoHeight) {
|
|
return;
|
|
}
|
|
|
|
var width, height; // The size the video will appear, after rotation
|
|
var rotation = videoRotation || 0;
|
|
|
|
switch (rotation) {
|
|
case 0:
|
|
case 180:
|
|
width = player.videoWidth;
|
|
height = player.videoHeight;
|
|
break;
|
|
case 90:
|
|
case 270:
|
|
width = player.videoHeight;
|
|
height = player.videoWidth;
|
|
}
|
|
|
|
var xscale = containerWidth / width;
|
|
var yscale = containerHeight / height;
|
|
var scale = Math.min(xscale, yscale);
|
|
|
|
// scale large videos down and scale small videos up
|
|
// this might result in lower image quality for small videos
|
|
width *= scale;
|
|
height *= scale;
|
|
|
|
var left = ((containerWidth - width) / 2);
|
|
var top = ((containerHeight - height) / 2);
|
|
|
|
/*
|
|
* The translate and scale only takes a number + length unit. According to
|
|
* MDN's number definition, the scientific notation, 2.1234e-14, is not a
|
|
* valid value. To prevent that, we use toFixed(4) to round at the 4th
|
|
* digits after decimal point.
|
|
*/
|
|
var transform;
|
|
switch (rotation) {
|
|
case 0:
|
|
transform = 'translate(' + left.toFixed(4) + 'px,' +
|
|
top.toFixed(4) + 'px)';
|
|
break;
|
|
case 90:
|
|
transform =
|
|
'translate(' + (left + width).toFixed(4) + 'px,' +
|
|
top.toFixed(4) + 'px) ' +
|
|
'rotate(90deg)';
|
|
break;
|
|
case 180:
|
|
transform =
|
|
'translate(' + (left + width).toFixed(4) + 'px,' +
|
|
(top + height).toFixed(4) + 'px) ' +
|
|
'rotate(180deg)';
|
|
break;
|
|
case 270:
|
|
transform =
|
|
'translate(' + left.toFixed(4) + 'px,' +
|
|
(top + height).toFixed(4) + 'px) ' +
|
|
'rotate(270deg)';
|
|
break;
|
|
}
|
|
|
|
transform += ' scale(' + scale.toFixed(4) + ')';
|
|
|
|
player.style.transform = transform;
|
|
},
|
|
|
|
/**
|
|
* To get the truncated string. It loads oldName into a HTML Element provided
|
|
* with options. This element must put into DOM tree and all css are applied.
|
|
* We use the height of this element to detect the creation of new line. So,
|
|
* the height of this element should not be fixed.
|
|
*
|
|
* arguments:
|
|
* oldName {string} the original string
|
|
* options {object} an object with the following attributes:
|
|
* node {HTMLElement}: the element contains the text.
|
|
* maxLine {int}: optional, maximum line of text. The default
|
|
* value is 2.
|
|
* ellipsisCharacter {string}: optional, the text of ellipsis
|
|
* char. The default value is '...'.
|
|
*
|
|
*/
|
|
getTruncated: function(oldName, options) {
|
|
|
|
// options
|
|
var maxLine = options.maxLine || 2;
|
|
var node = options.node;
|
|
var ellipsisCharacter = options.ellipsisCharacter || '...';
|
|
|
|
if (node === null) {
|
|
return oldName;
|
|
}
|
|
|
|
var realVisibility = node.style.visibility;
|
|
var realWordBreak = node.style.wordBreak;
|
|
|
|
/*
|
|
* Hide UI, because we are manipulating DOM
|
|
*/
|
|
node.style.visibility = 'hidden';
|
|
|
|
/*
|
|
* Force breaking on boundaries
|
|
*/
|
|
node.style.wordBreak = 'break-all';
|
|
|
|
/*
|
|
* Get the height of a line of text
|
|
*/
|
|
node.textContent = '.';
|
|
var baseHeight = node.clientHeight;
|
|
var computedStyle = window.getComputedStyle(node, null);
|
|
var paddingTop =
|
|
parseInt(computedStyle.getPropertyValue('padding-top'), 10);
|
|
var paddingBottom =
|
|
parseInt(computedStyle.getPropertyValue('padding-bottom'), 10);
|
|
var padding = paddingTop + paddingBottom;
|
|
var lineHeight = baseHeight - padding;
|
|
|
|
/*
|
|
* Determine if the title needs truncating
|
|
*/
|
|
node.textContent = oldName;
|
|
var originalTitleHeight = node.clientHeight - padding;
|
|
var linesForOriginalTitle = (originalTitleHeight / lineHeight);
|
|
if (linesForOriginalTitle <= maxLine) {
|
|
/*
|
|
* Title does not need truncating. Restore UI and return original title
|
|
*/
|
|
node.style.visibility = realVisibility;
|
|
node.style.wordBreak = realWordBreak;
|
|
return oldName;
|
|
}
|
|
|
|
function titleTooLong(pos) {
|
|
node.textContent = oldName.slice(0, pos) + ellipsisCharacter;
|
|
var tempTitleHeight = node.clientHeight - padding;
|
|
return (tempTitleHeight / lineHeight) > maxLine;
|
|
}
|
|
|
|
var low = 0;
|
|
var high = oldName.length - 1;
|
|
var mid;
|
|
var ellipsisIndex = 0;
|
|
|
|
do {
|
|
mid = Math.floor((low + high) / 2);
|
|
if (titleTooLong(mid)) {
|
|
high = mid - 1;
|
|
}
|
|
else {
|
|
ellipsisIndex = mid;
|
|
low = mid + 1;
|
|
}
|
|
}
|
|
while (low <= high);
|
|
|
|
var newName = oldName.slice(0, ellipsisIndex) + ellipsisCharacter;
|
|
|
|
// restore UI
|
|
node.style.visibility = realVisibility;
|
|
node.style.wordBreak = realWordBreak;
|
|
|
|
return newName;
|
|
}
|
|
};
|