Skip to content

Commit

Permalink
Additional class for complex backgrounds.
Browse files Browse the repository at this point in the history
  • Loading branch information
kennethcachia committed Sep 26, 2013
1 parent 1c0fef9 commit 1acd923
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 22 deletions.
35 changes: 34 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,38 @@ p.background--light {

Classes are only added if the element overlaps an image. An element is considered to overlap an image if at least 50% (configurable) of it's area is covering that image.

###Complex backgrounds

The light and dark classes work well with simple backgrounds, but you might require an additional level of control for elaborate backgrounds. BackgroundCheck adds `.background--complex` to an element if its background exceeds a certain level of complexity.

This class can be used as an intermediate state:

```css
p.background--light {
color: black;
}

p.background--dark {
color: white;
}

p.background--complex {
color: gray;
}
```

or:

```css
p.background--dark.background--complex {
color: #ccc;
}

p.background--light.background--complex {
color: #aaa;
}
```

##How to use

**Initialize**
Expand Down Expand Up @@ -79,8 +111,9 @@ Used with `.init()`, `.set()` or `.get()`
+ **images**: Images to be used. *Type:* String, Element or NodeList. *Default:* All images on page.
+ **changeParent**: Determines if classes are added to a target or to its parent. *Default:* false.
+ **threshold**: Midpoint between dark and light. *Default:* 50 (%).
+ **minComplexity**: Minimum image complexity required before the *complex* class is added to a target. *Default:* 30 (%).
+ **minOverlap**: Minimum overlap required between an element and any of the images for that element to be processed. *Default:* 50 (%).
+ **classes**: Classes added to targets. *Default:* `{ dark: 'background--dark', light: 'background--light' }`
+ **classes**: Classes added to targets. *Default:* `{ dark: 'background--dark', light: 'background--light', complex: 'background--complex' }`
+ **windowEvents**: Reprocess on window resize and scroll. *Default:* true.
+ **maxDuration**: Maximum processing time allowed. Killed if it takes longer. *Default:* 500 (ms).
+ **mask**: Used internally when checking if an element overlaps any of the images. *Default:* `{ r: 0, g: 255, b: 0 }`
Expand Down
50 changes: 34 additions & 16 deletions background-check.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* BackgroundCheck
* http://kennethcachia.com/background-check
*
* v1.0.0
* v1.1.0
*/

(function (root, factory) {
Expand Down Expand Up @@ -40,12 +40,17 @@
attrs.images = getElements(a.images || 'img');
attrs.changeParent = a.changeParent || false;
attrs.threshold = a.threshold || 50;
attrs.minComplexity = a.minComplexity || 30;
attrs.minOverlap = a.minOverlap || 50;
attrs.classes = a.classes || { dark: 'background--dark', light: 'background--light' };
attrs.windowEvents = a.windowEvents || true;
attrs.maxDuration = a.maxDuration || 500;
attrs.mask = a.mask || { r: 0, g: 255, b: 0 };
attrs.debug = a.debug || false;
attrs.classes = a.classes || {
dark: 'background--dark',
light: 'background--light',
complex: 'background--complex'
};

if (supported === undefined) {
checkSupport();
Expand Down Expand Up @@ -183,8 +188,9 @@
for (var t = 0; t < targets.length; t++) {
target = targets[t];
target = get('changeParent') ? target.parentNode : target;
target.className = target.className.replace(' ' + get('classes').light, '');
target.className = target.className.replace(' ' + get('classes').dark, '');
target.classList.remove(get('classes').light);
target.classList.remove(get('classes').dark);
target.classList.remove(get('classes').complex);
}
}

Expand All @@ -195,32 +201,44 @@
*/
function calculatePixelBrightness(target) {
var dims = target.getBoundingClientRect(),
pixels,
lum = 0,
brightness,
data,
pixels = 0,
delta,
deltaSqr = 0,
mean = 0,
variance,
minOverlap = 0,
mask = get('mask');

if (dims.width > 0 && dims.height > 0) {
removeClasses(target);

target = get('changeParent') ? target.parentNode : target;
pixels = context.getImageData(dims.left, dims.top, dims.width, dims.height).data;
data = context.getImageData(dims.left, dims.top, dims.width, dims.height).data;

for (var p = 0; p < pixels.length; p += 4) {
for (var p = 0; p < data.length; p += 4) {

if (pixels[p] === mask.r && pixels[p + 1] === mask.g && pixels[p + 2] === mask.b) {
if (data[p] === mask.r && data[p + 1] === mask.g && data[p + 2] === mask.b) {
minOverlap++;
} else {
pixels++;
brightness = (0.2126 * data[p]) + (0.7152 * data[p + 1]) + (0.0722 * data[p + 2]);
delta = brightness - mean;
deltaSqr += delta * delta;
mean = mean + delta / pixels;
}

lum += (0.2126 * pixels[p]) + (0.7152 * pixels[p + 1]) + (0.0722 * pixels[p + 2]);
}

pixels = ((pixels.length / 4) + 1);
lum = lum / pixels / 255;
if (minOverlap <= (data.length / 4) * (1 - (get('minOverlap') / 100))) {
variance = Math.sqrt(deltaSqr / pixels) / 255;
mean = mean / 255;
log('Target: ' + target.className + ' lum: ' + mean + ' var: ' + variance);
target.classList.add(mean <= (get('threshold') / 100) ? get('classes').dark : get('classes').light);

if (minOverlap <= pixels * (1 - (get('minOverlap') / 100))) {
log('Target: ' + target.className + ' lum: ' + lum);
target.className += ' ' + (lum <= (get('threshold') / 100) ? get('classes').dark : get('classes').light);
if (variance > get('minComplexity') / 100) {
target.classList.add(get('classes').complex);
}
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions background-check.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 1acd923

Please sign in to comment.