Initial commit: Web packages

This commit is contained in:
Ernad Husremovic 2025-08-29 15:20:51 +02:00
commit cd458d4b85
791 changed files with 410049 additions and 0 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright 2015-present Chen Fengyuan
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View file

@ -0,0 +1,304 @@
/*!
* Cropper.js v1.5.5
* https://fengyuanchen.github.io/cropperjs
*
* Copyright 2015-present Chen Fengyuan
* Released under the MIT license
*
* Date: 2019-08-04T02:26:27.232Z
*/
.cropper-container {
direction: ltr;
font-size: 0;
line-height: 0;
position: relative;
-ms-touch-action: none;
touch-action: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.cropper-container img {
display: block;
height: 100%;
image-orientation: 0deg;
max-height: none !important;
max-width: none !important;
min-height: 0 !important;
min-width: 0 !important;
width: 100%;
}
.cropper-wrap-box,
.cropper-canvas,
.cropper-drag-box,
.cropper-crop-box,
.cropper-modal {
bottom: 0;
left: 0;
position: absolute;
right: 0;
top: 0;
}
.cropper-wrap-box,
.cropper-canvas {
overflow: hidden;
}
.cropper-drag-box {
background-color: #fff;
opacity: 0;
}
.cropper-modal {
background-color: #000;
opacity: 0.5;
}
.cropper-view-box {
display: block;
height: 100%;
outline: 1px solid #39f;
outline-color: rgba(51, 153, 255, 0.75);
overflow: hidden;
width: 100%;
}
.cropper-dashed {
border: 0 dashed #eee;
display: block;
opacity: 0.5;
position: absolute;
}
.cropper-dashed.dashed-h {
border-bottom-width: 1px;
border-top-width: 1px;
height: calc(100% / 3);
left: 0;
top: calc(100% / 3);
width: 100%;
}
.cropper-dashed.dashed-v {
border-left-width: 1px;
border-right-width: 1px;
height: 100%;
left: calc(100% / 3);
top: 0;
width: calc(100% / 3);
}
.cropper-center {
display: block;
height: 0;
left: 50%;
opacity: 0.75;
position: absolute;
top: 50%;
width: 0;
}
.cropper-center::before,
.cropper-center::after {
background-color: #eee;
content: ' ';
display: block;
position: absolute;
}
.cropper-center::before {
height: 1px;
left: -3px;
top: 0;
width: 7px;
}
.cropper-center::after {
height: 7px;
left: 0;
top: -3px;
width: 1px;
}
.cropper-face,
.cropper-line,
.cropper-point {
display: block;
height: 100%;
opacity: 0.1;
position: absolute;
width: 100%;
}
.cropper-face {
background-color: #fff;
left: 0;
top: 0;
}
.cropper-line {
background-color: #39f;
}
.cropper-line.line-e {
cursor: ew-resize;
right: -3px;
top: 0;
width: 5px;
}
.cropper-line.line-n {
cursor: ns-resize;
height: 5px;
left: 0;
top: -3px;
}
.cropper-line.line-w {
cursor: ew-resize;
left: -3px;
top: 0;
width: 5px;
}
.cropper-line.line-s {
bottom: -3px;
cursor: ns-resize;
height: 5px;
left: 0;
}
.cropper-point {
background-color: #39f;
height: 5px;
opacity: 0.75;
width: 5px;
}
.cropper-point.point-e {
cursor: ew-resize;
margin-top: -3px;
right: -3px;
top: 50%;
}
.cropper-point.point-n {
cursor: ns-resize;
left: 50%;
margin-left: -3px;
top: -3px;
}
.cropper-point.point-w {
cursor: ew-resize;
left: -3px;
margin-top: -3px;
top: 50%;
}
.cropper-point.point-s {
bottom: -3px;
cursor: s-resize;
left: 50%;
margin-left: -3px;
}
.cropper-point.point-ne {
cursor: nesw-resize;
right: -3px;
top: -3px;
}
.cropper-point.point-nw {
cursor: nwse-resize;
left: -3px;
top: -3px;
}
.cropper-point.point-sw {
bottom: -3px;
cursor: nesw-resize;
left: -3px;
}
.cropper-point.point-se {
bottom: -3px;
cursor: nwse-resize;
height: 20px;
opacity: 1;
right: -3px;
width: 20px;
}
@media (min-width: 768px) {
.cropper-point.point-se {
height: 15px;
width: 15px;
}
}
@media (min-width: 992px) {
.cropper-point.point-se {
height: 10px;
width: 10px;
}
}
@media (min-width: 1200px) {
.cropper-point.point-se {
height: 5px;
opacity: 0.75;
width: 5px;
}
}
.cropper-point.point-se::before {
background-color: #39f;
bottom: -50%;
content: ' ';
display: block;
height: 200%;
opacity: 0;
position: absolute;
right: -50%;
width: 200%;
}
.cropper-invisible {
opacity: 0;
}
.cropper-bg {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC');
}
.cropper-hide {
display: block;
height: 0;
position: absolute;
width: 0;
}
.cropper-hidden {
display: none !important;
}
.cropper-move {
cursor: move;
}
.cropper-crop {
cursor: crosshair;
}
.cropper-disabled .cropper-drag-box,
.cropper-disabled .cropper-face,
.cropper-disabled .cropper-line,
.cropper-disabled .cropper-point {
cursor: not-allowed;
}

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,454 @@
/*
Copyright (c) 2014 Christophe Matthieu,
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
(function($){
'use strict';
var rad = Math.PI/180;
// public methods
var methods = {
init : function(settings) {
return this.each(function() {
var $this = $(this), transfo = $this.data('transfo');
if (!transfo) {
_init($this, settings);
} else {
_overwriteOptions($this, transfo, settings);
_targetCss($this, transfo);
}
});
},
destroy : function() {
return this.each(function() {
var $this = $(this);
if ($this.data('transfo')) {
_destroy($this);
}
});
},
reset : function() {
return this.each(function() {
var $this = $(this);
if ($this.data('transfo')) {
_reset($this);
}
});
},
toggle : function() {
return this.each(function() {
var $this = $(this);
var transfo = $this.data('transfo');
if (transfo) {
transfo.settings.hide = !transfo.settings.hide;
_showHide($this, transfo);
}
});
},
hide : function() {
return this.each(function() {
var $this = $(this);
var transfo = $this.data('transfo');
if (transfo) {
transfo.settings.hide = true;
_showHide($this, transfo);
}
});
},
show : function() {
return this.each(function() {
var $this = $(this);
var transfo = $this.data('transfo');
if (transfo) {
transfo.settings.hide = false;
_showHide($this, transfo);
}
});
},
settings : function() {
if(this.length > 1) {
this.map(function () {
var $this = $(this);
return $this.data('transfo') && $this.data('transfo').settings;
});
}
return this.data('transfo') && $this.data('transfo').settings;
},
center : function() {
if(this.length > 1) {
this.map(function () {
var $this = $(this);
return $this.data('transfo') && $this.data('transfo').$center.offset();
});
}
return this.data('transfo') && this.data('transfo').$center.offset();
}
};
$.fn.transfo = function( method ) {
if ( methods[method] ) {
return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof method === 'object' || ! method ) {
return methods.init.apply( this, arguments );
} else {
$.error( 'Method ' + method + ' does not exist on jQuery.transfo' );
}
return false;
};
function _init ($this, settings) {
var transfo = {};
$this.data('transfo', transfo);
transfo.settings = settings;
transfo.settings.document = transfo.settings.document || document;
// generate all the controls markup
var css = "box-sizing: border-box; position: absolute; background-color: #fff; border: 1px solid #ccc; width: 8px; height: 8px; margin-left: -4px; margin-top: -4px;";
transfo.$markup = $(''
+ '<div class="transfo-container">'
+ '<div class="transfo-controls">'
+ '<div style="cursor: crosshair; position: absolute; margin: -30px; top: 0; right: 0; padding: 1px 0 0 1px;" class="transfo-rotator">'
+ '<span class="fa-stack fa-lg">'
+ '<i class="fa fa-circle fa-stack-2x"></i>'
+ '<i class="fa fa-repeat fa-stack-1x fa-inverse"></i>'
+ '</span>'
+ '</div>'
+ '<div style="' + css + 'top: 0%; left: 0%; cursor: nw-resize;" class="transfo-scaler-tl"></div>'
+ '<div style="' + css + 'top: 0%; left: 100%; cursor: ne-resize;" class="transfo-scaler-tr"></div>'
+ '<div style="' + css + 'top: 100%; left: 100%; cursor: se-resize;" class="transfo-scaler-br"></div>'
+ '<div style="' + css + 'top: 100%; left: 0%; cursor: sw-resize;" class="transfo-scaler-bl"></div>'
+ '<div style="' + css + 'top: 0%; left: 50%; cursor: n-resize;" class="transfo-scaler-tc"></div>'
+ '<div style="' + css + 'top: 100%; left: 50%; cursor: s-resize;" class="transfo-scaler-bc"></div>'
+ '<div style="' + css + 'top: 50%; left: 0%; cursor: w-resize;" class="transfo-scaler-ml"></div>'
+ '<div style="' + css + 'top: 50%; left: 100%; cursor: e-resize;" class="transfo-scaler-mr"></div>'
+ '<div style="' + css + 'border: 0; width: 0px; height: 0px; top: 50%; left: 50%;" class="transfo-scaler-mc"></div>'
+ '</div>'
+ '</div>');
transfo.$center = transfo.$markup.find(".transfo-scaler-mc");
// init setting and get css to set wrap
_setOptions($this, transfo);
_overwriteOptions ($this, transfo, settings);
// append controls to container
$(transfo.settings.document.body).append(transfo.$markup);
// set transfo container and markup
setTimeout(function () {
_targetCss($this, transfo);
},0);
_bind($this, transfo);
_targetCss($this, transfo);
_stop_animation($this[0]);
}
function _overwriteOptions ($this, transfo, settings) {
transfo.settings = $.extend(transfo.settings, settings || {});
}
function _stop_animation (target) {
target.style.webkitAnimationPlayState = "paused";
target.style.animationPlayState = "paused";
target.style.webkitTransition = "none";
target.style.transition = "none";
}
function _setOptions ($this, transfo) {
var style = $this.attr("style") || "";
var transform = style.match(/transform\s*:([^;]+)/) ? style.match(/transform\s*:([^;]+)/)[1] : "";
transfo.settings = {};
transfo.settings.angle= transform.indexOf('rotate') != -1 ? parseFloat(transform.match(/rotate\(([^)]+)deg\)/)[1]) : 0;
transfo.settings.scalex= transform.indexOf('scaleX') != -1 ? parseFloat(transform.match(/scaleX\(([^)]+)\)/)[1]) : 1;
transfo.settings.scaley= transform.indexOf('scaleY') != -1 ? parseFloat(transform.match(/scaleY\(([^)]+)\)/)[1]) : 1;
transfo.settings.style = style.replace(/[^;]*transform[^;]+/g, '').replace(/;+/g, ';');
$this.attr("style", transfo.settings.style);
_stop_animation($this[0]);
transfo.settings.pos = $this.offset();
transfo.settings.height = $this.innerHeight();
transfo.settings.width = $this.innerWidth();
var translatex = transform.match(/translateX\(([0-9.-]+)(%|px)\)/);
var translatey = transform.match(/translateY\(([0-9.-]+)(%|px)\)/);
transfo.settings.translate = "%";
if (translatex && translatex[2] === "%") {
transfo.settings.translatexp = parseFloat(translatex[1]);
transfo.settings.translatex = transfo.settings.translatexp / 100 * transfo.settings.width;
} else {
transfo.settings.translatex = translatex ? parseFloat(translatex[1]) : 0;
}
if (translatey && translatey[2] === "%") {
transfo.settings.translateyp = parseFloat(translatey[1]);
transfo.settings.translatey = transfo.settings.translateyp / 100 * transfo.settings.height;
} else {
transfo.settings.translatey = translatey ? parseFloat(translatey[1]) : 0;
}
transfo.settings.css = window.getComputedStyle($this[0], null);
transfo.settings.rotationStep = 5;
transfo.settings.hide = false;
transfo.settings.callback = function () {};
}
function _bind ($this, transfo) {
function mousedown (event) {
_mouseDown($this, this, transfo, event);
$(transfo.settings.document).on("mousemove", mousemove).on("mouseup", mouseup);
}
function mousemove (event) {
_mouseMove($this, this, transfo, event);
}
function mouseup (event) {
_mouseUp($this, this, transfo, event);
$(transfo.settings.document).off("mousemove", mousemove).off("mouseup", mouseup);
}
transfo.$markup.off().on("mousedown", mousedown);
transfo.$markup.find(".transfo-controls >:not(.transfo-scaler-mc)").off().on("mousedown", mousedown);
}
function _mouseDown($this, div, transfo, event) {
event.preventDefault();
if (transfo.active || event.which !== 1) return;
var type = "position", $e = $(div);
if ($e.hasClass("transfo-rotator")) type = "rotator";
else if ($e.hasClass("transfo-scaler-tl")) type = "tl";
else if ($e.hasClass("transfo-scaler-tr")) type = "tr";
else if ($e.hasClass("transfo-scaler-br")) type = "br";
else if ($e.hasClass("transfo-scaler-bl")) type = "bl";
else if ($e.hasClass("transfo-scaler-tc")) type = "tc";
else if ($e.hasClass("transfo-scaler-bc")) type = "bc";
else if ($e.hasClass("transfo-scaler-ml")) type = "ml";
else if ($e.hasClass("transfo-scaler-mr")) type = "mr";
transfo.active = {
"type": type,
"scalex": transfo.settings.scalex,
"scaley": transfo.settings.scaley,
"pageX": event.pageX,
"pageY": event.pageY,
"center": transfo.$center.offset(),
};
}
function _mouseUp($this, div, transfo, event) {
transfo.active = null;
}
function _mouseMove($this, div, transfo, event) {
event.preventDefault();
if (!transfo.active) return;
var settings = transfo.settings;
var center = transfo.active.center;
var cdx = center.left - event.pageX;
var cdy = center.top - event.pageY;
if (transfo.active.type == "rotator") {
var ang, dang = Math.atan((settings.width * settings.scalex) / (settings.height * settings.scaley)) / rad;
if (cdy) ang = Math.atan(- cdx / cdy) / rad;
else ang = 0;
if (event.pageY >= center.top && event.pageX >= center.left) ang += 180;
else if (event.pageY >= center.top && event.pageX < center.left) ang += 180;
else if (event.pageY < center.top && event.pageX < center.left) ang += 360;
ang -= dang;
if (settings.scaley < 0 && settings.scalex < 0) ang += 180;
if (!event.ctrlKey) {
settings.angle = Math.round(ang / transfo.settings.rotationStep) * transfo.settings.rotationStep;
} else {
settings.angle = ang;
}
// reset position : don't move center
_targetCss($this, transfo);
var new_center = transfo.$center.offset();
var x = center.left - new_center.left;
var y = center.top - new_center.top;
var angle = ang * rad;
settings.translatex += x*Math.cos(angle) - y*Math.sin(-angle);
settings.translatey += - x*Math.sin(angle) + y*Math.cos(-angle);
}
else if (transfo.active.type == "position") {
var angle = settings.angle * rad;
var x = event.pageX - transfo.active.pageX;
var y = event.pageY - transfo.active.pageY;
transfo.active.pageX = event.pageX;
transfo.active.pageY = event.pageY;
var dx = x*Math.cos(angle) - y*Math.sin(-angle);
var dy = - x*Math.sin(angle) + y*Math.cos(-angle);
settings.translatex += dx;
settings.translatey += dy;
}
else if (transfo.active.type.length === 2) {
var angle = settings.angle * rad;
var dx = cdx*Math.cos(angle) - cdy*Math.sin(-angle);
var dy = - cdx*Math.sin(angle) + cdy*Math.cos(-angle);
if (transfo.active.type.indexOf("t") != -1) {
settings.scaley = dy / (settings.height/2);
}
if (transfo.active.type.indexOf("b") != -1) {
settings.scaley = - dy / (settings.height/2);
}
if (transfo.active.type.indexOf("l") != -1) {
settings.scalex = dx / (settings.width/2);
}
if (transfo.active.type.indexOf("r") != -1) {
settings.scalex = - dx / (settings.width/2);
}
if (settings.scaley > 0 && settings.scaley < 0.05) settings.scaley = 0.05;
if (settings.scalex > 0 && settings.scalex < 0.05) settings.scalex = 0.05;
if (settings.scaley < 0 && settings.scaley > -0.05) settings.scaley = -0.05;
if (settings.scalex < 0 && settings.scalex > -0.05) settings.scalex = -0.05;
if (event.shiftKey &&
(transfo.active.type === "tl" || transfo.active.type === "bl" ||
transfo.active.type === "tr" || transfo.active.type === "br")) {
settings.scaley = settings.scalex;
}
}
settings.angle = Math.round(settings.angle);
settings.translatex = Math.round(settings.translatex);
settings.translatey = Math.round(settings.translatey);
settings.scalex = Math.round(settings.scalex*100)/100;
settings.scaley = Math.round(settings.scaley*100)/100;
_targetCss($this, transfo);
_stop_animation($this[0]);
return false;
}
function _setCss($this, css, settings) {
var transform = "";
var trans = false;
if (settings.angle !== 0) {
trans = true;
transform += " rotate("+settings.angle+"deg) ";
}
if (settings.translatex) {
trans = true;
transform += " translateX("+(settings.translate === "%" ? settings.translatexp+"%" : settings.translatex+"px")+") ";
}
if (settings.translatey) {
trans = true;
transform += " translateY("+(settings.translate === "%" ? settings.translateyp+"%" : settings.translatey+"px")+") ";
}
if (settings.scalex != 1) {
trans = true;
transform += " scaleX("+settings.scalex+") ";
}
if (settings.scaley != 1){
trans = true;
transform += " scaleY("+settings.scaley+") ";
}
if (trans) {
css += ";"
/* Safari */
css += "-webkit-transform:" + transform + ";"
/* Firefox */
+ "-moz-transform:" + transform + ";"
/* IE */
+ "-ms-transform:" + transform + ";"
/* Opera */
+ "-o-transform:" + transform + ";"
/* Other */
+ "transform:" + transform + ";";
}
css = css.replace(/(\s*;)+/g, ';').replace(/^\s*;|;\s*$/g, '');
$this.attr("style", css);
}
function _targetCss ($this, transfo) {
var settings = transfo.settings;
var width = parseFloat(settings.css.width);
var height = parseFloat(settings.css.height);
settings.translatexp = Math.round(settings.translatex/width*1000)/10;
settings.translateyp = Math.round(settings.translatey/height*1000)/10;
_setCss($this, settings.style, settings);
transfo.$markup.css({
"position": "absolute",
"width": width + "px",
"height": height + "px",
"top": settings.pos.top + "px",
"left": settings.pos.left + "px"
});
var $controls = transfo.$markup.find('.transfo-controls');
_setCss($controls,
"width:" + width + "px;" +
"height:" + height + "px;" +
"cursor: move;",
settings);
$controls.children().css("transform", "scaleX("+(1/settings.scalex)+") scaleY("+(1/settings.scaley)+")");
_showHide($this, transfo);
transfo.settings.callback.call($this[0], $this);
}
function _showHide ($this, transfo) {
transfo.$markup.css("z-index", transfo.settings.hide ? -1 : 1000);
if (transfo.settings.hide) {
transfo.$markup.find(".transfo-controls > *").hide();
transfo.$markup.find(".transfo-scaler-mc").show();
} else {
transfo.$markup.find(".transfo-controls > *").show();
}
}
function _destroy ($this) {
$this.data('transfo').$markup.remove();
$this.removeData('transfo');
}
function _reset ($this) {
var transfo = $this.data('transfo');
_destroy($this);
$this.transfo(transfo.settings);
}
})(jQuery);

