Reputation: 844
I would like to mod the JavaScript below to select by class name
, rather than element id
:
https://github.com/sarathsaleem/grained/blob/master/grained.js
and then ideally initialize, like so:
grained(".classname", options);
Upvotes: 0
Views: 547
Reputation: 1595
This modified version of Sarath Saleem's grained.js gets all elements with a given class name selector (i.e. '.foo') and gives them the specified noise background. I have not tested this code very much, so it is definitely not production quality in terms of efficiency. The key is just to change the element
variable to elements
and use document.getElementsByClassName
where the, newly named, elements
variable is defined. This will return an HTMLCollection of all the HTML elements with the given class (i.e. 'foo'). Then, in the part where the element's position
and overflow
attributes are set, use a for loop and iterate through the HTMLCollection to set the position
and overflow
attributes for each of the found elements with the given class.
Note: At the bottom of the grained.js file is where I call the grained function.
Also, I adjusted the places that used, previously named, elementId
variable to use a new elementClass
variable that is based off the given class name.
You can do this anywhere after the grained.js iife as it is in the global namespace after that.
/*! Grained.js
* Author : Sarath Saleem - https://github.com/sarathsaleem
* MIT license: http://opensource.org/licenses/MIT
* GitHub : https://github.com/sarathsaleem/grained
* v0.0.1
*/
(function (window, doc) {
"use strict";
function grained(ele, opt) {
var elements = null,
elementClass = null,
selectorElement = null;
//1
if (typeof ele === 'string') {
elements = doc.getElementsByClassName(ele.split('.')[1]);
}
//1
if (!elements) {
console.error('Grained: cannot find any elements with class ' + ele);
return;
} else {
elementClass = elements[0].className;
}
var elementsLength = elements.length
for( var i = 0; i < elementsLength; i++) {
//set style for parent
if (elements[i].style.position !== 'absolute') {
elements[i].style.position = 'relative';
}
elements[i].style.overflow = 'hidden';
};
var prefixes = ["", "-moz-", "-o-animation-", "-webkit-", "-ms-"];
//default option values
var options = {
animate: true,
patternWidth: 100,
patternHeight: 100,
grainOpacity: 0.1,
grainDensity: 1,
grainWidth: 1,
grainHeight: 1,
grainChaos: 0.5,
grainSpeed: 20
};
Object.keys(opt).forEach(function (key) {
options[key] = opt[key];
});
var generateNoise = function () {
var canvas = doc.createElement('canvas');
var ctx = canvas.getContext('2d');
canvas.width = options.patternWidth;
canvas.height = options.patternHeight;
for (var w = 0; w < options.patternWidth; w += options.grainDensity) {
for (var h = 0; h < options.patternHeight; h += options.grainDensity) {
var rgb = Math.random() * 256 | 0;
ctx.fillStyle = 'rgba(' + [rgb, rgb, rgb, options.grainOpacity].join() + ')';
ctx.fillRect(w, h, options.grainWidth, options.grainHeight);
}
}
return canvas.toDataURL('image/png');
};
function addCSSRule(sheet, selector, rules, index) {
var ins = '';
if (selector.length) {
ins = selector + "{" + rules + "}";
} else {
ins = rules;
}
if ("insertRule" in sheet) {
sheet.insertRule(ins, index);
} else if ("addRule" in sheet) {
sheet.addRule(selector, rules, index);
}
}
var noise = generateNoise();
var animation = '',
keyFrames = ['0%:-10%,10%', '10%:-25%,0%', '20%:-30%,10%', '30%:-30%,30%', '40%::-20%,20%', '50%:-15%,10%', '60%:-20%,20%', '70%:-5%,20%', '80%:-25%,5%', '90%:-30%,25%', '100%:-10%,10%'];
var pre = prefixes.length;
while (pre--) {
animation += '@' + prefixes[pre] + 'keyframes grained{';
for (var key = 0; key < keyFrames.length; key++) {
var keyVal = keyFrames[key].split(':');
animation += keyVal[0] + '{';
animation += prefixes[pre] + 'transform:translate(' + keyVal[1] + ');';
animation += '}';
}
animation += '}';
}
//add animation keyframe
var animationAdded = doc.getElementById('grained-animation');
if (animationAdded) {
animationAdded.parentElement.removeChild(animationAdded);
}
var style = doc.createElement("style");
style.type = "text/css";
style.id = 'grained-animation';
style.innerHTML = animation;
doc.body.appendChild(style);
//add custimozed style
var styleAdded = doc.getElementById('grained-animation-' + elementClass);
if (styleAdded) {
styleAdded.parentElement.removeChild(styleAdded);
}
style = doc.createElement("style");
style.type = "text/css";
style.id = 'grained-animation-' + elementClass;
doc.body.appendChild(style);
var rule = 'background-image: url(' + noise + ');';
rule += 'position: absolute;content: "";height: 300%;width: 300%;left: -100%;top: -100%;';
pre = prefixes.length;
if (options.animate) {
while (pre--) {
rule += prefixes[pre] + 'animation-name:grained;';
rule += prefixes[pre] + 'animation-iteration-count: infinite;';
rule += prefixes[pre] + 'animation-duration: ' + options.grainChaos + 's;';
rule += prefixes[pre] + 'animation-timing-function: steps(' +options.grainSpeed + ', end);';
}
}
//selecter element to add grains
selectorElement = '.' + elementClass + '::before';
addCSSRule(style.sheet, selectorElement, rule, 0);
}
window.grained = grained;
//END
})(window, document);
grained('.foo', {});
<!doctype html>
<html>
<head>
<title>Example</title>
<style>
.foo {
height: 100px;
width: 100px;
}
</style>
</head>
<body>
<div class="foo">
<div class="contents">
<p>Hello World</p>
</div>
</div>
<p>No Noise For Me!</p>
<div class="foo">
<div class="contents">
<p>Hello World</p>
</div>
</div>
<script type="text/javascript" src="grained.js"></script>
<script type="text/javascript" src="index.js"></script>
</body>
</html>
Hope this helps! If you have any questions, please ask! I like to help :D.
Upvotes: 1