Switch to webpack build

This commit is contained in:
Florian Gauger
2018-06-30 12:59:25 +02:00
parent ed8a775ead
commit 37116f9c30
30 changed files with 8068 additions and 2354 deletions
-24
View File
@@ -1,24 +0,0 @@
parserOptions:
ecmaVersion: 6
extends:
- eslint:recommended
- google
rules:
no-console: 0
max-len:
- 2
- 120
env:
browser: true
jquery: true
globals:
g: true
icons: true
tinysort: true
canvasToFavicon: true
saveAs: true
Fuse: true
+2
View File
@@ -1,2 +1,4 @@
.DS_Store
.idea/
node_modules
dist
+5
View File
@@ -0,0 +1,5 @@
{
"printWidth": 120,
"singleQuote": true,
"trailingComma": all,
}
-1
View File
File diff suppressed because one or more lines are too long
-251
View File
@@ -1,251 +0,0 @@
$(window).on('load', function() {
var $color = $("#color");
var $color_text = $("#color_text");
var $background_color = $("#background_color");
var $background_color_text = $("#background_color_text");
var $search = $("#search");
var $right = $('#right');
var $size = $("#size");
var $download = $("#download");
var $stackedLabel = $("#stacked_label");
var $stackedSize = $("#stacked_size");
var $downloadIframe = $("#download_iframe");
var $fileFormatText = $("#file_format_text");
var createFaviconUrl = "https://fonticon-207412.appspot.com/";
var loading = false;
var symbol = "\uf004";
var symbolStyle = "s";
var stackedSelected = false;
var stackedSymbol = "\uf004";
var stackedSymbolStyle = "s";
var canvas = document.getElementById('canvas');
var sideLength = 1024;
canvas.width = sideLength;
canvas.height = sideLength;
var ctx = canvas.getContext('2d');
ctx.textAlign = "center";
ctx.textBaseline = "middle";
initialize();
function initialize() {
$size.on("input", draw);
$stackedSize.on("input", draw);
$color_text.on("input", updateColor.bind(updateColor, $color, $color_text,
false, true));
$background_color_text.on(
"input", updateColor.bind(updateColor, $background_color,
$background_color_text, false, true));
$color.spectrum({
color : "#ff3860",
showButtons : false,
showAlpha : true,
move : updateColor.bind(updateColor, $color, $color_text, true, true)
});
$background_color.spectrum({
color : "rgba(255,255,255,0)",
showButtons : false,
showAlpha : true,
move : updateColor.bind(updateColor, $background_color,
$background_color_text, true, true)
});
updateColor($color, $color_text, false, false);
updateColor($background_color, $background_color_text, false, false);
initSearch($search, $right);
function loadingFinished() {
loading = false;
$download.removeClass("loading");
}
function iconCreationError(errorMessage) { console.error(errorMessage); }
$download.on("click", function() {
if (!loading) {
loading = true;
$download.addClass("loading");
if ($fileFormatText.text() == ".ico") {
var iconData = canvas.toDataURL().split(',')[1];
$.ajax({
type : "POST",
url : createFaviconUrl,
data : iconData,
success : function(response) {
if (response.status == "error") {
iconCreationError(response.error_message);
} else {
$downloadIframe.attr('src', response.url);
}
},
error : function(jqXHR, textStatus,
errorMessage) { iconCreationError(errorMessage); },
complete : loadingFinished
})
} else {
canvas.toBlob(function(blob) {
saveAs(blob, "favicon.png");
loadingFinished();
});
}
}
});
$("#stacked").click(function() {
stackedSelected = this.checked;
this.checked ? $stackedSize.show() : $stackedSize.hide();
draw();
});
$.each(icons, function(index, icon) {
var $iconOuter = $("<div>").addClass("icon_outer").data("id", icon.id);
var iconStyle;
switch (icon.style) {
case 'solid':
iconStyle = 's';
break;
case 'regular':
iconStyle = 'r';
break;
default:
console.error('Unkown icon style.');
}
var styleClass = "fa" + iconStyle + " fa-" + icon.id;
var $icon = $("<div>")
.addClass("icon hover")
.data('style', iconStyle)
.data('unicode', icon.unicode)
.append($('<i>').addClass(styleClass));
$icon.append($("<div>").addClass("icon_text underline").text(icon.id));
$iconOuter.append($icon);
$right.append($iconOuter);
});
$(".icon").on("click touchstart", function() {
var selectedSymbol = $(this).data('unicode');
var selectedSymbolStyle = $(this).data('style');
if (stackedSelected) {
stackedSymbol = selectedSymbol;
stackedSymbolStyle = selectedSymbolStyle;
} else {
symbol = selectedSymbol;
symbolStyle = selectedSymbolStyle;
}
draw();
});
$("#file_format").on("click", function() {
new_format = ".ico";
if ($fileFormatText.text() == ".ico") {
new_format = ".png";
}
$fileFormatText.text(new_format);
});
setTimeout(draw, 1000);
}
function initSearch($search, $right) {
var options = {
id : "id",
shouldSort : true,
threshold : 0.3,
location : 0,
distance : 100,
maxPatternLength : 32,
minMatchCharLength : 1,
keys : [ "id", "name", "search_terms" ]
};
var fuse = new Fuse(icons, options);
$search.on("input", function() {
var query = $search.get(0).value;
var result = fuse.search(query);
$right.children().hide();
$right.children()
.filter(function(index, element) {
return query == "" || result.indexOf($(element).data("id")) != -1;
})
.show();
if (result.length == 0 && query != "") {
tinysort($right.children());
} else if (result.length > 0) {
tinysort($right.children(), {
sortFunction : function(a, b) {
return result.indexOf($(a.elm).data("id")) -
result.indexOf($(b.elm).data("id"));
}
});
}
})
}
function updateColor($color, $color_text, fromPicker, doDraw) {
if (!fromPicker) {
$color.spectrum("set", $color_text.val());
}
var rgba = colorToRgba($color.spectrum("get"));
$color.css("background-color", rgba);
if (fromPicker) {
$color_text.val(rgba);
}
if (doDraw) {
draw();
}
}
function colorToRgba(color) {
return "rgba(" + color.toRgb().r + ", " + color.toRgb().g + ", " +
color.toRgb().b + ", " + color.toRgb().a + ")";
}
function draw() {
if (sideLength > 0) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = $background_color_text.val();
ctx.fillRect(0, 0, canvas.width, canvas.height);
setFontSize(symbol, symbolStyle, $size);
ctx.fillStyle = "rgba(0, 0, 0, 1)";
ctx.globalCompositeOperation = "destination-out";
ctx.fillText(symbol, sideLength / 2, sideLength / 2);
ctx.fillStyle = $color_text.val();
ctx.globalCompositeOperation = "source-over";
ctx.fillText(symbol, sideLength / 2, sideLength / 2);
if (stackedSelected && stackedSymbol) {
ctx.save();
setFontSize(stackedSymbol, stackedSymbolStyle, $stackedSize);
ctx.globalCompositeOperation = "xor";
ctx.fillText(stackedSymbol, sideLength / 2, sideLength / 2);
ctx.restore();
}
canvasToFavicon(canvas);
}
}
function getFont(symbolStyle, pixelSize) {
var font = pixelSize + 'px "Font Awesome 5 Free"';
var fontWeight = 0;
switch (symbolStyle) {
case 's':
fontWeight = 900;
break;
case 'r':
fontWeight = 400;
break;
default:
console.error('Unkown icon style.');
}
return fontWeight + ' ' + font;
}
function setFontSize(symbol, symbolStyle, $size) {
var i = sideLength;
do {
ctx.font = getFont(symbolStyle, i);
i--;
} while (ctx.measureText(symbol).width > sideLength);
ctx.font = getFont(symbolStyle, i * $size.val() / 100);
}
});
-131
View File
@@ -1,131 +0,0 @@
/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js
*/
var saveAs =
saveAs ||
function(e) {
"use strict";
if (typeof e === "undefined" ||
typeof navigator !== "undefined" &&
/MSIE [1-9]\./.test(navigator.userAgent)) {
return
}
var t = e.document, n = function() { return e.URL || e.webkitURL || e },
r = t.createElementNS("http://www.w3.org/1999/xhtml", "a"),
o = "download" in r,
i =
function(e) {
var t = new MouseEvent("click");
e.dispatchEvent(t)
},
a = /constructor/i.test(e.HTMLElement),
f = /CriOS\/[\d]+/.test(navigator.userAgent), u = function(t) {
(e.setImmediate || e.setTimeout)(function() { throw t }, 0)
}, d = "application/octet-stream", s = 1e3 * 40, c = function(e) {
var t = function() {
if (typeof e === "string") {
n().revokeObjectURL(e)
} else {
e.remove()
}
};
setTimeout(t, s)
}, l = function(e, t, n) {
t = [].concat(t);
var r = t.length;
while (r--) {
var o = e["on" + t[r]];
if (typeof o === "function") {
try {
o.call(e, n || e)
} catch (i) {
u(i)
}
}
}
}, p = function(e) {
if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i
.test(e.type)) {
return new Blob([ String.fromCharCode(65279), e ],
{type : e.type})
}
return e
}, v = function(t, u, s) {
if (!s) {
t = p(t)
}
var v = this, w = t.type, m = w === d, y, h = function() {
l(v, "writestart progress write writeend".split(" "))
}, S = function() {
if ((f || m && a) && e.FileReader) {
var r = new FileReader;
r.onloadend = function() {
var t = f ? r.result
: r.result.replace(/^data:[^;]*;/,
"data:attachment/file;");
var n = e.open(t, "_blank");
if (!n)
e.location.href = t;
t = undefined;
v.readyState = v.DONE;
h()
};
r.readAsDataURL(t);
v.readyState = v.INIT;
return
}
if (!y) {
y = n().createObjectURL(t)
}
if (m) {
e.location.href = y
} else {
var o = e.open(y, "_blank");
if (!o) {
e.location.href = y
}
}
v.readyState = v.DONE;
h();
c(y)
};
v.readyState = v.INIT;
if (o) {
y = n().createObjectURL(t);
setTimeout(function() {
r.href = y;
r.download = u;
i(r);
h();
c(y);
v.readyState = v.DONE
});
return
}
S()
}, w = v.prototype, m = function(e, t, n) {
return new v(e, t || e.name || "download", n)
};
if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) {
return function(e, t, n) {
t = t || e.name || "download";
if (!n) {
e = p(e)
}
return navigator.msSaveOrOpenBlob(e, t)
}
}
w.abort = function() {};
w.readyState = w.INIT = 0;
w.WRITING = 1;
w.DONE = 2;
w.error = w.onwritestart = w.onprogress = w.onwrite = w.onabort =
w.onerror = w.onwriteend = null;
return m
}(typeof self !== "undefined" && self ||
typeof window !== "undefined" && window || this.content);
if (typeof module !== "undefined" && module.exports) {
module.exports.saveAs = saveAs
} else if (typeof define !== "undefined" && define !== null &&
define.amd !== null) {
define([], function() { return saveAs })
}
-50
View File
@@ -1,50 +0,0 @@
!function(t) {
"use strict";
var e = t.HTMLCanvasElement && t.HTMLCanvasElement.prototype,
o = t.Blob &&
function() {
try {
return Boolean(new Blob)
} catch (t) {
return !1
}
}(),
n = o && t.Uint8Array &&
function() {
try {
return 100 === new Blob([ new Uint8Array(100) ]).size
} catch (t) {
return !1
}
}(),
r = t.BlobBuilder || t.WebKitBlobBuilder || t.MozBlobBuilder ||
t.MSBlobBuilder,
a = /^data:((.*?)(;charset=.*?)?)(;base64)?,/,
i = (o || r) && t.atob && t.ArrayBuffer && t.Uint8Array && function(t) {
var e, i, l, u, b, c, d, B, f;
if (e = t.match(a), !e)
throw new Error("invalid data URI");
for (i = e[2] ? e[1] : "text/plain" + (e[3] || ";charset=US-ASCII"),
l = !!e[4], u = t.slice(e[0].length),
b = l ? atob(u) : decodeURIComponent(u),
c = new ArrayBuffer(b.length), d = new Uint8Array(c), B = 0;
B < b.length; B += 1)
d[B] = b.charCodeAt(B);
return o ? new Blob([ n ? d : c ], {type : i})
: (f = new r, f.append(c), f.getBlob(i))
};
t.HTMLCanvasElement && !e.toBlob &&
(e.mozGetAsFile
? e.toBlob =
function(t, o, n) {
t(n && e.toDataURL && i ? i(this.toDataURL(o, n))
: this.mozGetAsFile("blob", o))
}
: e.toDataURL && i &&
(e.toBlob = function(t, e, o) { t(i(this.toDataURL(e, o))) })),
"function" == typeof define && define.amd
? define(function() { return i })
: "object" == typeof module &&module.exports ? module.exports = i
: t.dataURLtoBlob = i
}(window);
//# sourceMappingURL=canvas-to-blob.min.js.map
-1
View File
@@ -1 +0,0 @@
{"version":3,"sources":["canvas-to-blob.js"],"names":["window","CanvasPrototype","HTMLCanvasElement","prototype","hasBlobConstructor","Blob","Boolean","e","hasArrayBufferViewSupport","Uint8Array","size","BlobBuilder","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","dataURIPattern","dataURLtoBlob","atob","ArrayBuffer","dataURI","matches","mediaType","isBase64","dataString","byteString","arrayBuffer","intArray","i","bb","match","Error","slice","length","decodeURIComponent","charCodeAt","type","append","getBlob","toBlob","mozGetAsFile","callback","quality","toDataURL","this","define","amd","module","exports"],"mappings":"CAgBE,SAAUA,GACV,YAEA,IAAIC,GAAkBD,EAAOE,mBACLF,EAAOE,kBAAkBC,UAC7CC,EAAqBJ,EAAOK,MAAS,WACvC,IACE,MAAOC,SAAQ,GAAID,OACnB,MAAOE,GACP,OAAO,MAGPC,EAA4BJ,GAAsBJ,EAAOS,YAC1D,WACC,IACE,MAAgD,OAAzC,GAAIJ,OAAM,GAAII,YAAW,OAAOC,KACvC,MAAOH,GACP,OAAO,MAGTI,EAAcX,EAAOW,aAAeX,EAAOY,mBAC3BZ,EAAOa,gBAAkBb,EAAOc,cAChDC,EAAiB,0CACjBC,GAAiBZ,GAAsBO,IAAgBX,EAAOiB,MAChEjB,EAAOkB,aAAelB,EAAOS,YAC7B,SAAUU,GACR,GAAIC,GACFC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,CAGF,IADAR,EAAUD,EAAQU,MAAMd,IACnBK,EACH,KAAM,IAAIU,OAAM,mBAkBlB,KAfAT,EAAYD,EAAQ,GAChBA,EAAQ,GACR,cAAgBA,EAAQ,IAAM,qBAClCE,IAAaF,EAAQ,GACrBG,EAAaJ,EAAQY,MAAMX,EAAQ,GAAGY,QAGpCR,EAFEF,EAEWL,KAAKM,GAGLU,mBAAmBV,GAGlCE,EAAc,GAAIP,aAAYM,EAAWQ,QACzCN,EAAW,GAAIjB,YAAWgB,GACrBE,EAAI,EAAGA,EAAIH,EAAWQ,OAAQL,GAAK,EACtCD,EAASC,GAAKH,EAAWU,WAAWP,EAGtC,OAAIvB,GACK,GAAIC,OACRG,EAA4BkB,EAAWD,IACvCU,KAAMd,KAGXO,EAAK,GAAIjB,GACTiB,EAAGQ,OAAOX,GACHG,EAAGS,QAAQhB,IAElBrB,GAAOE,oBAAsBD,EAAgBqC,SAC3CrC,EAAgBsC,aAClBtC,EAAgBqC,OAAS,SAAUE,EAAUL,EAAMM,GAE/CD,EADEC,GAAWxC,EAAgByC,WAAa1B,EACjCA,EAAc2B,KAAKD,UAAUP,EAAMM,IAEnCE,KAAKJ,aAAa,OAAQJ,KAG9BlC,EAAgByC,WAAa1B,IACtCf,EAAgBqC,OAAS,SAAUE,EAAUL,EAAMM,GACjDD,EAASxB,EAAc2B,KAAKD,UAAUP,EAAMM,QAI5B,kBAAXG,SAAyBA,OAAOC,IACzCD,OAAO,WACL,MAAO5B,KAEkB,gBAAX8B,SAAuBA,OAAOC,QAC9CD,OAAOC,QAAU/B,EAEjBhB,EAAOgB,cAAgBA,GAEzBhB","file":"canvas-to-blob.min.js"}
-608
View File
@@ -1,608 +0,0 @@
/***
Spectrum Colorpicker v1.8.0
https://github.com/bgrins/spectrum
Author: Brian Grinstead
License: MIT
***/
.sp-container {
position: absolute;
top: 0;
left: 0;
display: inline-block;
*display: inline;
*zoom: 1;
/* https://github.com/bgrins/spectrum/issues/40 */
z-index: 9999994;
overflow: hidden;
}
.sp-container.sp-flat {
position: relative;
}
/* Fix for * { box-sizing: border-box; } */
.sp-container,
.sp-container * {
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
/* http://ansciath.tumblr.com/post/7347495869/css-aspect-ratio */
.sp-top {
position: relative;
width: 100%;
display: inline-block;
}
.sp-top-inner {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
.sp-color {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 20%;
}
.sp-hue {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 84%;
height: 100%;
}
.sp-clear-enabled .sp-hue {
top: 33px;
height: 77.5%;
}
.sp-fill {
padding-top: 80%;
}
.sp-sat,
.sp-val {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.sp-alpha-enabled .sp-top {
margin-bottom: 18px;
}
.sp-alpha-enabled .sp-alpha {
display: block;
}
.sp-alpha-handle {
position: absolute;
top: -4px;
bottom: -4px;
width: 6px;
left: 50%;
cursor: pointer;
border: 1px solid black;
background: white;
opacity: .8;
}
.sp-alpha {
display: none;
position: absolute;
bottom: -14px;
right: 0;
left: 0;
height: 8px;
}
.sp-alpha-inner {
border: solid 1px #333;
}
.sp-clear {
display: none;
}
.sp-clear.sp-clear-display {
background-position: center;
}
.sp-clear-enabled .sp-clear {
display: block;
position: absolute;
top: 0px;
right: 0;
bottom: 0;
left: 84%;
height: 28px;
}
/* Don't allow text selection */
.sp-container,
.sp-replacer,
.sp-preview,
.sp-dragger,
.sp-slider,
.sp-alpha,
.sp-clear,
.sp-alpha-handle,
.sp-container.sp-dragging .sp-input,
.sp-container button {
-webkit-user-select: none;
-moz-user-select: -moz-none;
-o-user-select: none;
user-select: none;
}
.sp-container.sp-input-disabled .sp-input-container {
display: none;
}
.sp-container.sp-buttons-disabled .sp-button-container {
display: none;
}
.sp-container.sp-palette-buttons-disabled .sp-palette-button-container {
display: none;
}
.sp-palette-only .sp-picker-container {
display: none;
}
.sp-palette-disabled .sp-palette-container {
display: none;
}
.sp-initial-disabled .sp-initial {
display: none;
}
/* Gradients for hue, saturation and value instead of images. Not pretty... but it works */
.sp-sat {
background-image: -webkit-gradient(linear, 0 0, 100% 0, from(#FFF), to(rgba(204, 154, 129, 0)));
background-image: -webkit-linear-gradient(left, #FFF, rgba(204, 154, 129, 0));
background-image: -moz-linear-gradient(left, #fff, rgba(204, 154, 129, 0));
background-image: -o-linear-gradient(left, #fff, rgba(204, 154, 129, 0));
background-image: -ms-linear-gradient(left, #fff, rgba(204, 154, 129, 0));
background-image: linear-gradient(to right, #fff, rgba(204, 154, 129, 0));
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr=#FFFFFFFF, endColorstr=#00CC9A81)";
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1, startColorstr='#FFFFFFFF', endColorstr='#00CC9A81');
}
.sp-val {
background-image: -webkit-gradient(linear, 0 100%, 0 0, from(#000000), to(rgba(204, 154, 129, 0)));
background-image: -webkit-linear-gradient(bottom, #000000, rgba(204, 154, 129, 0));
background-image: -moz-linear-gradient(bottom, #000, rgba(204, 154, 129, 0));
background-image: -o-linear-gradient(bottom, #000, rgba(204, 154, 129, 0));
background-image: -ms-linear-gradient(bottom, #000, rgba(204, 154, 129, 0));
background-image: linear-gradient(to top, #000, rgba(204, 154, 129, 0));
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#00CC9A81, endColorstr=#FF000000)";
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00CC9A81', endColorstr='#FF000000');
}
.sp-hue {
background: -moz-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
background: -ms-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
background: -o-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
background: -webkit-gradient(linear, left top, left bottom, from(#ff0000), color-stop(0.17, #ffff00), color-stop(0.33, #00ff00), color-stop(0.5, #00ffff), color-stop(0.67, #0000ff), color-stop(0.83, #ff00ff), to(#ff0000));
background: -webkit-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
background: linear-gradient(to bottom, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
}
/* IE filters do not support multiple color stops.
Generate 6 divs, line them up, and do two color gradients for each.
Yes, really.
*/
.sp-1 {
height: 17%;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0000', endColorstr='#ffff00');
}
.sp-2 {
height: 16%;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff00', endColorstr='#00ff00');
}
.sp-3 {
height: 17%;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ff00', endColorstr='#00ffff');
}
.sp-4 {
height: 17%;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ffff', endColorstr='#0000ff');
}
.sp-5 {
height: 16%;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0000ff', endColorstr='#ff00ff');
}
.sp-6 {
height: 17%;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff00ff', endColorstr='#ff0000');
}
.sp-hidden {
display: none !important;
}
/* Clearfix hack */
.sp-cf:before,
.sp-cf:after {
content: "";
display: table;
}
.sp-cf:after {
clear: both;
}
.sp-cf {
*zoom: 1;
}
/* Mobile devices, make hue slider bigger so it is easier to slide */
@media (max-device-width: 480px) {
.sp-color {
right: 40%;
}
.sp-hue {
left: 63%;
}
.sp-fill {
padding-top: 60%;
}
}
.sp-dragger {
border-radius: 5px;
height: 5px;
width: 5px;
border: 1px solid #fff;
background: #000;
cursor: pointer;
position: absolute;
top: 0;
left: 0;
}
.sp-slider {
position: absolute;
top: 0;
cursor: pointer;
height: 3px;
left: -1px;
right: -1px;
border: 1px solid #000;
background: white;
opacity: .8;
}
/*
Theme authors:
Here are the basic themeable display options (colors, fonts, global widths).
See http://bgrins.github.io/spectrum/themes/ for instructions.
*/
.sp-container {
border-radius: 0;
background-color: transparent;
/*border: solid 1px #f0c49B;*/
border: none;
padding: 0;
}
.sp-container,
.sp-container button,
.sp-container input,
.sp-color,
.sp-hue,
.sp-clear {
font: normal 12px "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Geneva, Verdana, sans-serif;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
}
.sp-top {
margin-bottom: 3px;
}
.sp-color,
.sp-hue,
.sp-clear {
border: solid 1px #666;
}
/* Input */
.sp-input-container {
float: right;
width: 100px;
margin-bottom: 4px;
}
.sp-initial-disabled .sp-input-container {
width: 100%;
}
.sp-input {
font-size: 12px !important;
border: 1px inset;
padding: 4px 5px;
margin: 0;
width: 100%;
background: transparent;
border-radius: 3px;
color: #222;
}
.sp-input:focus {
border: 1px solid orange;
}
.sp-input.sp-validation-error {
border: 1px solid red;
background: #fdd;
}
.sp-picker-container,
.sp-palette-container {
float: left;
position: relative;
padding: 10px;
padding-bottom: 300px;
margin-bottom: -290px;
}
.sp-picker-container {
width: 172px;
/*border-left: solid 1px #fff;*/
}
/* Palettes */
.sp-palette-container {
border-right: solid 1px #ccc;
}
.sp-palette-only .sp-palette-container {
border: 0;
}
.sp-palette .sp-thumb-el {
display: block;
position: relative;
float: left;
width: 24px;
height: 15px;
margin: 3px;
cursor: pointer;
border: solid 2px transparent;
}
.sp-palette .sp-thumb-el:hover,
.sp-palette .sp-thumb-el.sp-thumb-active {
border-color: orange;
}
.sp-thumb-el {
position: relative;
}
/* Initial */
.sp-initial {
float: left;
border: solid 1px #333;
}
.sp-initial span {
width: 30px;
height: 25px;
border: none;
display: block;
float: left;
margin: 0;
}
.sp-initial .sp-clear-display {
background-position: center;
}
/* Buttons */
.sp-palette-button-container,
.sp-button-container {
float: right;
}
/* Replacer (the little preview div that shows up instead of the <input>) */
.sp-replacer {
margin: 0;
overflow: hidden;
cursor: pointer;
padding: 4px;
display: inline-block;
*zoom: 1;
*display: inline;
border: solid 1px #91765d;
background: #eee;
color: #333;
vertical-align: middle;
}
.sp-replacer:hover,
.sp-replacer.sp-active {
border-color: #F0C49B;
color: #111;
}
.sp-replacer.sp-disabled {
cursor: default;
border-color: silver;
color: silver;
}
.sp-dd {
padding: 2px 0;
height: 16px;
line-height: 16px;
float: left;
font-size: 10px;
}
.sp-preview {
position: relative;
width: 25px;
height: 20px;
border: solid 1px #222;
margin-right: 5px;
float: left;
z-index: 0;
}
.sp-palette {
*width: 220px;
max-width: 220px;
}
.sp-palette .sp-thumb-el {
width: 16px;
height: 16px;
margin: 2px 1px;
border: solid 1px #d0d0d0;
}
.sp-container {
padding-bottom: 0;
}
/* Buttons: http://hellohappy.org/css3-buttons/ */
.sp-container button {
background-color: #eeeeee;
background-image: -webkit-linear-gradient(top, #eeeeee, #cccccc);
background-image: -moz-linear-gradient(top, #eeeeee, #cccccc);
background-image: -ms-linear-gradient(top, #eeeeee, #cccccc);
background-image: -o-linear-gradient(top, #eeeeee, #cccccc);
background-image: linear-gradient(to bottom, #eeeeee, #cccccc);
border: 1px solid #ccc;
border-bottom: 1px solid #bbb;
border-radius: 3px;
color: #333;
font-size: 14px;
line-height: 1;
padding: 5px 4px;
text-align: center;
text-shadow: 0 1px 0 #eee;
vertical-align: middle;
}
.sp-container button:hover {
background-color: #dddddd;
background-image: -webkit-linear-gradient(top, #dddddd, #bbbbbb);
background-image: -moz-linear-gradient(top, #dddddd, #bbbbbb);
background-image: -ms-linear-gradient(top, #dddddd, #bbbbbb);
background-image: -o-linear-gradient(top, #dddddd, #bbbbbb);
background-image: linear-gradient(to bottom, #dddddd, #bbbbbb);
border: 1px solid #bbb;
border-bottom: 1px solid #999;
cursor: pointer;
text-shadow: 0 1px 0 #ddd;
}
.sp-container button:active {
border: 1px solid #aaa;
border-bottom: 1px solid #888;
-webkit-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
-moz-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
-ms-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
-o-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
}
.sp-cancel {
font-size: 11px;
color: #d93f3f !important;
margin: 0;
padding: 2px;
margin-right: 5px;
vertical-align: middle;
text-decoration: none;
}
.sp-cancel:hover {
color: #d93f3f !important;
text-decoration: underline;
}
.sp-palette span:hover,
.sp-palette span.sp-thumb-active {
border-color: #000;
}
.sp-preview,
.sp-alpha,
.sp-thumb-el {
position: relative;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);
}
.sp-preview-inner,
.sp-alpha-inner,
.sp-thumb-inner {
display: block;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
.sp-palette .sp-thumb-inner {
background-position: 50% 50%;
background-repeat: no-repeat;
}
.sp-palette .sp-thumb-light.sp-thumb-active .sp-thumb-inner {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAIVJREFUeNpiYBhsgJFMffxAXABlN5JruT4Q3wfi/0DsT64h8UD8HmpIPCWG/KemIfOJCUB+Aoacx6EGBZyHBqI+WsDCwuQ9mhxeg2A210Ntfo8klk9sOMijaURm7yc1UP2RNCMbKE9ODK1HM6iegYLkfx8pligC9lCD7KmRof0ZhjQACDAAceovrtpVBRkAAAAASUVORK5CYII=);
}
.sp-palette .sp-thumb-dark.sp-thumb-active .sp-thumb-inner {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAMdJREFUOE+tkgsNwzAMRMugEAahEAahEAZhEAqlEAZhEAohEAYh81X2dIm8fKpEspLGvudPOsUYpxE2BIJCroJmEW9qJ+MKaBFhEMNabSy9oIcIPwrB+afvAUFoK4H0tMaQ3XtlrggDhOVVMuT4E5MMG0FBbCEYzjYT7OxLEvIHQLY2zWwQ3D+9luyOQTfKDiFD3iUIfPk8VqrKjgAiSfGFPecrg6HN6m/iBcwiDAo7WiBeawa+Kwh7tZoSCGLMqwlSAzVDhoK+6vH4G0P5wdkAAAAASUVORK5CYII=);
}
.sp-clear-display {
background-repeat: no-repeat;
background-position: center;
background-image: url(data:image/gif;base64,R0lGODlhFAAUAPcAAAAAAJmZmZ2dnZ6enqKioqOjo6SkpKWlpaampqenp6ioqKmpqaqqqqurq/Hx8fLy8vT09PX19ff39/j4+Pn5+fr6+vv7+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAP8ALAAAAAAUABQAAAihAP9FoPCvoMGDBy08+EdhQAIJCCMybCDAAYUEARBAlFiQQoMABQhKUJBxY0SPICEYHBnggEmDKAuoPMjS5cGYMxHW3IiT478JJA8M/CjTZ0GgLRekNGpwAsYABHIypcAgQMsITDtWJYBR6NSqMico9cqR6tKfY7GeBCuVwlipDNmefAtTrkSzB1RaIAoXodsABiZAEFB06gIBWC1mLVgBa0AAOw==);
}
-1204
View File
File diff suppressed because it is too large Load Diff
+7385
View File
File diff suppressed because it is too large Load Diff
+45
View File
@@ -0,0 +1,45 @@
{
"name": "fonticon",
"version": "1.0.0",
"description": "Tool for creating favicons and images from [Font Awesome](http://fontawesome.io/) icons. The generated icon can be previewed live in the browser.",
"private": true,
"directories": {
"lib": "lib",
"test": "test"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --display-modules",
"start:dev": "webpack-dev-server"
},
"repository": {
"type": "git",
"url": "git+https://github.com/devgg/FontIcon.git"
},
"keywords": [],
"author": "",
"license": "MIT",
"bugs": {
"url": "https://github.com/devgg/FontIcon/issues"
},
"homepage": "https://github.com/devgg/FontIcon#readme",
"devDependencies": {
"@fortawesome/fontawesome-free-webfonts": "^1.0.9",
"css-loader": "^0.28.11",
"file-loader": "^1.1.11",
"html-webpack-plugin": "^3.2.0",
"style-loader": "^0.21.0",
"uglifyjs-webpack-plugin": "^1.2.7",
"webpack": "^4.12.1",
"webpack-cli": "^3.0.8",
"webpack-dev-server": "^3.1.4"
},
"dependencies": {
"blueimp-canvas-to-blob": "^3.14.0",
"file-saver": "^1.3.8",
"fuse.js": "^3.2.1",
"jquery": "^3.3.1",
"spectrum-colorpicker": "^1.8.0",
"tinysort": "^2.3.6"
}
}
+10
View File
@@ -123,6 +123,11 @@ body {
width: 80%;
border-radius: 5px 0 0 5px;
border-right-color: white;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
}
#download:hover,
@@ -345,6 +350,11 @@ input[type='checkbox']:checked:before {
padding-right: 15px;
font-size: 14px;
cursor: pointer;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
}
#stacked {
+63 -76
View File
@@ -1,76 +1,63 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Create favicons using Font Awesome icons. Preview favicons live in browser.">
<title>Font Awesome Favicon Generator</title>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.13/css/all.css" integrity="sha384-DNOHZ68U8hZfKXOrtjWvjxusGo9WQnrNx2sqG0tfsghAvtVlRW3tvkXWZh58N9jp" crossorigin="anonymous">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Raleway">
<link rel="stylesheet" href="css/rangeslider.css">
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="css/mobile.css">
<link rel='stylesheet' href='lib/spectrum.css' />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tinysort/2.3.6/tinysort.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fuse.js/3.0.4/fuse.min.js"></script>
<script src="lib/ga.js"></script>
<script src='lib/spectrum.js'></script>
<script src="lib/canvas-to-blob.min.js"></script>
<script src="lib/FileSaver.min.js"></script>
<script src="lib/canvas-to-favicon.js"></script>
<script src="js/icons.js"></script>
<script src="js/main.js"></script>
</head>
<body>
<div id="left">
<div id="controls_container">
<canvas id="canvas"></canvas>
<div id="colors">
<div class="color_input">
<div class="color_button_container">
<div id="color" class="color_button"></div>
</div>
<input id="color_text" class="color_text" type="text" value="#ff3860">
</div>
<div class="color_input">
<div class="color_button_container">
<div id="background_color" class="color_button"></div>
</div>
<input id="background_color_text" class="color_text" type="text" value="rgba(255,255,255,0)">
</div>
</div>
<input id="size" type="range" min="10" max="100" step="1" value="85" data-orientation="horizontal">
<div class="stack_container">
<div class="stack_input">
<input id="stacked" type="checkbox" name="stacked">
<label for="stacked">Stacked</label>
</div>
<input id="stacked_size" type="range" min="10" max="100" step="1" value="60" data-orientation="horizontal">
</div>
<input id="search" type="text" name="search" autocomplete="off" placeholder="Search...">
<div id="download_container">
<div id="download">
<div>download</div>
<i class="fas fa-circle-notch fa-spin"></i>
</div>
<div id="file_format">
<div id="file_format_text">.ico</div>
<i class="fas fa-angle-down"></i>
</div>
</div>
</div>
<a id="footer" href="https://github.com/devgg/FontIcon" target="_blank">
<i class="fab fa-github"></i>
View on GitHub
</a>
</div>
<div id="right">
</div>
<iframe id="download_iframe" style="display:none;"></iframe>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Create favicons using Font Awesome icons. Preview favicons live in browser.">
<title>Font Awesome Favicon Generator</title>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Raleway">
</head>
<body>
<div id="left">
<div id="controls_container">
<canvas id="canvas"></canvas>
<div id="colors">
<div class="color_input">
<div class="color_button_container">
<div id="color" class="color_button"></div>
</div>
<input id="color_text" class="color_text" type="text">
</div>
<div class="color_input">
<div class="color_button_container">
<div id="background_color" class="color_button"></div>
</div>
<input id="background_color_text" class="color_text" type="text">
</div>
</div>
<input id="size" type="range" min="10" max="100" step="1" value="85" data-orientation="horizontal">
<div class="stack_container">
<div class="stack_input">
<input id="stacked" type="checkbox" name="stacked">
<label for="stacked">Stacked</label>
</div>
<input id="stacked_size" type="range" min="10" max="100" step="1" value="60" data-orientation="horizontal">
</div>
<input id="search" type="text" name="search" autocomplete="off" placeholder="Search...">
<div id="download_container">
<div id="download">
<div>download</div>
<i class="fas fa-circle-notch fa-spin"></i>
</div>
<div id="file_format">
<div id="file_format_text">.ico</div>
<i class="fas fa-angle-down"></i>
</div>
</div>
</div>
<a id="footer" href="https://github.com/devgg/FontIcon" target="_blank">
<i class="fab fa-github"></i>
View on GitHub
</a>
</div>
<div id="right">
</div>
<iframe id="download_iframe" style="display:none;"></iframe>
<form id="interactive_download" action="https://realfavicongenerator.net/api/favicon_generator" method="POST" style="display:none;">
<input id="interactive_download_input" type='hidden' name='json_params'></input>"
</form>
</body>
</html>
View File

Before

Width:  |  Height:  |  Size: 980 B

After

Width:  |  Height:  |  Size: 980 B

+94
View File
@@ -0,0 +1,94 @@
import draw from './draw.js';
import spectrum from 'spectrum-colorpicker';
function initColors(state) {
const $color = $('#color');
const $colorText = $('#color_text');
const $backgroundColor = $('#background_color');
const $backgroundColorText = $('#background_color_text');
const colors = {
foreground: {
setState: c => (state.foregroundColor = c),
$: $color,
$text: $colorText,
},
background: {
setState: c => (state.backgroundColor = c),
$: $backgroundColor,
$text: $backgroundColorText,
},
};
function colorFromPicker(color) {
const col = color.$.spectrum('get');
return 'rgba(' + col.toRgb().r + ', ' + col.toRgb().g + ', ' + col.toRgb().b + ', ' + col.toRgb().a + ')';
}
function updateColor(color, fromPicker, doDraw) {
if (!fromPicker) {
color.$.spectrum('set', color.$text.val());
}
const rgba = colorFromPicker(color);
color.setState(rgba);
color.$.css('background-color', rgba);
if (fromPicker) {
color.$text.val(rgba);
}
if (doDraw) {
draw();
}
}
$color.spectrum({
color: 'rgba(255, 56, 96, 1)',
showButtons: false,
showAlpha: true,
move: updateColor.bind(updateColor, colors.foreground, true, true),
});
$backgroundColor.spectrum({
color: 'rgba(255, 255, 255, 0)',
showButtons: false,
showAlpha: true,
move: updateColor.bind(updateColor, colors.background, true, true),
});
$colorText.on('input', updateColor.bind(updateColor, $color, $colorText, false, true));
$backgroundColorText.on('input', updateColor.bind(updateColor, colors.background, false, true));
updateColor(colors.foreground, true, false);
updateColor(colors.background, true, false);
}
function initControls(state) {
initColors(state);
const $size = $('#size');
const $stackedSize = $('#stacked_size');
const $stacked = $('#stacked');
$size.on('input', () => {
state.size = $size.val();
draw();
});
$stackedSize.on('input', () => {
state.stackedSize = $stackedSize.val();
draw();
});
$stacked.click(() => {
state.stackedSelected = !state.stackedSelected;
state.stackedSelected ? $stackedSize.show() : $stackedSize.hide();
draw();
});
$size.val(state.size);
$stackedSize.val(state.stackedSize);
$stacked.attr('checked', state.stackedSelected);
}
export { initControls };
+127
View File
@@ -0,0 +1,127 @@
import saveAs from 'file-saver';
import _ from 'blueimp-canvas-to-blob';
function initDownload() {
const createFaviconUrl = 'https://fonticon-207412.appspot.com/';
const $download = $('#download');
const $fileFormat = $('#file_format_text');
const $fileFormatText = $('#file_format_text');
const $downloadIframe = $('#download_iframe');
const $interactiveDownload = $('#interactive_download');
const $interactiveDownloadInput = $('#interactive_download_input');
let loading = false;
function iconCreationError(errorMessage) {
console.error(errorMessage);
}
function loadingFinished() {
loading = false;
$download.removeClass('loading');
}
$download.on('click', function() {
postAndRedirect(createAdvancedRequest());
if (false) {
// if (!loading) {
loading = true;
$download.addClass('loading');
if ($fileFormatText.text() == '.ico') {
const iconData = generateBase64Picture();
$.ajax({
type: 'POST',
url: createFaviconUrl,
data: iconData,
success: function(response) {
if (response.status == 'error') {
iconCreationError(response.error_message);
} else {
downloadFromUrl(response.url);
}
},
error: function(jqXHR, textStatus, errorMessage) {
iconCreationError(errorMessage);
},
complete: loadingFinished,
});
} else {
canvas.toBlob(function(blob) {
saveAs(blob, 'favicon.png');
loadingFinished();
});
}
}
});
$fileFormat.on('click', function() {
let new_format = '.ico';
if ($fileFormatText.text() == '.ico') {
new_format = '.png';
}
$fileFormatText.text(new_format);
});
downloadIfParameterPresent();
function getUrlParameter(param) {
const url = decodeURIComponent(window.location.search.substring(1));
const params = url.split('&');
for (let i = 0; i < params.length; i++) {
let p = params[i].split('=');
if (p[0] === param) {
p = params[i].split(param + '=');
return p[1] === undefined ? true : p[1];
}
}
}
function downloadFromUrl(url) {
$downloadIframe.attr('src', url);
}
function downloadIfParameterPresent() {
let downloadResponse = getUrlParameter('json_result');
if (downloadResponse !== undefined) {
downloadResponse = JSON.parse(downloadResponse).favicon_generation_result;
if (downloadResponse.result.status == 'error') {
iconCreationError(downloadResponse.result.status.error_message);
} else {
downloadFromUrl(downloadResponse.favicon.package_url);
}
}
}
function postAndRedirect(data) {
$interactiveDownloadInput.attr('value', data);
$interactiveDownload.submit();
}
function generateBase64Picture() {
return canvas.toDataURL().split(',')[1];
}
function createAdvancedRequest() {
return JSON.stringify({
favicon_generation: {
api_key: '87d5cd739b05c00416c4a19cd14a8bb5632ea563',
master_picture: {
type: 'inline',
content: generateBase64Picture(),
demo: 'false',
},
files_location: { type: 'no_location' },
callback: {
type: 'url',
url: 'https://gauger.io/fonticon',
short_url: 'false',
path_only: 'false',
},
},
});
}
}
export { initDownload };
+54
View File
@@ -0,0 +1,54 @@
import canvasToFavicon from './lib/canvas-to-favicon.js';
let canvas;
let ctx;
let canvasSize;
let s;
function initDraw(canvas_, ctx_, canvasSize_, state) {
canvas = canvas_;
ctx = ctx_;
canvasSize = canvasSize_;
s = state;
}
function setFont(icon, size) {
var fontWeight = 0;
switch (icon.style) {
case 'fas':
fontWeight = 900;
break;
case 'far':
fontWeight = 400;
break;
default:
console.error('Unkown icon style: ' + icon.style);
}
ctx.font = fontWeight + ' ' + (icon.max_size * size) / 100 + 'px "Font Awesome 5 Free"';
}
function draw() {
if (canvasSize > 0) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = s.backgroundColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
setFont(s.icon, s.size);
ctx.fillStyle = 'rgba(0, 0, 0, 1)';
ctx.globalCompositeOperation = 'destination-out';
ctx.fillText(s.icon.unicode, canvasSize / 2, canvasSize / 2);
ctx.fillStyle = s.foregroundColor;
ctx.globalCompositeOperation = 'source-over';
ctx.fillText(s.icon.unicode, canvasSize / 2, canvasSize / 2);
if (s.stackedSelected) {
ctx.save();
setFont(s.stackedIcon, s.stackedSize);
ctx.globalCompositeOperation = 'xor';
ctx.fillText(s.stackedIcon.unicode, canvasSize / 2, canvasSize / 2);
ctx.restore();
}
canvasToFavicon(canvas);
}
}
export { initDraw, draw };
export default draw;
File diff suppressed because one or more lines are too long
+37
View File
@@ -0,0 +1,37 @@
import icons from './generated/icons.js';
import { draw } from './draw.js';
function initIcons(state) {
const $right = $('#right');
$.each(icons, (index, icon) => {
const $iconOuter = $('<div>').addClass('icon_outer');
const styleClass = icon.style + ' fa-' + icon.id;
const $icon = $('<div>')
.addClass('icon hover')
.data('idx', icon.idx)
.append($('<i>').addClass(styleClass));
$icon.append(
$('<div>')
.addClass('icon_text underline')
.text(icon.id),
);
$iconOuter.append($icon);
$right.append($iconOuter);
});
$('.icon').on('click touchstart', event => {
const icon = icons[$(event.currentTarget).data('idx')];
if (!state.stackedSelected) {
state.icon = icon;
} else {
state.stackedIcon = icon;
}
draw();
});
}
export { initIcons };
+21
View File
@@ -0,0 +1,21 @@
import { initDraw, draw } from './draw.js';
import { initIcons } from './icons.js';
import { initState, c, s } from './state.js';
import { initControls } from './controls.js';
import { initSearch } from './search.js';
import { initDownload } from './download.js';
import 'spectrum-colorpicker/spectrum.css';
import './../css/rangeslider.css';
import './../css/style.css';
import './../css/mobile.css';
$(window).on('load', function() {
initState();
initIcons(s);
initSearch();
initDownload();
initControls(s);
initDraw(c.canvas, c.ctx, c.canvasSize, s);
setTimeout(draw, 1000);
});
View File
+94
View File
@@ -0,0 +1,94 @@
import Fuse from 'fuse.js';
import tinysort from 'tinysort';
import icons from './generated/icons.js';
function initSearch() {
const $search = $('#search');
const $right = $('#right');
const icon_map = icons.map;
const options = {
id: 'idx',
shouldSort: true,
threshold: 0.3,
location: 0,
distance: 100,
maxPatternLength: 32,
minMatchCharLength: 1,
keys: ['id', 'search_terms'],
};
const fuse = new Fuse(icons, options);
const result_map = new Array(icons.length);
function createResultMap(result) {
for (let i = 0; i < result_map.length; i++) {
result_map[i] = -1;
}
for (let i = 0; i < result.length; i++) {
result_map[result[i]] = i;
}
}
function filterIcons(query) {
$right.children().hide();
$right
.children()
.filter(function(index, element) {
return query == '' || result_map[$(element).data('idx')] != -1;
})
.show();
}
$search.on('input', function() {
console.time('someFunction');
console.time('search');
const query = $search.get(0).value;
const result = fuse.search(query);
createResultMap(result);
console.timeEnd('search');
console.time('filter');
filterIcons(query, result);
console.timeEnd('filter');
if (result.length == 0 && query == '') {
tinysort($right.children());
} else if (result.length > 0) {
tinysort($right.children(), {
sortFunction: function(a, b) {
return result_map[$(a.elm).data('idx')] - result_map[$(b.elm).data('idx')];
},
});
}
console.timeEnd('someFunction');
});
// function filterIcons(query, result) {
// $right.children().hide();
// $right
// .children()
// .filter(function(index, element) {
// return query == '' || result.indexOf($(element).data('id')) != -1;
// })
// .show();
// }
//
// $search.on('input', function() {
// console.time('someFunction');
// const query = $search.get(0).value;
// const result = fuse.search(query);
// //createResultMap(result);
//
// filterIcons(query, result);
// if (result.length == 0 && query == '') {
// tinysort($right.children());
// } else if (result.length > 0) {
// tinysort($right.children(), {
// sortFunction: function(a, b) {
// return result.indexOf($(a.elm).data('id')) - result.indexOf($(b.elm).data('id'));
// },
// });
// }
// console.timeEnd('someFunction');
// });
}
export { initSearch };
+30
View File
@@ -0,0 +1,30 @@
import icons from './generated/icons.js';
const c = {
canvas: undefined,
ctx: undefined,
canvasSize: 1024,
};
const s = {
foregroundColor: '#345334',
backgroundColor: '#345334',
size: 85,
stackedSize: 60,
icon: icons[432],
stackedIcon: icons[432],
stackedSelected: false,
};
function initState() {
c.canvas = document.getElementById('canvas');
c.canvas.width = c.canvasSize;
c.canvas.height = c.canvasSize;
c.ctx = c.canvas.getContext('2d');
c.ctx.textAlign = 'center';
c.ctx.textBaseline = 'middle';
Object.freeze(c);
}
export { initState, c, s };
+13
View File
@@ -0,0 +1,13 @@
language: node_js
script: npm run build
deploy:
provider: pages
skip-cleanup: true
github-token: $GITHUB_TOKEN # Set in the settings page of your repository, as a secure variable
keep-history: true
local-dir: dist
target-branch: master
project-name: devgg/devgg.github.io
on:
branch: master
+40 -8
View File
@@ -1,30 +1,62 @@
import urllib.request, json
from PIL import ImageFont
icons_json_url = 'https://raw.githubusercontent.com/FortAwesome/Font-Awesome/master/advanced-options/metadata/icons.json'
with urllib.request.urlopen(icons_json_url) as url:
icons_json = json.loads(url.read().decode())
def get_style(style):
if style == 'solid':
return ('fas', './node_modules/@fortawesome/fontawesome-free-webfonts/webfonts/fa-solid-900.woff')
elif style == 'regular':
return ('far', './node_modules/@fortawesome/fontawesome-free-webfonts/webfonts/fa-regular-400.woff')
else:
print('Warning: style {0} unkown.'.format(style))
def get_max_size(font, icon):
font_size = 1200;
max_size = 1024
width = max_size + 1
height = max_size + 1
# todo implement binary search
while width >= max_size or height >= max_size:
font_size -= 10
f = ImageFont.truetype(font, font_size)
width, height = f.getsize(icon)
if width > 0:
while width < max_size and height < max_size:
font_size += 1
f = ImageFont.truetype(font, font_size)
width, height = f.getsize(icon)
return font_size
result = []
for icon_name, icon in icons_json.items():
idx = 0
for i, (icon_name, icon) in enumerate(icons_json.items()):
if icon_name != 'font-awesome-logo-full':
for style in icon['styles']:
if style != 'brands':
style, font = get_style(style)
uni = ('\\u' + icon['unicode']).encode().decode('unicode-escape')
result_icon = {
'idx': idx,
'id': icon_name,
'name': icon['label'],
'style': style,
'unicode': '\\u' + icon['unicode'],
'unicode': uni,
'max_size': get_max_size(font, uni),
}
search_terms = icon['search']['terms']
if search_terms:
result_icon['search_terms'] = search_terms
result.append(result_icon)
idx += 1
print('{0}/{1} icons processed.'.format(i + 1, len(icons_json)), end="\r")
js_icons = 'var icons = ' + json.dumps(
result, separators=(',', ':')).replace('\\\\', '\\')
js_icons = 'export default ' + json.dumps(result, separators=(',', ':'))
with open('js/icons.js', 'w') as f:
with open('src/generated/icons.js', 'w') as f:
f.write(js_icons)
print(str(len(result)) + ' icons were written.')
+47
View File
@@ -0,0 +1,47 @@
const path = require('path');
const webpack = require('webpack');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
//mode: 'production',
mode: 'development',
entry: { index: './src/js/index.js', ga: './src/js/lib/ga.js' },
output: {
filename: '[name].js',
},
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
}),
new HtmlWebpackPlugin({
template: './src/html/index.html',
}),
],
devServer: {
contentBase: 'dist',
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
emitFile: true,
},
},
],
},
],
},
optimization: {
minimizer: [new UglifyJsPlugin()],
},
};