View file

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2018 Chen Fengyuan
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View file

@ -0,0 +1,75 @@
/*!
* jQuery Cropper v1.0.0
* https://github.com/fengyuanchen/jquery-cropper
*
* Copyright (c) 2018 Chen Fengyuan
* Released under the MIT license
*
* Date: 2018-04-01T06:20:13.168Z
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('jquery'), require('cropperjs')) :
typeof define === 'function' && define.amd ? define(['jquery', 'cropperjs'], factory) :
(factory(global.jQuery,global.Cropper));
}(this, (function ($,Cropper) { 'use strict';
$ = $ && $.hasOwnProperty('default') ? $['default'] : $;
Cropper = Cropper && Cropper.hasOwnProperty('default') ? Cropper['default'] : Cropper;
if ($.fn) {
var AnotherCropper = $.fn.cropper;
var NAMESPACE = 'cropper';
$.fn.cropper = function jQueryCropper(option) {
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
var result = void 0;
this.each(function (i, element) {
var $element = $(element);
var isDestroy = option === 'destroy';
var cropper = $element.data(NAMESPACE);
if (!cropper) {
if (isDestroy) {
return;
}
var options = $.extend({}, $element.data(), $.isPlainObject(option) && option);
cropper = new Cropper(element, options);
$element.data(NAMESPACE, cropper);
}
if (typeof option === 'string') {
var fn = cropper[option];
if ($.isFunction(fn)) {
result = fn.apply(cropper, args);
if (result === cropper) {
result = undefined;
}
if (isDestroy) {
$element.removeData(NAMESPACE);
}
}
}
});
return result !== undefined ? result : this;
};
$.fn.cropper.Constructor = Cropper;
$.fn.cropper.setDefaults = Cropper.setDefaults;
$.fn.cropper.noConflict = function noConflict() {
$.fn.cropper = AnotherCropper;
return this;
};
}
})));

View file

@ -0,0 +1,358 @@
/**
* vkBeautify - javascript plugin to pretty-print or minify text in XML, JSON, CSS and SQL formats.
*
* Version - 0.99.00.beta
* Copyright (c) 2012 Vadim Kiryukhin
* vkiryukhin @ gmail.com
* http://www.eslinstructor.net/vkbeautify/
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
* Pretty print
*
* vkbeautify.xml(text [,indent_pattern]);
* vkbeautify.json(text [,indent_pattern]);
* vkbeautify.css(text [,indent_pattern]);
* vkbeautify.sql(text [,indent_pattern]);
*
* @text - String; text to beatufy;
* @indent_pattern - Integer | String;
* Integer: number of white spaces;
* String: character string to visualize indentation ( can also be a set of white spaces )
* Minify
*
* vkbeautify.xmlmin(text [,preserve_comments]);
* vkbeautify.jsonmin(text);
* vkbeautify.cssmin(text [,preserve_comments]);
* vkbeautify.sqlmin(text);
*
* @text - String; text to minify;
* @preserve_comments - Bool; [optional];
* Set this flag to true to prevent removing comments from @text ( minxml and mincss functions only. )
*
* Examples:
* vkbeautify.xml(text); // pretty print XML
* vkbeautify.json(text, 4 ); // pretty print JSON
* vkbeautify.css(text, '. . . .'); // pretty print CSS
* vkbeautify.sql(text, '----'); // pretty print SQL
*
* vkbeautify.xmlmin(text, true);// minify XML, preserve comments
* vkbeautify.jsonmin(text);// minify JSON
* vkbeautify.cssmin(text);// minify CSS, remove comments ( default )
* vkbeautify.sqlmin(text);// minify SQL
*
*/
(function() {
function createShiftArr(step) {
var space = ' ';
if ( isNaN(parseInt(step)) ) { // argument is string
space = step;
} else { // argument is integer
switch(step) {
case 1: space = ' '; break;
case 2: space = ' '; break;
case 3: space = ' '; break;
case 4: space = ' '; break;
case 5: space = ' '; break;
case 6: space = ' '; break;
case 7: space = ' '; break;
case 8: space = ' '; break;
case 9: space = ' '; break;
case 10: space = ' '; break;
case 11: space = ' '; break;
case 12: space = ' '; break;
}
}
var shift = ['\n']; // array of shifts
for(ix=0;ix<100;ix++){
shift.push(shift[ix]+space);
}
return shift;
}
function vkbeautify(){
this.step = ' '; // 4 spaces
this.shift = createShiftArr(this.step);
};
vkbeautify.prototype.xml = function(text,step) {
var ar = text.replace(/>\s{0,}</g,"><")
.replace(/</g,"~::~<")
.replace(/\s*xmlns\:/g,"~::~xmlns:")
.replace(/\s*xmlns\=/g,"~::~xmlns=")
.split('~::~'),
len = ar.length,
inComment = false,
deep = 0,
str = '',
ix = 0,
shift = step ? createShiftArr(step) : this.shift;
for(ix=0;ix<len;ix++) {
// start comment or <![CDATA[...]]> or <!DOCTYPE //
if(ar[ix].search(/<!/) > -1) {
str += shift[deep]+ar[ix];
inComment = true;
// end comment or <![CDATA[...]]> //
if(ar[ix].search(/-->/) > -1 || ar[ix].search(/\]>/) > -1 || ar[ix].search(/!DOCTYPE/) > -1 ) {
inComment = false;
}
} else
// end comment or <![CDATA[...]]> //
if(ar[ix].search(/-->/) > -1 || ar[ix].search(/\]>/) > -1) {
str += ar[ix];
inComment = false;
} else
// <elm></elm> //
if( /^<\w/.exec(ar[ix-1]) && /^<\/\w/.exec(ar[ix]) &&
/^<[\w:\-\.\,]+/.exec(ar[ix-1]) == /^<\/[\w:\-\.\,]+/.exec(ar[ix])[0].replace('/','')) {
str += ar[ix];
if(!inComment) deep--;
} else
// <elm> //
if(ar[ix].search(/<\w/) > -1 && ar[ix].search(/<\//) == -1 && ar[ix].search(/\/>/) == -1 ) {
str = !inComment ? str += shift[deep++]+ar[ix] : str += ar[ix];
} else
// <elm>...</elm> //
if(ar[ix].search(/<\w/) > -1 && ar[ix].search(/<\//) > -1) {
str = !inComment ? str += shift[deep]+ar[ix] : str += ar[ix];
} else
// </elm> //
if(ar[ix].search(/<\//) > -1) {
str = !inComment ? str += shift[--deep]+ar[ix] : str += ar[ix];
} else
// <elm/> //
if(ar[ix].search(/\/>/) > -1 ) {
str = !inComment ? str += shift[deep]+ar[ix] : str += ar[ix];
} else
// <? xml ... ?> //
if(ar[ix].search(/<\?/) > -1) {
str += shift[deep]+ar[ix];
} else
// xmlns //
if( ar[ix].search(/xmlns\:/) > -1 || ar[ix].search(/xmlns\=/) > -1) {
str += shift[deep]+ar[ix];
}
else {
str += ar[ix];
}
}
return (str[0] == '\n') ? str.slice(1) : str;
}
vkbeautify.prototype.json = function(text,step) {
var step = step ? step : this.step;
if (typeof JSON === 'undefined' ) return text;
if ( typeof text === "string" ) return JSON.stringify(JSON.parse(text), null, step);
if ( typeof text === "object" ) return JSON.stringify(text, null, step);
return text; // text is not string nor object
}
vkbeautify.prototype.css = function(text, step) {
var ar = text.replace(/\s{1,}/g,' ')
.replace(/\{/g,"{~::~")
.replace(/\}/g,"~::~}~::~")
.replace(/\;/g,";~::~")
.replace(/\/\*/g,"~::~/*")
.replace(/\*\//g,"*/~::~")
.replace(/~::~\s{0,}~::~/g,"~::~")
.split('~::~'),
len = ar.length,
deep = 0,
str = '',
ix = 0,
shift = step ? createShiftArr(step) : this.shift;
for(ix=0;ix<len;ix++) {
if( /\{/.exec(ar[ix])) {
str += shift[deep++]+ar[ix];
} else
if( /\}/.exec(ar[ix])) {
str += shift[--deep]+ar[ix];
} else
if( /\*\\/.exec(ar[ix])) {
str += shift[deep]+ar[ix];
}
else {
str += shift[deep]+ar[ix];
}
}
return str.replace(/^\n{1,}/,'');
}
//----------------------------------------------------------------------------
function isSubquery(str, parenthesisLevel) {
return parenthesisLevel - (str.replace(/\(/g,'').length - str.replace(/\)/g,'').length )
}
function split_sql(str, tab) {
return str.replace(/\s{1,}/g," ")
.replace(/ AND /ig,"~::~"+tab+tab+"AND ")
.replace(/ BETWEEN /ig,"~::~"+tab+"BETWEEN ")
.replace(/ CASE /ig,"~::~"+tab+"CASE ")
.replace(/ ELSE /ig,"~::~"+tab+"ELSE ")
.replace(/ END /ig,"~::~"+tab+"END ")
.replace(/ FROM /ig,"~::~FROM ")
.replace(/ GROUP\s{1,}BY/ig,"~::~GROUP BY ")
.replace(/ HAVING /ig,"~::~HAVING ")
//.replace(/ SET /ig," SET~::~")
.replace(/ IN /ig," IN ")
.replace(/ JOIN /ig,"~::~JOIN ")
.replace(/ CROSS~::~{1,}JOIN /ig,"~::~CROSS JOIN ")
.replace(/ INNER~::~{1,}JOIN /ig,"~::~INNER JOIN ")
.replace(/ LEFT~::~{1,}JOIN /ig,"~::~LEFT JOIN ")
.replace(/ RIGHT~::~{1,}JOIN /ig,"~::~RIGHT JOIN ")
.replace(/ ON /ig,"~::~"+tab+"ON ")
.replace(/ OR /ig,"~::~"+tab+tab+"OR ")
.replace(/ ORDER\s{1,}BY/ig,"~::~ORDER BY ")
.replace(/ OVER /ig,"~::~"+tab+"OVER ")
.replace(/\(\s{0,}SELECT /ig,"~::~(SELECT ")
.replace(/\)\s{0,}SELECT /ig,")~::~SELECT ")
.replace(/ THEN /ig," THEN~::~"+tab+"")
.replace(/ UNION /ig,"~::~UNION~::~")
.replace(/ USING /ig,"~::~USING ")
.replace(/ WHEN /ig,"~::~"+tab+"WHEN ")
.replace(/ WHERE /ig,"~::~WHERE ")
.replace(/ WITH /ig,"~::~WITH ")
//.replace(/\,\s{0,}\(/ig,",~::~( ")
//.replace(/\,/ig,",~::~"+tab+tab+"")
.replace(/ ALL /ig," ALL ")
.replace(/ AS /ig," AS ")
.replace(/ ASC /ig," ASC ")
.replace(/ DESC /ig," DESC ")
.replace(/ DISTINCT /ig," DISTINCT ")
.replace(/ EXISTS /ig," EXISTS ")
.replace(/ NOT /ig," NOT ")
.replace(/ NULL /ig," NULL ")
.replace(/ LIKE /ig," LIKE ")
.replace(/\s{0,}SELECT /ig,"SELECT ")
.replace(/\s{0,}UPDATE /ig,"UPDATE ")
.replace(/ SET /ig," SET ")
.replace(/~::~{1,}/g,"~::~")
.split('~::~');
}
vkbeautify.prototype.sql = function(text,step) {
var ar_by_quote = text.replace(/\s{1,}/g," ")
.replace(/\'/ig,"~::~\'")
.split('~::~'),
len = ar_by_quote.length,
ar = [],
deep = 0,
tab = this.step,//+this.step,
inComment = true,
inQuote = false,
parenthesisLevel = 0,
str = '',
ix = 0,
shift = step ? createShiftArr(step) : this.shift;;
for(ix=0;ix<len;ix++) {
if(ix%2) {
ar = ar.concat(ar_by_quote[ix]);
} else {
ar = ar.concat(split_sql(ar_by_quote[ix], tab) );
}
}
len = ar.length;
for(ix=0;ix<len;ix++) {
parenthesisLevel = isSubquery(ar[ix], parenthesisLevel);
if( /\s{0,}\s{0,}SELECT\s{0,}/.exec(ar[ix])) {
ar[ix] = ar[ix].replace(/\,/g,",\n"+tab+tab+"")
}
if( /\s{0,}\s{0,}SET\s{0,}/.exec(ar[ix])) {
ar[ix] = ar[ix].replace(/\,/g,",\n"+tab+tab+"")
}
if( /\s{0,}\(\s{0,}SELECT\s{0,}/.exec(ar[ix])) {
deep++;
str += shift[deep]+ar[ix];
} else
if( /\'/.exec(ar[ix]) ) {
if(parenthesisLevel<1 && deep) {
deep--;
}
str += ar[ix];
}
else {
str += shift[deep]+ar[ix];
if(parenthesisLevel<1 && deep) {
deep--;
}
}
var junk = 0;
}
str = str.replace(/^\n{1,}/,'').replace(/\n{1,}/g,"\n");
return str;
}
vkbeautify.prototype.xmlmin = function(text, preserveComments) {
var str = preserveComments ? text
: text.replace(/\<![ \r\n\t]*(--([^\-]|[\r\n]|-[^\-])*--[ \r\n\t]*)\>/g,"")
.replace(/[ \r\n\t]{1,}xmlns/g, ' xmlns');
return str.replace(/>\s{0,}</g,"><");
}
vkbeautify.prototype.jsonmin = function(text) {
if (typeof JSON === 'undefined' ) return text;
return JSON.stringify(JSON.parse(text), null, 0);
}
vkbeautify.prototype.cssmin = function(text, preserveComments) {
var str = preserveComments ? text
: text.replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\//g,"") ;
return str.replace(/\s{1,}/g,' ')
.replace(/\{\s{1,}/g,"{")
.replace(/\}\s{1,}/g,"}")
.replace(/\;\s{1,}/g,";")
.replace(/\/\*\s{1,}/g,"/*")
.replace(/\*\/\s{1,}/g,"*/");
}
vkbeautify.prototype.sqlmin = function(text) {
return text.replace(/\s{1,}/g," ").replace(/\s{1,}\(/,"(").replace(/\s{1,}\)/,")");
}
window.vkbeautify = new vkbeautify();
})();

View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 Dominic Szablewski - phoboslab.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -0,0 +1,640 @@
/*
WebGLImageFilter - MIT Licensed
2013, Dominic Szablewski - phoboslab.org
*/
(function(window){
var WebGLProgram = function( gl, vertexSource, fragmentSource ) {
var _collect = function( source, prefix, collection ) {
var r = new RegExp('\\b' + prefix + ' \\w+ (\\w+)', 'ig');
source.replace(r, function(match, name) {
collection[name] = 0;
return match;
});
};
var _compile = function( gl, source, type ) {
var shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if( !gl.getShaderParameter(shader, gl.COMPILE_STATUS) ) {
console.log(gl.getShaderInfoLog(shader));
return null;
}
return shader;
};
this.uniform = {};
this.attribute = {};
var _vsh = _compile(gl, vertexSource, gl.VERTEX_SHADER);
var _fsh = _compile(gl, fragmentSource, gl.FRAGMENT_SHADER);
this.id = gl.createProgram();
gl.attachShader(this.id, _vsh);
gl.attachShader(this.id, _fsh);
gl.linkProgram(this.id);
if( !gl.getProgramParameter(this.id, gl.LINK_STATUS) ) {
console.log(gl.getProgramInfoLog(this.id));
}
gl.useProgram(this.id);
// Collect attributes
_collect(vertexSource, 'attribute', this.attribute);
for( var a in this.attribute ) {
this.attribute[a] = gl.getAttribLocation(this.id, a);
}
// Collect uniforms
_collect(vertexSource, 'uniform', this.uniform);
_collect(fragmentSource, 'uniform', this.uniform);
for( var u in this.uniform ) {
this.uniform[u] = gl.getUniformLocation(this.id, u);
}
};
const identityMatrix = [
1, 0, 0, 0, 0,
0, 1, 0, 0, 0,
0, 0, 1, 0, 0,
0, 0, 0, 1, 0,
];
const weightedAvg = (a, b, w) => a * w + b * (1 - w);
var WebGLImageFilter = window.WebGLImageFilter = function (params) {
if (!params)
params = { };
var
gl = null,
_drawCount = 0,
_sourceTexture = null,
_lastInChain = false,
_currentFramebufferIndex = -1,
_tempFramebuffers = [null, null],
_filterChain = [],
_width = -1,
_height = -1,
_vertexBuffer = null,
_currentProgram = null,
_canvas = params.canvas || document.createElement('canvas');
// key is the shader program source, value is the compiled program
var _shaderProgramCache = { };
var gl = _canvas.getContext("webgl") || _canvas.getContext("experimental-webgl");
if( !gl ) {
throw "Couldn't get WebGL context";
}
this.addFilter = function( name ) {
var args = Array.prototype.slice.call(arguments, 1);
var filter = _filter[name];
_filterChain.push({func:filter, args:args});
};
this.reset = function() {
_filterChain = [];
};
this.apply = function( image ) {
_resize( image.width, image.height );
_drawCount = 0;
// Create the texture for the input image if we haven't yet
if (!_sourceTexture)
_sourceTexture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, _sourceTexture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
// No filters? Just draw
if( _filterChain.length == 0 ) {
var program = _compileShader(SHADER.FRAGMENT_IDENTITY);
_draw();
return _canvas;
}
for( var i = 0; i < _filterChain.length; i++ ) {
_lastInChain = (i == _filterChain.length-1);
var f = _filterChain[i];
f.func.apply(this, f.args || []);
}
return _canvas;
};
var _resize = function( width, height ) {
// Same width/height? Nothing to do here
if( width == _width && height == _height ) { return; }
_canvas.width = _width = width;
_canvas.height = _height = height;
// Create the context if we don't have it yet
if( !_vertexBuffer ) {
// Create the vertex buffer for the two triangles [x, y, u, v] * 6
var vertices = new Float32Array([
-1, -1, 0, 1, 1, -1, 1, 1, -1, 1, 0, 0,
-1, 1, 0, 0, 1, -1, 1, 1, 1, 1, 1, 0
]);
_vertexBuffer = gl.createBuffer(),
gl.bindBuffer(gl.ARRAY_BUFFER, _vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
// Note sure if this is a good idea; at least it makes texture loading
// in Ejecta instant.
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
}
gl.viewport(0, 0, _width, _height);
// Delete old temp framebuffers
_tempFramebuffers = [null, null];
};
var _getTempFramebuffer = function( index ) {
_tempFramebuffers[index] =
_tempFramebuffers[index] ||
_createFramebufferTexture( _width, _height );
return _tempFramebuffers[index];
};
var _createFramebufferTexture = function( width, height ) {
var fbo = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
var renderbuffer = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
gl.bindTexture(gl.TEXTURE_2D, null);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
return {fbo: fbo, texture: texture};
};
var _draw = function( flags ) {
var source = null,
target = null,
flipY = false;
// Set up the source
if( _drawCount == 0 ) {
// First draw call - use the source texture
source = _sourceTexture;
}
else {
// All following draw calls use the temp buffer last drawn to
source = _getTempFramebuffer(_currentFramebufferIndex).texture;
}
_drawCount++;
// Set up the target
if( _lastInChain && !(flags & DRAW.INTERMEDIATE) ) {
// Last filter in our chain - draw directly to the WebGL Canvas. We may
// also have to flip the image vertically now
target = null;
flipY = _drawCount % 2 == 0;
}
else {
// Intermediate draw call - get a temp buffer to draw to
_currentFramebufferIndex = (_currentFramebufferIndex+1) % 2;
target = _getTempFramebuffer(_currentFramebufferIndex).fbo;
}
// Bind the source and target and draw the two triangles
gl.bindTexture(gl.TEXTURE_2D, source);
gl.bindFramebuffer(gl.FRAMEBUFFER, target);
gl.uniform1f(_currentProgram.uniform.flipY, (flipY ? -1 : 1) );
gl.drawArrays(gl.TRIANGLES, 0, 6);
};
var _compileShader = function( fragmentSource ) {
if (_shaderProgramCache[fragmentSource]) {
_currentProgram = _shaderProgramCache[fragmentSource];
gl.useProgram(_currentProgram.id);
return _currentProgram;
}
// Compile shaders
_currentProgram = new WebGLProgram( gl, SHADER.VERTEX_IDENTITY, fragmentSource );
var floatSize = Float32Array.BYTES_PER_ELEMENT;
var vertSize = 4 * floatSize;
gl.enableVertexAttribArray(_currentProgram.attribute.pos);
gl.vertexAttribPointer(_currentProgram.attribute.pos, 2, gl.FLOAT, false, vertSize , 0 * floatSize);
gl.enableVertexAttribArray(_currentProgram.attribute.uv);
gl.vertexAttribPointer(_currentProgram.attribute.uv, 2, gl.FLOAT, false, vertSize, 2 * floatSize);
_shaderProgramCache[fragmentSource] = _currentProgram;
return _currentProgram;
};
var DRAW = { INTERMEDIATE: 1 };
var SHADER = {};
SHADER.VERTEX_IDENTITY = [
'precision highp float;',
'attribute vec2 pos;',
'attribute vec2 uv;',
'varying vec2 vUv;',
'uniform float flipY;',
'void main(void) {',
'vUv = uv;',
'gl_Position = vec4(pos.x, pos.y*flipY, 0.0, 1.);',
'}'
].join('\n');
SHADER.FRAGMENT_IDENTITY = [
'precision highp float;',
'varying vec2 vUv;',
'uniform sampler2D texture;',
'void main(void) {',
'gl_FragColor = texture2D(texture, vUv);',
'}',
].join('\n');
var _filter = {};
// -------------------------------------------------------------------------
// Color Matrix Filter
_filter.colorMatrix = function( matrix , amount = 1 ) {
matrix = matrix.map((coef, index) => weightedAvg(coef, identityMatrix[index], amount));
// Create a Float32 Array and normalize the offset component to 0-1
var m = new Float32Array(matrix);
m[4] /= 255;
m[9] /= 255;
m[14] /= 255;
m[19] /= 255;
// Can we ignore the alpha value? Makes things a bit faster.
var shader = (1==m[18]&&0==m[3]&&0==m[8]&&0==m[13]&&0==m[15]&&0==m[16]&&0==m[17]&&0==m[19])
? _filter.colorMatrix.SHADER.WITHOUT_ALPHA
: _filter.colorMatrix.SHADER.WITH_ALPHA;
var program = _compileShader(shader);
gl.uniform1fv(program.uniform.m, m);
_draw();
};
_filter.colorMatrix.SHADER = {};
_filter.colorMatrix.SHADER.WITH_ALPHA = [
'precision highp float;',
'varying vec2 vUv;',
'uniform sampler2D texture;',
'uniform float m[20];',
'void main(void) {',
'vec4 c = texture2D(texture, vUv);',
'gl_FragColor.r = m[0] * c.r + m[1] * c.g + m[2] * c.b + m[3] * c.a + m[4];',
'gl_FragColor.g = m[5] * c.r + m[6] * c.g + m[7] * c.b + m[8] * c.a + m[9];',
'gl_FragColor.b = m[10] * c.r + m[11] * c.g + m[12] * c.b + m[13] * c.a + m[14];',
'gl_FragColor.a = m[15] * c.r + m[16] * c.g + m[17] * c.b + m[18] * c.a + m[19];',
'}',
].join('\n');
_filter.colorMatrix.SHADER.WITHOUT_ALPHA = [
'precision highp float;',
'varying vec2 vUv;',
'uniform sampler2D texture;',
'uniform float m[20];',
'void main(void) {',
'vec4 c = texture2D(texture, vUv);',
'gl_FragColor.r = m[0] * c.r + m[1] * c.g + m[2] * c.b + m[4];',
'gl_FragColor.g = m[5] * c.r + m[6] * c.g + m[7] * c.b + m[9];',
'gl_FragColor.b = m[10] * c.r + m[11] * c.g + m[12] * c.b + m[14];',
'gl_FragColor.a = c.a;',
'}',
].join('\n');
_filter.brightness = function( brightness ) {
var b = (brightness || 0) + 1;
_filter.colorMatrix([
b, 0, 0, 0, 0,
0, b, 0, 0, 0,
0, 0, b, 0, 0,
0, 0, 0, 1, 0
]);
};
_filter.saturation = function( amount ) {
var x = (amount || 0) * 2/3 + 1;
var y = ((x-1) *-0.5);
_filter.colorMatrix([
x, y, y, 0, 0,
y, x, y, 0, 0,
y, y, x, 0, 0,
0, 0, 0, 1, 0
]);
};
_filter.desaturate = function() {
_filter.saturation(-1);
};
_filter.contrast = function( amount ) {
var v = (amount || 0) + 1;
var o = -128 * (v-1);
_filter.colorMatrix([
v, 0, 0, 0, o,
0, v, 0, 0, o,
0, 0, v, 0, o,
0, 0, 0, 1, 0
]);
};
_filter.negative = function() {
_filter.contrast(-2);
};
_filter.hue = function( rotation ) {
rotation = (rotation || 0)/180 * Math.PI;
var cos = Math.cos(rotation),
sin = Math.sin(rotation),
lumR = 0.213,
lumG = 0.715,
lumB = 0.072;
_filter.colorMatrix([
lumR+cos*(1-lumR)+sin*(-lumR),lumG+cos*(-lumG)+sin*(-lumG),lumB+cos*(-lumB)+sin*(1-lumB),0,0,
lumR+cos*(-lumR)+sin*(0.143),lumG+cos*(1-lumG)+sin*(0.140),lumB+cos*(-lumB)+sin*(-0.283),0,0,
lumR+cos*(-lumR)+sin*(-(1-lumR)),lumG+cos*(-lumG)+sin*(lumG),lumB+cos*(1-lumB)+sin*(lumB),0,0,
0, 0, 0, 1, 0
]);
};
_filter.desaturateLuminance = function( amount ) {
_filter.colorMatrix([
0.2764723, 0.9297080, 0.0938197, 0, -37.1,
0.2764723, 0.9297080, 0.0938197, 0, -37.1,
0.2764723, 0.9297080, 0.0938197, 0, -37.1,
0, 0, 0, 1, 0
], amount);
};
_filter.sepia = function( amount ) {
_filter.colorMatrix([
0.393, 0.7689999, 0.18899999, 0, 0,
0.349, 0.6859999, 0.16799999, 0, 0,
0.272, 0.5339999, 0.13099999, 0, 0,
0,0,0,1,0
], amount);
};
_filter.brownie = function( amount ) {
_filter.colorMatrix([
0.5997023498159715,0.34553243048391263,-0.2708298674538042,0,47.43192855600873,
-0.037703249837783157,0.8609577587992641,0.15059552388459913,0,-36.96841498319127,
0.24113635128153335,-0.07441037908422492,0.44972182064877153,0,-7.562075277591283,
0,0,0,1,0
], amount);
};
_filter.vintagePinhole = function( amount ) {
_filter.colorMatrix([
0.6279345635605994,0.3202183420819367,-0.03965408211312453,0,9.651285835294123,
0.02578397704808868,0.6441188644374771,0.03259127616149294,0,7.462829176470591,
0.0466055556782719,-0.0851232987247891,0.5241648018700465,0,5.159190588235296,
0,0,0,1,0
], amount);
};
_filter.kodachrome = function( amount ) {
_filter.colorMatrix([
1.1285582396593525,-0.3967382283601348,-0.03992559172921793,0,63.72958762196502,
-0.16404339962244616,1.0835251566291304,-0.05498805115633132,0,24.732407896706203,
-0.16786010706155763,-0.5603416277695248,1.6014850761964943,0,35.62982807460946,
0,0,0,1,0
], amount);
};
_filter.technicolor = function( amount ) {
_filter.colorMatrix([
1.9125277891456083,-0.8545344976951645,-0.09155508482755585,0,11.793603434377337,
-0.3087833385928097,1.7658908555458428,-0.10601743074722245,0,-70.35205161461398,
-0.231103377548616,-0.7501899197440212,1.847597816108189,0,30.950940869491138,
0,0,0,1,0
], amount);
};
_filter.polaroid = function( amount ) {
_filter.colorMatrix([
1.438,-0.062,-0.062,0,0,
-0.122,1.378,-0.122,0,0,
-0.016,-0.016,1.483,0,0,
0,0,0,1,0
], amount);
};
_filter.shiftToBGR = function(amount) {
_filter.colorMatrix([
0,0,1,0,0,
0,1,0,0,0,
1,0,0,0,0,
0,0,0,1,0
], amount);
};
// -------------------------------------------------------------------------
// Convolution Filter
_filter.convolution = function( matrix ) {
var m = new Float32Array(matrix);
var pixelSizeX = 1 / _width;
var pixelSizeY = 1 / _height;
var program = _compileShader(_filter.convolution.SHADER);
gl.uniform1fv(program.uniform.m, m);
gl.uniform2f(program.uniform.px, pixelSizeX, pixelSizeY);
_draw();
};
_filter.convolution.SHADER = [
'precision highp float;',
'varying vec2 vUv;',
'uniform sampler2D texture;',
'uniform vec2 px;',
'uniform float m[9];',
'void main(void) {',
'vec4 c11 = texture2D(texture, vUv - px);', // top left
'vec4 c12 = texture2D(texture, vec2(vUv.x, vUv.y - px.y));', // top center
'vec4 c13 = texture2D(texture, vec2(vUv.x + px.x, vUv.y - px.y));', // top right
'vec4 c21 = texture2D(texture, vec2(vUv.x - px.x, vUv.y) );', // mid left
'vec4 c22 = texture2D(texture, vUv);', // mid center
'vec4 c23 = texture2D(texture, vec2(vUv.x + px.x, vUv.y) );', // mid right
'vec4 c31 = texture2D(texture, vec2(vUv.x - px.x, vUv.y + px.y) );', // bottom left
'vec4 c32 = texture2D(texture, vec2(vUv.x, vUv.y + px.y) );', // bottom center
'vec4 c33 = texture2D(texture, vUv + px );', // bottom right
'gl_FragColor = ',
'c11 * m[0] + c12 * m[1] + c22 * m[2] +',
'c21 * m[3] + c22 * m[4] + c23 * m[5] +',
'c31 * m[6] + c32 * m[7] + c33 * m[8];',
'gl_FragColor.a = c22.a;',
'}',
].join('\n');
_filter.detectEdges = function() {
_filter.convolution.call(this, [
0, 1, 0,
1, -4, 1,
0, 1, 0
]);
};
_filter.sobelX = function() {
_filter.convolution.call(this, [
-1, 0, 1,
-2, 0, 2,
-1, 0, 1
]);
};
_filter.sobelY = function() {
_filter.convolution.call(this, [
-1, -2, -1,
0, 0, 0,
1, 2, 1
]);
};
_filter.sharpen = function( amount ) {
var a = amount || 1;
_filter.convolution.call(this, [
0, -1*a, 0,
-1*a, 1 + 4*a, -1*a,
0, -1*a, 0
]);
};
_filter.emboss = function( size ) {
var s = size || 1;
_filter.convolution.call(this, [
-2*s, -1*s, 0,
-1*s, 1, 1*s,
0, 1*s, 2*s
]);
};
// -------------------------------------------------------------------------
// Blur Filter
_filter.blur = function( size ) {
var blurSizeX = (size/7) / _width;
var blurSizeY = (size/7) / _height;
var program = _compileShader(_filter.blur.SHADER);
// Vertical
gl.uniform2f(program.uniform.px, 0, blurSizeY);
_draw(DRAW.INTERMEDIATE);
// Horizontal
gl.uniform2f(program.uniform.px, blurSizeX, 0);
_draw();
};
_filter.blur.SHADER = [
'precision highp float;',
'varying vec2 vUv;',
'uniform sampler2D texture;',
'uniform vec2 px;',
'void main(void) {',
'gl_FragColor = vec4(0.0);',
'gl_FragColor += texture2D(texture, vUv + vec2(-7.0*px.x, -7.0*px.y))*0.0044299121055113265;',
'gl_FragColor += texture2D(texture, vUv + vec2(-6.0*px.x, -6.0*px.y))*0.00895781211794;',
'gl_FragColor += texture2D(texture, vUv + vec2(-5.0*px.x, -5.0*px.y))*0.0215963866053;',
'gl_FragColor += texture2D(texture, vUv + vec2(-4.0*px.x, -4.0*px.y))*0.0443683338718;',
'gl_FragColor += texture2D(texture, vUv + vec2(-3.0*px.x, -3.0*px.y))*0.0776744219933;',
'gl_FragColor += texture2D(texture, vUv + vec2(-2.0*px.x, -2.0*px.y))*0.115876621105;',
'gl_FragColor += texture2D(texture, vUv + vec2(-1.0*px.x, -1.0*px.y))*0.147308056121;',
'gl_FragColor += texture2D(texture, vUv )*0.159576912161;',
'gl_FragColor += texture2D(texture, vUv + vec2( 1.0*px.x, 1.0*px.y))*0.147308056121;',
'gl_FragColor += texture2D(texture, vUv + vec2( 2.0*px.x, 2.0*px.y))*0.115876621105;',
'gl_FragColor += texture2D(texture, vUv + vec2( 3.0*px.x, 3.0*px.y))*0.0776744219933;',
'gl_FragColor += texture2D(texture, vUv + vec2( 4.0*px.x, 4.0*px.y))*0.0443683338718;',
'gl_FragColor += texture2D(texture, vUv + vec2( 5.0*px.x, 5.0*px.y))*0.0215963866053;',
'gl_FragColor += texture2D(texture, vUv + vec2( 6.0*px.x, 6.0*px.y))*0.00895781211794;',
'gl_FragColor += texture2D(texture, vUv + vec2( 7.0*px.x, 7.0*px.y))*0.0044299121055113265;',
'}',
].join('\n');
// -------------------------------------------------------------------------
// Pixelate Filter
_filter.pixelate = function( size ) {
var blurSizeX = (size) / _width;
var blurSizeY = (size) / _height;
var program = _compileShader(_filter.pixelate.SHADER);
// Horizontal
gl.uniform2f(program.uniform.size, blurSizeX, blurSizeY);
_draw();
};
_filter.pixelate.SHADER = [
'precision highp float;',
'varying vec2 vUv;',
'uniform vec2 size;',
'uniform sampler2D texture;',
'vec2 pixelate(vec2 coord, vec2 size) {',
'return floor( coord / size ) * size;',
'}',
'void main(void) {',
'gl_FragColor = vec4(0.0);',
'vec2 coord = pixelate(vUv, size);',
'gl_FragColor += texture2D(texture, coord);',
'}',
].join('\n');
};
})(window);