gyorgy@0: (function($) { gyorgy@0: gyorgy@0: $.extend(mejs.MepDefaults, { gyorgy@0: backlightBackground: [0,0,0], gyorgy@0: backlightHorizontalLights: 5, gyorgy@0: backlightVerticalLights: 5, gyorgy@0: backlightSize: 50, gyorgy@0: backlightTimeout: 200 gyorgy@0: }); gyorgy@0: gyorgy@0: gyorgy@0: gyorgy@0: MediaElementPlayer.prototype.buildbacklight = function(player, controls, layers, media) { gyorgy@0: if (!player.isVideo) gyorgy@0: return; gyorgy@0: gyorgy@0: //http://www.splashnology.com/blog/html5/382.html gyorgy@0: gyorgy@0: var gyorgy@0: mediaContainer = player.container.find('.mejs-mediaelement').parent(), gyorgy@0: border = $('
') gyorgy@0: .prependTo(mediaContainer) gyorgy@0: .css('position','absolute') gyorgy@0: .css('top','-10px') gyorgy@0: .css('left','-10px') gyorgy@0: .css('border','solid 10px #010101') gyorgy@0: .width(player.width).height(player.height), gyorgy@0: glowBase = $('
') gyorgy@0: .prependTo(mediaContainer) gyorgy@0: .css('position','absolute') gyorgy@0: .css('display','none') gyorgy@0: .css('top',0) gyorgy@0: .css('left',0) gyorgy@0: .width(player.width).height(player.height), gyorgy@0: base = $('
') gyorgy@0: .prependTo(mediaContainer) gyorgy@0: .css('position','absolute') gyorgy@0: .css('top',0) gyorgy@0: .css('left',0) gyorgy@0: .width(player.width).height(player.height), gyorgy@0: gyorgy@0: i, gyorgy@0: copyCanvas = document.createElement('canvas'), gyorgy@0: copyContext = copyCanvas.getContext('2d'), gyorgy@0: pixels, gyorgy@0: keepUpdating = true, gyorgy@0: isActive = true, gyorgy@0: timer = null, gyorgy@0: glowCanvas = document.createElement('canvas'), gyorgy@0: glowContext = glowCanvas.getContext('2d'), gyorgy@0: size = player.options.backlightSize, gyorgy@0: backgroundColor = player.options.backlightBackground, gyorgy@0: gradient, gyorgy@0: width = player.width, gyorgy@0: height = player.height; gyorgy@0: gyorgy@0: // set sizes gyorgy@0: copyCanvas.width = width; gyorgy@0: copyCanvas.height = height; gyorgy@0: glowCanvas.width = width + size + size; gyorgy@0: glowCanvas.height = height + size + size; gyorgy@0: gyorgy@0: // draw glow overlay gyorgy@0: // top gyorgy@0: gradient = addGlow(backgroundColor,glowContext.createLinearGradient(size, size, size, 0)); gyorgy@0: glowContext.fillStyle = gradient; gyorgy@0: glowContext.fillRect(size, size, width, -size); gyorgy@0: gyorgy@0: // tr gyorgy@0: gradient = addGlow(backgroundColor,glowContext.createRadialGradient(width+size, size, 0, width+size, size, size)); gyorgy@0: glowContext.fillStyle = gradient; gyorgy@0: glowContext.fillRect(width+size, size, size, -size); gyorgy@0: gyorgy@0: // right gyorgy@0: gradient = addGlow(backgroundColor,glowContext.createLinearGradient(width+size, size, width+size+size, size)); gyorgy@0: glowContext.fillStyle = gradient; gyorgy@0: glowContext.fillRect(width+size, size, size, height); gyorgy@0: gyorgy@0: // br gyorgy@0: gradient = addGlow(backgroundColor,glowContext.createRadialGradient(width+size, height+size, 0, width+size, height+size, size)); gyorgy@0: glowContext.fillStyle = gradient; gyorgy@0: glowContext.fillRect(width+size, height+size, size, size); gyorgy@0: gyorgy@0: // bottom gyorgy@0: var gradient = addGlow(backgroundColor,glowContext.createLinearGradient(size, size+height, size, size+height+size)); gyorgy@0: glowContext.fillStyle = gradient; gyorgy@0: glowContext.fillRect(size, size+height, width, size); gyorgy@0: gyorgy@0: // bl gyorgy@0: gradient = addGlow(backgroundColor,glowContext.createRadialGradient(size, height+size, 0, size, height+size, size)); gyorgy@0: glowContext.fillStyle = gradient; gyorgy@0: glowContext.fillRect(0, height+size, size, size); gyorgy@0: gyorgy@0: // left gyorgy@0: gradient = addGlow(backgroundColor,glowContext.createLinearGradient(size, size, 0, size)); gyorgy@0: glowContext.fillStyle = gradient; gyorgy@0: glowContext.fillRect(size, size, -size, height); gyorgy@0: gyorgy@0: // tl gyorgy@0: gradient = addGlow(backgroundColor,glowContext.createRadialGradient(size, size, 0, size, size, size)); gyorgy@0: glowContext.fillStyle = gradient; gyorgy@0: glowContext.fillRect(0, 0, size, size); gyorgy@0: gyorgy@0: $(glowCanvas) gyorgy@0: .css('position','absolute') gyorgy@0: .css('top',-size) gyorgy@0: .css('left',-size) gyorgy@0: .appendTo(glowBase); gyorgy@0: gyorgy@0: gyorgy@0: // add toggle control gyorgy@0: $('
') gyorgy@0: .appendTo(controls) gyorgy@0: .click(function() { gyorgy@0: if (isActive) { gyorgy@0: delete timer; gyorgy@0: timer = null; gyorgy@0: base.hide(); gyorgy@0: glowBase.hide(); gyorgy@0: $(this) gyorgy@0: .removeClass('mejs-backlight-active') gyorgy@0: .addClass('mejs-backlight-inactive') gyorgy@0: } else { gyorgy@0: updateLights(); gyorgy@0: base.show(); gyorgy@0: glowBase.show(); gyorgy@0: $(this) gyorgy@0: .removeClass('mejs-backlight-inactive') gyorgy@0: .addClass('mejs-backlight-active') gyorgy@0: } gyorgy@0: isActive = !isActive; gyorgy@0: }); gyorgy@0: gyorgy@0: gyorgy@0: // http://www.splashnology.com/blog/html5/382.html gyorgy@0: function updateLights() { gyorgy@0: gyorgy@0: // get a copy of video gyorgy@0: copyContext.drawImage(media, 0, 0, media.width, media.height); gyorgy@0: gyorgy@0: // create the gradient lights gyorgy@0: addLights(base, copyCanvas, copyContext, gyorgy@0: player.options.backlightVerticalLights, gyorgy@0: player.options.backlightHorizontalLights, gyorgy@0: player.options.backlightSize, gyorgy@0: 30); gyorgy@0: gyorgy@0: if (keepUpdating && isActive) { gyorgy@0: timer = setTimeout(updateLights, player.options.backlightTimeout); gyorgy@0: } gyorgy@0: } gyorgy@0: gyorgy@0: gyorgy@0: gyorgy@0: gyorgy@0: //setTimeout(updateLights, timeOut); gyorgy@0: gyorgy@0: media.addEventListener('play',function() { gyorgy@0: if (isActive) { gyorgy@0: keepUpdating = true; gyorgy@0: updateLights(); gyorgy@0: glowBase.css('display',''); gyorgy@0: } gyorgy@0: }, false); gyorgy@0: media.addEventListener('pause',function() { gyorgy@0: keepUpdating = false; gyorgy@0: }, false); gyorgy@0: media.addEventListener('ended',function() { gyorgy@0: keepUpdating = false; gyorgy@0: }, false); gyorgy@0: gyorgy@0: }; gyorgy@0: gyorgy@0: gyorgy@0: gyorgy@0: function addLights(base, canvas, context, vBlocks, hBlocks, size, depth) { gyorgy@0: base.empty(); gyorgy@0: gyorgy@0: var gyorgy@0: lightsCanvas = document.createElement('canvas'), gyorgy@0: lightsContext = lightsCanvas.getContext('2d'), gyorgy@0: width = canvas.width, gyorgy@0: height = canvas.height, gyorgy@0: g, gyorgy@0: topLights = getMidColors(canvas, context, hBlocks, depth, 'top'), gyorgy@0: bottomLights = getMidColors(canvas, context, hBlocks, depth, 'bottom'), gyorgy@0: leftLights = getMidColors(canvas, context, vBlocks, depth, 'left'), gyorgy@0: rightLights = getMidColors(canvas, context, vBlocks, depth, 'right'), gyorgy@0: corners = [], gyorgy@0: stopSize = 0; gyorgy@0: gyorgy@0: lightsCanvas.width = width + size + size; gyorgy@0: lightsCanvas.height = height + size + size; gyorgy@0: lightsContext.globalCompositeOperation = 'xor'; //'darker'; //'lighter'; gyorgy@0: gyorgy@0: // draw four gradients gyorgy@0: // create corners gyorgy@0: corners.push(averageColor(topLights[topLights.length-1], rightLights[0]) ); gyorgy@0: corners.push(averageColor(bottomLights[bottomLights.length-1], rightLights[rightLights.length-1]) ); gyorgy@0: corners.push(averageColor(bottomLights[0], leftLights[leftLights.length-1]) ); gyorgy@0: corners.push(averageColor(topLights[0], leftLights[0]) ); gyorgy@0: gyorgy@0: // top gyorgy@0: stopSize = 1 / topLights.length; gyorgy@0: gradient = context.createLinearGradient(size, size, width+size, size); gyorgy@0: gradient.addColorStop(0, 'rgb(' + adjustColor(corners[3]).join(',') + ')'); gyorgy@0: for (var i = 0, il = topLights.length; i < il; i++) { gyorgy@0: gradient.addColorStop(i * stopSize + stopSize/2, 'rgb(' + adjustColor(topLights[i]).join(',') + ')'); gyorgy@0: } gyorgy@0: gradient.addColorStop(1.0, 'rgb(' + adjustColor(corners[0]).join(',') + ')'); gyorgy@0: lightsContext.fillStyle = gradient; gyorgy@0: lightsContext.fillRect(size, 0, width, size); gyorgy@0: gyorgy@0: // right gyorgy@0: gradient = context.createLinearGradient(size+width, size, size+width, size+height); gyorgy@0: gradient.addColorStop(0, 'rgb(' + adjustColor(corners[0]).join(',') + ')'); gyorgy@0: for (var i = 0, il = rightLights.length; i < il; i++) { gyorgy@0: gradient.addColorStop(i * stopSize + stopSize/2, 'rgb(' + adjustColor(rightLights[i]).join(',') + ')'); gyorgy@0: } gyorgy@0: gradient.addColorStop(1.0, 'rgb(' + adjustColor(corners[1]).join(',') + ')'); gyorgy@0: lightsContext.fillStyle = gradient; gyorgy@0: lightsContext.fillRect(size+width, size, size+width+size, height); gyorgy@0: gyorgy@0: gyorgy@0: // bottom gyorgy@0: gradient = context.createLinearGradient(size, size+height, size+width, size+height); gyorgy@0: gradient.addColorStop(0, 'rgb(' + adjustColor(corners[2]).join(',') + ')'); gyorgy@0: for (var i = 0, il = bottomLights.length; i < il; i++) { gyorgy@0: gradient.addColorStop(i * stopSize + stopSize/2, 'rgb(' + adjustColor(bottomLights[i]).join(',') + ')'); gyorgy@0: } gyorgy@0: gradient.addColorStop(1.0, 'rgb(' + adjustColor(corners[1]).join(',') + ')'); gyorgy@0: lightsContext.fillStyle = gradient; gyorgy@0: lightsContext.fillRect(size, size+height, width, size); gyorgy@0: gyorgy@0: // left gyorgy@0: gradient = context.createLinearGradient(size, size, size, size+height); gyorgy@0: gradient.addColorStop(0, 'rgb(' + adjustColor(corners[3]).join(',') + ')'); gyorgy@0: for (var i = 0, il = leftLights.length; i < il; i++) { gyorgy@0: gradient.addColorStop(i * stopSize + stopSize/2, 'rgb(' + adjustColor(leftLights[i]).join(',') + ')'); gyorgy@0: } gyorgy@0: gradient.addColorStop(1.0, 'rgb(' + adjustColor(corners[2]).join(',') + ')'); gyorgy@0: lightsContext.fillStyle = gradient; gyorgy@0: lightsContext.fillRect(0, size, size, height); gyorgy@0: gyorgy@0: // corners gyorgy@0: gyorgy@0: // top right gyorgy@0: lightsContext.fillStyle = 'rgb(' + adjustColor(corners[0]).join(',') + ')'; gyorgy@0: lightsContext.fillRect(width+size, 0, size+width+size, size); gyorgy@0: gyorgy@0: // bottom right gyorgy@0: lightsContext.fillStyle = 'rgb(' + adjustColor(corners[1]).join(',') + ')'; gyorgy@0: lightsContext.fillRect(width+size, size+height, size+width+size, size+height+size); gyorgy@0: gyorgy@0: // bottom left gyorgy@0: lightsContext.fillStyle = 'rgb(' + adjustColor(corners[2]).join(',') + ')'; gyorgy@0: lightsContext.fillRect(0, size+height, size, size+height+size); gyorgy@0: gyorgy@0: // top left gyorgy@0: lightsContext.fillStyle = 'rgb(' + adjustColor(corners[3]).join(',') + ')'; gyorgy@0: lightsContext.fillRect(0, 0, size, size); gyorgy@0: gyorgy@0: gyorgy@0: gyorgy@0: gyorgy@0: gyorgy@0: $(lightsCanvas) gyorgy@0: .css('position','absolute') gyorgy@0: .css('top',-size) gyorgy@0: .css('left',-size) gyorgy@0: .appendTo(base); gyorgy@0: } gyorgy@0: gyorgy@0: function addGlow(color, g) { gyorgy@0: g.addColorStop(0.0, 'rgba(' + color.join(',') + ',0)'); gyorgy@0: g.addColorStop(1.0, 'rgba(' + color.join(',') + ',1)'); gyorgy@0: return g; gyorgy@0: } gyorgy@0: gyorgy@0: gyorgy@0: gyorgy@0: gyorgy@0: function getMidColors(canvas, context, blocks, blockDepth, side) { gyorgy@0: var width = canvas.width, gyorgy@0: height = canvas.height, gyorgy@0: blockHeight = (side == 'top' || side == 'bottom') ? blockDepth : Math.ceil(height / blocks), // height of the analyzed block gyorgy@0: blockWidth = (side == 'top' || side == 'bottom') ? Math.ceil(width / blocks) : blockDepth, gyorgy@0: result = [], gyorgy@0: imgdata, gyorgy@0: i; gyorgy@0: gyorgy@0: if (side == 'top' || side == 'bottom') { gyorgy@0: for (i = 0; i < blocks; i++) { gyorgy@0: try { gyorgy@0: imgdata = context.getImageData(i*blockWidth, (side == 'top') ? 0 : height - blockHeight , blockWidth, blockHeight); gyorgy@0: result.push( gyorgy@0: calcMidColor(imgdata.data) gyorgy@0: ); gyorgy@0: } catch (e) { gyorgy@0: console.log(e); gyorgy@0: } gyorgy@0: } gyorgy@0: } else { gyorgy@0: gyorgy@0: for (i = 0; i < blocks; i++) { gyorgy@0: try { gyorgy@0: imgdata = context.getImageData( (side == 'right') ? width - blockWidth : 0, i*blockHeight, blockWidth, blockHeight); gyorgy@0: result.push( gyorgy@0: calcMidColor(imgdata.data) gyorgy@0: ); gyorgy@0: } catch (e) { gyorgy@0: console.log(e); gyorgy@0: } gyorgy@0: gyorgy@0: } gyorgy@0: } gyorgy@0: gyorgy@0: gyorgy@0: return result; gyorgy@0: } gyorgy@0: gyorgy@0: function averageColor(c1,c2) { gyorgy@0: var result = gyorgy@0: [(c1[0] + c2[0]) / 2, gyorgy@0: (c1[1] + c2[1]) / 2, gyorgy@0: (c1[2] + c2[2]) / 2]; gyorgy@0: gyorgy@0: return result; gyorgy@0: } gyorgy@0: gyorgy@0: // average color for a block gyorgy@0: function calcMidColorVertical(data, from, to) { gyorgy@0: var result = [0, 0, 0]; gyorgy@0: var totalPixels = (to - from) / 4; gyorgy@0: gyorgy@0: for (var i = from; i <= to; i += 4) { gyorgy@0: result[0] += data[i]; gyorgy@0: result[1] += data[i + 1]; gyorgy@0: result[2] += data[i + 2]; gyorgy@0: } gyorgy@0: gyorgy@0: result[0] = Math.round(result[0] / totalPixels); gyorgy@0: result[1] = Math.round(result[1] / totalPixels); gyorgy@0: result[2] = Math.round(result[2] / totalPixels); gyorgy@0: gyorgy@0: return result; gyorgy@0: } gyorgy@0: gyorgy@0: // average color for a block gyorgy@0: function calcMidColor(data) { gyorgy@0: var result = [0, 0, 0]; gyorgy@0: var totalPixels = data.length; gyorgy@0: gyorgy@0: for (var i = 0; i < totalPixels; i += 4) { gyorgy@0: result[0] += data[i]; gyorgy@0: result[1] += data[i + 1]; gyorgy@0: result[2] += data[i + 2]; gyorgy@0: } gyorgy@0: gyorgy@0: result[0] = Math.round(result[0] / totalPixels); gyorgy@0: result[1] = Math.round(result[1] / totalPixels); gyorgy@0: result[2] = Math.round(result[2] / totalPixels); gyorgy@0: gyorgy@0: return result; gyorgy@0: } gyorgy@0: gyorgy@0: function adjustColor(color) { gyorgy@0: //if (color[0] <= 2 && color[2] <= 2 && color[3] <= 2) gyorgy@0: // return color; gyorgy@0: gyorgy@0: color = rgb2hsv(color); gyorgy@0: color[1] = Math.min(100, color[1] * 1.2); //1.4); // saturation gyorgy@0: color[2] = 80; //Math.min(100, color[2] * 2.7); //2.7); // brightness gyorgy@0: return hsv2rgb(color); gyorgy@0: } gyorgy@0: gyorgy@0: function rgb2hsv(color) { gyorgy@0: var r = color[0] / 255, gyorgy@0: g = color[1] / 255, gyorgy@0: b = color[2] / 255, gyorgy@0: gyorgy@0: x, val, d1, d2, hue, sat, val; gyorgy@0: gyorgy@0: x = Math.min(Math.min(r, g), b); gyorgy@0: val = Math.max(Math.max(r, g), b); gyorgy@0: //if (x == val) gyorgy@0: // throw Error('h is undefined'); gyorgy@0: gyorgy@0: d1 = (r == x) ? g-b : ((g == x) ? b-r : r-g); gyorgy@0: d2 = (r == x) ? 3 : ((g == x) ? 5 : 1); gyorgy@0: gyorgy@0: hue = Math.floor((d2 - d1 / (val - x)) * 60) % 360; gyorgy@0: sat = Math.floor(((val - x) / val) * 100); gyorgy@0: val = Math.floor(val * 100); gyorgy@0: return [hue, sat, val]; gyorgy@0: } gyorgy@0: gyorgy@0: /** gyorgy@0: * Convers HSV color to RGB model gyorgy@0: * @param {Number[]} RGB color gyorgy@0: * @return {Number[]} HSV color gyorgy@0: */ gyorgy@0: function hsv2rgb(color) { gyorgy@0: var h = color[0], gyorgy@0: s = color[1], gyorgy@0: v = color[2]; gyorgy@0: gyorgy@0: var r, g, a, b, c, s = s / 100, v = v / 100, h = h / 360; gyorgy@0: gyorgy@0: if (s > 0) { gyorgy@0: if (h >= 1) h=0; gyorgy@0: gyorgy@0: h = 6 * h; gyorgy@0: var f = h - Math.floor(h); gyorgy@0: a = Math.round(255 * v * (1 - s)); gyorgy@0: b = Math.round(255 * v * (1 - (s * f))); gyorgy@0: c = Math.round(255 * v * (1 - (s * (1 - f)))); gyorgy@0: v = Math.round(255 * v); gyorgy@0: gyorgy@0: switch (Math.floor(h)) { gyorgy@0: case 0: r = v; g = c; b = a; break; gyorgy@0: case 1: r = b; g = v; b = a; break; gyorgy@0: case 2: r = a; g = v; b = c; break; gyorgy@0: case 3: r = a; g = b; b = v; break; gyorgy@0: case 4: r = c; g = a; b = v; break; gyorgy@0: case 5: r = v; g = a; b = b; break; gyorgy@0: } gyorgy@0: gyorgy@0: return [r || 0, g || 0, b || 0]; gyorgy@0: gyorgy@0: } else { gyorgy@0: v = Math.round(v * 255); gyorgy@0: return [v, v, v]; gyorgy@0: } gyorgy@0: } gyorgy@0: gyorgy@0: })(mejs.$);