1/* 2 * backgroundBrightness.js 3 * 4 * Copyright 2016, Jesse Lee & Organic Themes w/ snippets from ColourBrightness.js 5 * Released under the WTFPL license 6 * https://organicthemes.com 7 * 8 * Version: 1.0 9 */ 10 11(function ($) { 12 13 "use strict"; 14 15 $.fn.extend({ 16 17 backgroundBrightness: function (contentSelectors, threshold) { 18 19 // RGB Brightness Threshold 20 var threshold = 160; 21 22 // Background Object 23 var el = $(this); 24 25 // Content Targets 26 if ( ! contentSelectors ) { 27 contentSelectors = false; 28 } else if ( !( contentSelectors.constructor === Array) ) { 29 contentSelectors = [contentSelectors]; 30 } 31 32 //Loop Through all Items 33 $.each(el, function(key, value){ 34 35 //Initialize 36 var r,g,b,brightness; 37 38 //Get Background Styles for element 39 var bgStyles = getBackgroundStyles( $(value) ); 40 var colour = bgStyles.bgColor; 41 var image = bgStyles.bgImage; 42 var targetedElement = bgStyles.targetedElement; 43 44 // If bg image found, calculate luminosity of image 45 if ( image ) { 46 getBackgroundImageLuminosity( targetedElement, contentSelectors, threshold); 47 } 48 // If no bg image, calculate bg color brightness 49 else if ( colour ) { 50 if (colour.match(/^rgb/)) { 51 colour = colour.match(/rgba?\(([^)]+)\)/)[1]; 52 colour = colour.split(/ *, */).map(Number); 53 r = colour[0]; 54 g = colour[1]; 55 b = colour[2]; 56 } else if ("#" === colour[0] && 7 === colour.length) { 57 r = parseInt(colour.slice(1, 3), 16); 58 g = parseInt(colour.slice(3, 5), 16); 59 b = parseInt(colour.slice(5, 7), 16); 60 } else if ("#" === colour[0] && 4 === colour.length) { 61 r = parseInt(colour[1] + colour[1], 16); 62 g = parseInt(colour[2] + colour[2], 16); 63 b = parseInt(colour[3] + colour[3], 16); 64 } 65 66 brightness = (r * 299 + g * 587 + b * 114) / 1000; 67 68 if (brightness < threshold) { 69 // white text 70 targetedElement.removeClass("ocw-bg-light").addClass("ocw-bg-dark"); 71 } else { 72 // black text 73 targetedElement.removeClass("ocw-bg-dark").addClass("ocw-bg-light"); 74 } 75 76 } 77 78 }); 79 80 function getBackgroundImageLuminosity(el, contentSelectors, threshold ) { 81 82 var bg = el.css("backgroundImage"); 83 bg = bg.replace(/^url\(['"]?/, "").replace(/['"]?\)$/, ""); 84 85 getImageLightness( bg, el ,function(brightness,el){ 86 87 // Set classes to add and to remove 88 if (brightness < threshold) { 89 var addClass = "ocw-bg-dark"; 90 var removeClass = "ocw-bg-light"; 91 } else { 92 var addClass = "ocw-bg-light"; 93 var removeClass = "ocw-bg-dark"; 94 } 95 96 // Add and remove classes 97 // If applying to self 98 if (!contentSelectors ){ 99 if ( !el.hasClass("ocw-bg-img") ) el.addClass("ocw-bg-img"); 100 el.removeClass(removeClass); 101 el.addClass(addClass); 102 } 103 // If applying to custom selectors 104 else { 105 contentSelectors.forEach(function(contentSelector){ 106 if ( !$(contentSelector).hasClass("ocw-bg-img") ) $(contentSelector).addClass("ocw-bg-img"); 107 $(contentSelector).removeClass(removeClass); 108 $(contentSelector).addClass(addClass); 109 }); 110 } 111 112 }); // End getImageLightness(){} 113 114 } // End getBackgroundImageLuminosity(){} 115 116 function getImageLightness(imageSrc, imgObject, callback) { 117 var img = document.createElement("img"); 118 img.crossOrigin = "Anonymous"; 119 img.src = imageSrc; 120 img.style.display = "none"; 121 // document.body.appendChild(img); // Adds HTML img tag in footer twice 122 123 var colorSum = 0; 124 125 img.onload = function() { 126 // create canvas 127 var canvas = document.createElement( "canvas" ); 128 canvas.width = this.width; 129 canvas.height = this.height; 130 131 var ctx = canvas.getContext( "2d" ); 132 ctx.drawImage(this,0,0); 133 134 var imageData = ctx.getImageData( 0, 0, canvas.width, canvas.height ); 135 var data = imageData.data; 136 var r,g,b,avg; 137 138 for ( var x = 0, len = data.length; x < len; x += 4 ) { 139 r = data[x]; 140 g = data[x + 1]; 141 b = data[x + 2]; 142 143 avg = Math.floor( (r + g + b) / 3 ); 144 colorSum += avg; 145 } 146 147 var brightness = Math.floor(colorSum / (this.width * this.height)); 148 callback(brightness, imgObject); 149 } 150 } // End getImageLightness(){} 151 152 /* ======== ColourBrightness Addons =========*/ 153
154 function getBackgroundStyles(el) { 155 var bgColor = false; 156 var bgImage = false; 157 while(el[0].tagName.toLowerCase() !== "html") { 158 bgColor = ( ! el.css("backgroundColor") || el.css("backgroundColor") === "rgba(0, 0, 0, 0)" || el.css("backgroundColor") === "transparent" ) ? false : el.css("backgroundColor"); 159 bgImage = ( ! el.css("backgroundImage") || el.css("backgroundImage") === "" || el.css("backgroundImage") === "none" ) ? false : el.css("backgroundImage"); 160 if ( bgColor || bgImage ) { 161 break; 162 } 163 el = el.parent(); 164 } 165 return { bgColor: bgColor, bgImage: bgImage, targetedElement: el }; 166 } 167 168 } // End backgroundBrightness(){} 169 170 }) 171 172})( jQuery );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.