2015-05-28 12:47:00 +00:00
|
|
|
<?
|
|
|
|
|
2016-02-16 10:49:12 +00:00
|
|
|
$src = '../LICENSE-ICONS-3RD-PARTY.json';
|
|
|
|
|
2015-05-28 12:47:00 +00:00
|
|
|
// check for ajax request
|
|
|
|
if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
|
2016-02-16 10:49:12 +00:00
|
|
|
return file_put_contents($src, json_encode($_POST['list'], JSON_PRETTY_PRINT));
|
2015-05-28 12:47:00 +00:00
|
|
|
exit();
|
|
|
|
}
|
|
|
|
|
|
|
|
?>
|
2015-05-26 19:42:17 +00:00
|
|
|
<!doctype html>
|
|
|
|
<title>Zammad Icons</title>
|
|
|
|
<style>
|
|
|
|
html {
|
|
|
|
padding: 0 14px 14px 0;
|
|
|
|
}
|
|
|
|
body {
|
|
|
|
margin: 28px 28px 14px 14px;
|
|
|
|
background: hsl(210,14%,97%);
|
|
|
|
font-family: sans-serif;
|
|
|
|
font-size: 13px;
|
|
|
|
}
|
2016-02-16 10:49:12 +00:00
|
|
|
.controls {
|
|
|
|
border: 1px solid hsl(167,72%,60%);
|
|
|
|
border-radius: 5px;
|
|
|
|
margin: 0 0 28px 14px;
|
|
|
|
display: table;
|
|
|
|
box-shadow: 0 1px hsl(199,44%,96%);
|
|
|
|
}
|
|
|
|
.controls label {
|
|
|
|
padding: 7px 10px;
|
|
|
|
float: left;
|
|
|
|
cursor: pointer;
|
|
|
|
}
|
|
|
|
.controls label:not(:last-child) {
|
|
|
|
border-right: 1px solid hsl(167,72%,60%);
|
|
|
|
}
|
|
|
|
.controls input {
|
|
|
|
display: none;
|
|
|
|
}
|
|
|
|
.controls input:checked + label {
|
|
|
|
background: hsl(167,72%,60%);
|
|
|
|
color: white;
|
|
|
|
}
|
|
|
|
.icons {
|
|
|
|
display: flex;
|
|
|
|
flex-wrap: wrap;
|
|
|
|
}
|
2015-05-26 19:42:17 +00:00
|
|
|
.icon-holder {
|
|
|
|
border: 1px solid hsl(199,44%,93%);
|
|
|
|
background: white;
|
|
|
|
box-shadow: 0 2px hsl(210,7%,96%);
|
|
|
|
margin: 0 0 14px 14px;
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
align-items: center;
|
|
|
|
justify-content: center;
|
2016-02-16 10:49:12 +00:00
|
|
|
flex: 1;
|
|
|
|
}
|
|
|
|
.icon-holder.is-filtered {
|
|
|
|
display: none;
|
2015-05-26 19:42:17 +00:00
|
|
|
}
|
|
|
|
.icon {
|
|
|
|
position: relative;
|
|
|
|
padding: 14px;
|
|
|
|
width: 100%;
|
|
|
|
box-sizing: border-box;
|
|
|
|
display: flex;
|
|
|
|
justify-content: center;
|
2015-05-27 07:54:27 +00:00
|
|
|
background: hsl(210,14%,98%);
|
|
|
|
}
|
|
|
|
.icon.is-light {
|
|
|
|
background: hsl(210,14%,88%);
|
2015-05-26 19:42:17 +00:00
|
|
|
}
|
|
|
|
.icon svg {
|
|
|
|
width: 128px;
|
|
|
|
height: 128px;
|
|
|
|
position: relative;
|
|
|
|
}
|
|
|
|
.icon-body {
|
2016-02-16 10:49:12 +00:00
|
|
|
padding: 14px 14px 10px;
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
justify-content: center;
|
2015-05-26 19:42:17 +00:00
|
|
|
}
|
|
|
|
.icon-name {
|
|
|
|
margin: 0 0 7px;
|
|
|
|
white-space: nowrap;
|
|
|
|
}
|
2016-02-16 10:49:12 +00:00
|
|
|
input:not([type=radio]) {
|
|
|
|
margin: 0 0 4px;
|
2015-05-26 19:42:17 +00:00
|
|
|
font: inherit;
|
|
|
|
border: 1px solid #ddd;
|
|
|
|
padding: 3px 5px;
|
|
|
|
}
|
2016-02-16 10:49:12 +00:00
|
|
|
input:not([type=radio]):focus {
|
2015-05-26 19:42:17 +00:00
|
|
|
outline: none;
|
|
|
|
border-color: hsl(205,74%,61%);
|
|
|
|
}
|
2015-05-27 07:54:27 +00:00
|
|
|
/*.icon:before {
|
2015-05-26 19:42:17 +00:00
|
|
|
content: "";
|
|
|
|
position: absolute;
|
|
|
|
left: 0;
|
|
|
|
top: 0;
|
|
|
|
width: 100%;
|
|
|
|
height: 100%;
|
|
|
|
background-image:
|
|
|
|
linear-gradient(45deg, black 25%, transparent 25%, transparent 75%, black 75%, black),
|
|
|
|
linear-gradient(45deg, black 25%, transparent 25%, transparent 75%, black 75%, black);
|
|
|
|
background-size: 20px 20px;
|
|
|
|
background-position: 10px 10px, 40px 40px;
|
|
|
|
opacity: 0.3;
|
2015-05-27 07:54:27 +00:00
|
|
|
}*/
|
2015-05-26 19:42:17 +00:00
|
|
|
</style>
|
|
|
|
|
2016-02-16 10:49:12 +00:00
|
|
|
<div class="controls">
|
|
|
|
<input type="radio" value="off" name="filter" checked id="off"><label for="off">No Filter</label>
|
|
|
|
<input type="radio" value="empty_author" name="filter" id="author"><label for="author">No Author</label>
|
|
|
|
<input type="radio" value="empty_license" name="filter" id="license"><label for="license">No License</label>
|
|
|
|
</div>
|
|
|
|
<div class="icons">
|
2015-05-26 19:42:17 +00:00
|
|
|
<?
|
|
|
|
|
|
|
|
# Path to image folder
|
2016-02-16 10:49:12 +00:00
|
|
|
$imageFolder = '../public/assets/images/icons/';
|
2015-05-26 19:42:17 +00:00
|
|
|
|
|
|
|
# Show only these file types from the image folder
|
|
|
|
$imageTypes = '{*.svg}';
|
|
|
|
|
|
|
|
# Set to true if you prefer sorting images by name
|
|
|
|
# If set to false, images will be sorted by date
|
2016-02-16 10:49:12 +00:00
|
|
|
$sortByImageName = false;
|
2015-05-26 19:42:17 +00:00
|
|
|
|
|
|
|
# Set to false if you want the oldest images to appear first
|
|
|
|
# This is only used if images are sorted by date (see above)
|
|
|
|
$newestImagesFirst = true;
|
|
|
|
|
|
|
|
# The rest of the code is technical
|
|
|
|
|
|
|
|
# Add images to array
|
|
|
|
$images = glob($imageFolder . $imageTypes, GLOB_BRACE);
|
|
|
|
|
2016-02-16 10:49:12 +00:00
|
|
|
$author_data = json_decode(file_get_contents($src), true);
|
2015-05-26 19:42:17 +00:00
|
|
|
|
|
|
|
# Sort images
|
|
|
|
if ($sortByImageName) {
|
|
|
|
$sortedImages = $images;
|
|
|
|
natsort($sortedImages);
|
|
|
|
} else {
|
|
|
|
# Sort the images based on its 'last modified' time stamp
|
|
|
|
$sortedImages = array();
|
|
|
|
$count = count($images);
|
|
|
|
for ($i = 0; $i < $count; $i++) {
|
|
|
|
$sortedImages[date('YmdHis', filemtime($images[$i])) . $i] = $images[$i];
|
|
|
|
}
|
|
|
|
# Sort images in array
|
|
|
|
if ($newestImagesFirst) {
|
|
|
|
krsort($sortedImages);
|
|
|
|
} else {
|
|
|
|
ksort($sortedImages);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
?>
|
|
|
|
|
|
|
|
<? foreach ($sortedImages as $image): ?>
|
|
|
|
<?
|
|
|
|
# Get the name of the image, stripped from image folder path and file type extension
|
|
|
|
$filename = basename($image);
|
|
|
|
$name = preg_replace('/\\.[^.\\s]{3,4}$/', '', $filename);
|
|
|
|
|
|
|
|
# Begin adding
|
|
|
|
?>
|
|
|
|
<div class="icon-holder">
|
|
|
|
<div class="icon">
|
|
|
|
<?= file_get_contents($image) ?>
|
|
|
|
</div>
|
2016-02-16 10:49:12 +00:00
|
|
|
<form class="icon-body" data-filename="<?= $filename ?>">
|
2015-05-26 19:42:17 +00:00
|
|
|
<div class="icon-name"><?= $name ?></div>
|
2016-02-16 10:49:12 +00:00
|
|
|
<input name="author" value="<?= $author_data[$filename]['author'] ?>" placeholder="Author">
|
|
|
|
<input type="url" name="url" value="<?= $author_data[$filename]['url'] ?>" placeholder="URL">
|
|
|
|
<input name="license" value="<?= $author_data[$filename]['license'] ?>" placeholder="License">
|
|
|
|
</form>
|
2015-05-26 19:42:17 +00:00
|
|
|
</div>
|
|
|
|
<? endforeach ?>
|
2016-02-16 10:49:12 +00:00
|
|
|
</div>
|
2015-05-26 19:42:17 +00:00
|
|
|
|
2016-02-16 10:49:12 +00:00
|
|
|
<script src="../app/assets/javascripts/app/lib/core/jquery-2.1.4.js"></script>
|
2015-05-26 19:42:17 +00:00
|
|
|
<script>
|
2016-02-16 10:49:12 +00:00
|
|
|
var self = "<?= basename($_SERVER["SCRIPT_FILENAME"]) ?>"
|
|
|
|
var filter = "off"
|
|
|
|
var filterTimeout
|
|
|
|
|
|
|
|
$('input').on({
|
|
|
|
input: storeAuthors,
|
|
|
|
blur: onBlur,
|
|
|
|
focus: onFocus
|
|
|
|
})
|
|
|
|
|
|
|
|
function onBlur(){
|
|
|
|
filterTimeout = setTimeout(applyFilter, 500)
|
|
|
|
}
|
|
|
|
|
|
|
|
function onFocus(){
|
|
|
|
clearTimeout(filterTimeout)
|
|
|
|
}
|
2015-05-28 12:47:00 +00:00
|
|
|
|
|
|
|
function storeAuthors(){
|
2015-05-26 19:42:17 +00:00
|
|
|
var iconList = {}
|
|
|
|
|
2016-02-16 10:49:12 +00:00
|
|
|
$('.icon-holder form').each(function(){
|
|
|
|
iconList[$(this).attr('data-filename')] = {
|
|
|
|
author: this.elements.author.value,
|
|
|
|
url: this.elements.url.value,
|
|
|
|
license: this.elements.license.value
|
|
|
|
}
|
2015-05-26 19:42:17 +00:00
|
|
|
})
|
|
|
|
|
2016-02-16 10:49:12 +00:00
|
|
|
$.post(self, { list: iconList }, function(data){ console.log(data) })
|
|
|
|
}
|
|
|
|
|
|
|
|
$('[name="filter"]').change(function(){
|
|
|
|
filter = this.value
|
|
|
|
applyFilter()
|
|
|
|
})
|
|
|
|
|
|
|
|
function applyFilter(){
|
|
|
|
$('.icon-holder').removeClass('is-filtered').each(function(){
|
|
|
|
var holder = $(this)
|
|
|
|
|
|
|
|
switch(filter){
|
|
|
|
case "empty_author":
|
|
|
|
if(holder.find("[name='author']").val())
|
|
|
|
holder.addClass('is-filtered')
|
|
|
|
break;
|
|
|
|
case "empty_license":
|
|
|
|
if(holder.find("[name='license']").val())
|
|
|
|
holder.addClass('is-filtered')
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
});
|
2015-05-28 12:47:00 +00:00
|
|
|
}
|
2015-05-27 07:54:27 +00:00
|
|
|
|
|
|
|
$('svg').each(function(i, svg){
|
|
|
|
var areas = []
|
|
|
|
var svgBoundingBox = svg.getBoundingClientRect()
|
|
|
|
var svgArea = svgBoundingBox.width * svgBoundingBox.height
|
|
|
|
|
|
|
|
$(svg).find('*').each(function(i, el){
|
|
|
|
var fill = $(el).attr('fill')
|
|
|
|
if(fill && fill != 'none'){
|
|
|
|
var childBoundingBox = el.getBoundingClientRect()
|
|
|
|
areas.push({
|
|
|
|
luminance: getLuminance(fill),
|
|
|
|
areaPercentage: (childBoundingBox.width * childBoundingBox.height)/svgArea
|
|
|
|
})
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
if(!areas.length)
|
|
|
|
return
|
|
|
|
|
|
|
|
var averageLuminance = areas.reduce(function(previousValue, currentValue, index, array){
|
|
|
|
if(array.length == 1)
|
|
|
|
return currentValue.luminance
|
|
|
|
else
|
|
|
|
return previousValue + currentValue.luminance * currentValue.areaPercentage
|
|
|
|
}, 0)
|
|
|
|
|
|
|
|
if(averageLuminance > 220){
|
|
|
|
$(svg).parent().addClass('is-light')
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
//
|
|
|
|
// from http://stackoverflow.com/questions/12043187/how-to-check-if-hex-color-is-too-black
|
|
|
|
//
|
|
|
|
function getLuminance(hex){
|
|
|
|
var c = hex.substring(1); // strip #
|
|
|
|
var rgb = parseInt(c, 16); // convert rrggbb to decimal
|
|
|
|
var r = (rgb >> 16) & 0xff; // extract red
|
|
|
|
var g = (rgb >> 8) & 0xff; // extract green
|
|
|
|
var b = (rgb >> 0) & 0xff; // extract blue
|
|
|
|
|
|
|
|
return 0.2126 * r + 0.7152 * g + 0.0722 * b; // per ITU-R BT.709
|
|
|
|
}
|
2015-05-26 19:42:17 +00:00
|
|
|
</script>
|