/* Philter v1.5.0 | (c) 2015-2018 Liudas Dzisevicius | MIT License */
(function() {
'use strict';
window.Philter = function() {
var defaults = {
transitionTime: 0.5,
tag: true
};
var sheet = document.createElement('style');
this.filterCount = {
'color': 0,
'duotone': 0,
'vintage-1': 0,
'vintage-2': 0,
'vintage-3': 0,
'vintage-4': 0,
'vintage-5': 0,
'vintage-6': 0
};
this.filters = [
'blur',
'grayscale',
'hue-rotate',
'saturate',
'sepia',
'contrast',
'invert',
'opacity',
'brightness',
'drop-shadow',
'svg',
'color',
'duotone',
'vintage'
];
this.elements = [];
this.styleString = '';
this.transitionString = '';
if (arguments[0] && typeof arguments[0] === "object") {
this.options = extendDefaults(defaults, arguments[0]);
} else {
this.options = defaults;
}
getElements.call(this);
parseElements.call(this);
this.styleString += this.transitionString + '{transition:filter ' + this.options.transitionTime + 's,-webkit-filter ' + this.options.transitionTime + 's;}#svg{height:0;}';
sheet.innerHTML = this.styleString;
document.head.appendChild(sheet);
}
function getElements() {
for (var i = 0; i < this.filters.length; i++) {
if (this.options.tag) {
var query = document.querySelectorAll('[data-philter-' + this.filters[i] + ']');
} else {
var query = document.querySelectorAll('[data-' + this.filters[i] + ']');
}
if (query) {
for (var j = 0; j < query.length; j++) {
if (this.elements.indexOf(query[j]) < 0) {
this.elements.push(query[j]);
}
}
}
}
}
function parseElements() {
var filterStrings = ['', ''];
var selector = '';
for (var i = 0; i < this.elements.length; i++) {
for (var j = 0; j < this.filters.length; j++) {
if (this.options.tag) {
var filter = this.elements[i].getAttribute('data-philter-' + this.filters[j] + '');
} else {
var filter = this.elements[i].getAttribute('data-' + this.filters[j] + '');
}
if (filter) {
if (this.options.tag) {
selector += '[data-philter-' + this.filters[j] + '="' + filter + '"]';
} else {
selector += '[data-' + this.filters[j] + '="' + filter + '"]';
}
filter = filter.split(' ');
filter.unshift(this.filters[j]);
filterStrings = getFilterString.call(this, filterStrings, filter, getUnits(filter[0]));
}
}
this.transitionString == '' ? this.transitionString += selector : this.transitionString += ',' + selector;
this.styleString += selector + '{filter:' + filterStrings[0] + ';-webkit-filter:' + filterStrings[0] + ';}';
if (filterStrings[0] != filterStrings[1]) {
this.styleString += selector + ':hover{filter:' + filterStrings[1] + ';-webkit-filter:' + filterStrings[1] + ';}';
}
filterStrings = ['', ''];
selector = '';
}
}
function getFilterString (filterStrings, filter, units) {
switch (filter[0]) {
case 'drop-shadow':
filterStrings[0] = filterStrings[0] + filter[0] + '(' + filter[1] + units + ' ' + filter[2] + units + ' ' + filter[3] + units + ' rgba(0,0,0,' + filter[4]*0.01 + ')) ';
if (filter[5] && filter[6] && filter[7] && filter[8]) {
filterStrings[1] = filterStrings[1] + filter[0] + '(' + filter[5] + units + ' ' + filter[6] + units + ' ' + filter[7] + units + ' rgba(0,0,0,' + filter[8]*0.01 + ')) ';
} else {
filterStrings[1] = filterStrings[1] + filter[0] + '(' + filter[1] + units + ' ' + filter[2] + units + ' ' + filter[3] + units + ' rgba(0,0,0,' + filter[4]*0.01 + ')) ';
}
break;
case 'svg':
filterStrings[0] = filterStrings[0] + 'url(' + units + filter[1] + ') ';
if (filter[2]) {
filterStrings[1] = filterStrings[1] + 'url(' + units + filter[2] + ') ';
} else {
filterStrings[1] = filterStrings[1] + 'url(' + units + filter[1] + ') ';
}
break;
case 'color':
++this.filterCount['color'];
createColorFilter.call(this, filter[1], filter[2], this.filterCount['color']);
filterStrings[0] = filterStrings[0] + 'url(' + units + 'color-' + this.filterCount['color'] + ') ';
if (filter[3] && filter[4]) {
++this.filterCount['color'];
createColorFilter.call(this, filter[3], filter[4], this.filterCount['color']);
filterStrings[1] = filterStrings[1] + 'url(' + units + 'color-' + this.filterCount['color'] + ') ';
} else {
filterStrings[1] = filterStrings[1] + 'url(' + units + 'color-' + this.filterCount['color'] + ') ';
}
break;
case 'duotone':
++this.filterCount['duotone'];
createDuotoneFilter.call(this, filter[1], filter[2], this.filterCount['duotone']);
filterStrings[0] = filterStrings[0] + 'url(' + units + 'duotone-' + this.filterCount['duotone'] + ') ';
if (filter[3] && filter[4]) {
++this.filterCount['duotone'];
createDuotoneFilter.call(this, filter[3], filter[4], this.filterCount['duotone']);
filterStrings[1] = filterStrings[1] + 'url(' + units + 'duotone-' + this.filterCount['duotone'] + ') ';
} else {
filterStrings[1] = filterStrings[1] + 'url(' + units + 'duotone-' + this.filterCount['duotone'] + ') ';
}
break;
case 'vintage':
if (this.filterCount['vintage-' + filter[1]] == 0) {
createVintageFilter.call(this, filter[1]);
}
++this.filterCount['vintage-' + filter[1]];
filterStrings[0] = filterStrings[0] + 'url(' + units + 'vintage-' + filter[1] + ') ';
if (filter[2]) {
if (this.filterCount['vintage-' + filter[2]] == 0) {
createVintageFilter.call(this, filter[2]);
}
++this.filterCount['vintage-' + filter[1]];
filterStrings[1] = filterStrings[1] + 'url(' + units + 'vintage-' + filter[2] + ') ';
} else {
filterStrings[1] = filterStrings[1] + 'url(' + units + 'vintage-' + filter[1] + ') ';
}
break;
default:
filterStrings[0] = filterStrings[0] + filter[0] + '(' + filter[1] + units + ') ';
if (filter[2]) {
filterStrings[1] = filterStrings[1] + filter[0] + '(' + filter[2] + units + ') ';
} else {
filterStrings[1] = filterStrings[1] + filter[0] + '(' + filter[1] + units + ') ';
}
}
return filterStrings;
}
function createColorFilter(color, opacity, id) {
var svg = document.getElementById('svg');
if (!svg) {
svg = document.createElement('div');
svg.setAttribute('id', 'svg');
svg.innerHTML = '';
document.body.appendChild(svg);
svg = document.getElementById('svg');
}
opacity = opacity * 0.01;
var data = '';
data = data.replace('color', 'color-' + id);
svg.querySelector('defs').innerHTML += data;
var flood = svg.querySelector('filter[id="color-' + id + '"]').children[0];
setAttributes(flood, { 'flood-opacity': opacity, 'flood-color': color });
}
function createDuotoneFilter(color1, color2, id) {
var svg = document.getElementById('svg');
if (!svg) {
svg = document.createElement('div');
svg.setAttribute('id', 'svg');
svg.innerHTML = '';
document.body.appendChild(svg);
svg = document.getElementById('svg');
}
color1 = rgb(color1);
color2 = rgb(color2);
var data = '';
data = data.replace('duotone', 'duotone-' + id);
svg.querySelector('defs').innerHTML += data;
var red = svg.querySelector('filter[id="duotone-' + id + '"] fefuncr');
setAttributes(red, { 'tableValues': color1.r/255+' '+color2.r/255 });
var green = svg.querySelector('filter[id="duotone-' + id + '"] fefuncg');
setAttributes(green, { 'tableValues': color1.g/255+' '+color2.g/255 });
var blue = svg.querySelector('filter[id="duotone-' + id + '"] fefuncb');
setAttributes(blue, { 'tableValues': color1.b/255+' '+color2.b/255 });
}
function createVintageFilter(type) {
var svg = document.getElementById('svg');
if (!svg) {
svg = document.createElement('div');
svg.setAttribute('id', 'svg');
svg.innerHTML = '';
document.body.appendChild(svg);
svg = document.getElementById('svg');
}
var data = '';
switch (type) {
case '1':
data = '';
break;
case '2':
data = '';
break;
case '3':
data = '';
break;
case '4':
data = '';
break;
case '5':
data = '';
break;
case '6':
data = '';
break;
}
svg.querySelector('defs').innerHTML += data;
}
function getUnits(filter) {
var units = {
'blur': 'px',
'hue-rotate': 'deg',
'drop-shadow': 'px',
'svg': '#',
'color': '#',
'vintage': '#',
'duotone': '#',
'default': '%'
};
if (units[filter]) {
return units[filter];
} else {
return units['default'];
}
}
function setAttributes(el, attrs) {
for(var key in attrs) {
el.setAttribute(key, attrs[key]);
}
}
function extendDefaults(source, properties) {
var property;
for (property in properties) {
if (properties.hasOwnProperty(property)) {
source[property] = properties[property];
}
}
return source;
}
function rgb(hex) {
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
}
}());