Skip to content

Commit 1acd923

Browse files
committed
Additional class for complex backgrounds.
1 parent 1c0fef9 commit 1acd923

File tree

5 files changed

+73
-22
lines changed

5 files changed

+73
-22
lines changed

README.md

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,38 @@ p.background--light {
2828

2929
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.
3030

31+
###Complex backgrounds
32+
33+
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.
34+
35+
This class can be used as an intermediate state:
36+
37+
```css
38+
p.background--light {
39+
color: black;
40+
}
41+
42+
p.background--dark {
43+
color: white;
44+
}
45+
46+
p.background--complex {
47+
color: gray;
48+
}
49+
```
50+
51+
or:
52+
53+
```css
54+
p.background--dark.background--complex {
55+
color: #ccc;
56+
}
57+
58+
p.background--light.background--complex {
59+
color: #aaa;
60+
}
61+
```
62+
3163
##How to use
3264

3365
**Initialize**
@@ -79,8 +111,9 @@ Used with `.init()`, `.set()` or `.get()`
79111
+ **images**: Images to be used. *Type:* String, Element or NodeList. *Default:* All images on page.
80112
+ **changeParent**: Determines if classes are added to a target or to its parent. *Default:* false.
81113
+ **threshold**: Midpoint between dark and light. *Default:* 50 (%).
114+
+ **minComplexity**: Minimum image complexity required before the *complex* class is added to a target. *Default:* 30 (%).
82115
+ **minOverlap**: Minimum overlap required between an element and any of the images for that element to be processed. *Default:* 50 (%).
83-
+ **classes**: Classes added to targets. *Default:* `{ dark: 'background--dark', light: 'background--light' }`
116+
+ **classes**: Classes added to targets. *Default:* `{ dark: 'background--dark', light: 'background--light', complex: 'background--complex' }`
84117
+ **windowEvents**: Reprocess on window resize and scroll. *Default:* true.
85118
+ **maxDuration**: Maximum processing time allowed. Killed if it takes longer. *Default:* 500 (ms).
86119
+ **mask**: Used internally when checking if an element overlaps any of the images. *Default:* `{ r: 0, g: 255, b: 0 }`

background-check.js

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* BackgroundCheck
44
* http://kennethcachia.com/background-check
55
*
6-
* v1.0.0
6+
* v1.1.0
77
*/
88

99
(function (root, factory) {
@@ -40,12 +40,17 @@
4040
attrs.images = getElements(a.images || 'img');
4141
attrs.changeParent = a.changeParent || false;
4242
attrs.threshold = a.threshold || 50;
43+
attrs.minComplexity = a.minComplexity || 30;
4344
attrs.minOverlap = a.minOverlap || 50;
44-
attrs.classes = a.classes || { dark: 'background--dark', light: 'background--light' };
4545
attrs.windowEvents = a.windowEvents || true;
4646
attrs.maxDuration = a.maxDuration || 500;
4747
attrs.mask = a.mask || { r: 0, g: 255, b: 0 };
4848
attrs.debug = a.debug || false;
49+
attrs.classes = a.classes || {
50+
dark: 'background--dark',
51+
light: 'background--light',
52+
complex: 'background--complex'
53+
};
4954

5055
if (supported === undefined) {
5156
checkSupport();
@@ -183,8 +188,9 @@
183188
for (var t = 0; t < targets.length; t++) {
184189
target = targets[t];
185190
target = get('changeParent') ? target.parentNode : target;
186-
target.className = target.className.replace(' ' + get('classes').light, '');
187-
target.className = target.className.replace(' ' + get('classes').dark, '');
191+
target.classList.remove(get('classes').light);
192+
target.classList.remove(get('classes').dark);
193+
target.classList.remove(get('classes').complex);
188194
}
189195
}
190196

@@ -195,32 +201,44 @@
195201
*/
196202
function calculatePixelBrightness(target) {
197203
var dims = target.getBoundingClientRect(),
198-
pixels,
199-
lum = 0,
204+
brightness,
205+
data,
206+
pixels = 0,
207+
delta,
208+
deltaSqr = 0,
209+
mean = 0,
210+
variance,
200211
minOverlap = 0,
201212
mask = get('mask');
202213

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

206217
target = get('changeParent') ? target.parentNode : target;
207-
pixels = context.getImageData(dims.left, dims.top, dims.width, dims.height).data;
218+
data = context.getImageData(dims.left, dims.top, dims.width, dims.height).data;
208219

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

211-
if (pixels[p] === mask.r && pixels[p + 1] === mask.g && pixels[p + 2] === mask.b) {
222+
if (data[p] === mask.r && data[p + 1] === mask.g && data[p + 2] === mask.b) {
212223
minOverlap++;
224+
} else {
225+
pixels++;
226+
brightness = (0.2126 * data[p]) + (0.7152 * data[p + 1]) + (0.0722 * data[p + 2]);
227+
delta = brightness - mean;
228+
deltaSqr += delta * delta;
229+
mean = mean + delta / pixels;
213230
}
214-
215-
lum += (0.2126 * pixels[p]) + (0.7152 * pixels[p + 1]) + (0.0722 * pixels[p + 2]);
216231
}
217232

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

221-
if (minOverlap <= pixels * (1 - (get('minOverlap') / 100))) {
222-
log('Target: ' + target.className + ' lum: ' + lum);
223-
target.className += ' ' + (lum <= (get('threshold') / 100) ? get('classes').dark : get('classes').light);
239+
if (variance > get('minComplexity') / 100) {
240+
target.classList.add(get('classes').complex);
241+
}
224242
}
225243
}
226244
}

background-check.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)