Flask application which powers the conceptnull.org website, using MediaWiki as it's backend.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

252 lines
6.8 KiB

//
(function() {
// list of guis
var guis = [];
// default slider params
var sliderMin = 0;
var sliderMax = 100;
var sliderStep = 1;
// default gui provider
var guiProvider = 'QuickSettings';
const defaultLabel = 'p5.gui';
// Create a GUI using QuickSettings (or DAT.GUI or ...)
// You only need to pass a reference to the sketch in instance mode
// Usually you will call createGui(this, 'label');
p5.prototype.createGui = function(sketch, label, provider) {
// createGui(label) signature
if ((typeof sketch) === 'string') {
return this.createGui(label, sketch, provider);
}
// normally the sketch will just be embedded below the body
let parent = document.body;
if(sketch === undefined) {
// p5js global mode
sketch = window;
label = label || document.title || defaultLabel;
} else {
// p5js instance mode
parent = sketch.canvas.parentElement;
label = label || parent.id || defaultLabel;
}
if(!('color' in sketch)) {
console.error(`${parent.id}: You need to pass the p5 sketch to createGui in instance mode!`);
}
// default gui provider
provider = provider || guiProvider;
var gui;
// create a gui using the provider
if(provider === 'QuickSettings') {
if(QuickSettings) {
console.log('Creating p5.gui powered by QuickSettings.');
gui = new QSGui(label, parent, sketch);
} else {
console.log('QuickSettings not found. Is the script included in your HTML?');
gui = new DummyGui(label, parent, sketch);
}
} else {
console.log('Unknown GUI provider ' + provider);
gui = new DummyGui(label, parent, sketch);
}
// add it to the list of guis
guis.push(gui);
// return it
return gui;
};
p5.prototype.removeGui = function(gui) {
// TODO: implement this
};
// update defaults used for creation of sliders
p5.prototype.sliderRange = function(vmin, vmax, vstep) {
sliderMin = vmin;
sliderMax = vmax;
sliderStep = vstep;
};
// extend default behaviour of noLoop()
p5.prototype.noLoop = function() {
this._loop = false;
for(var i = 0; i < guis.length; i++) {
guis[i].noLoop();
}
};
// extend default behaviour of loop()
p5.prototype.loop = function() {
for(var i = 0; i < guis.length; i++) {
guis[i].loop();
}
this._loop = true;
this._draw();
};
// interface for quicksettings
function QSGui(label, parent, sketch) {
// hard code the position, it can be changed later
let x = 20;
let y = 20;
var qs = QuickSettings.create(x, y, label, parent);
// proxy all functions of quicksettings
this.prototype = qs;
// addGlobals(global1, global2, ...) to add the selected globals
this.addGlobals = function() {
qs.bindGlobals(arguments);
};
// addObject(object) to add all params of the object
// addObject(object, param1, param2, ...) to add selected params
this.addObject = function() {
// get object
object = arguments[0];
// convert arguments object to array
var params = [];
if(arguments.length > 1) {
params = Array.prototype.slice.call(arguments)
params = params.slice(1);
}
// if no arguments are provided take all keys of the object
if(params.length === 0) {
// won't work in Internet Explorer < 9 (use a polyfill)
params = Object.keys(object);
}
qs.bindParams(object, params);
};
// noLoop() to call draw every time the gui changes when we are not looping
this.noLoop = function() {
qs.setGlobalChangeHandler(sketch._draw);
};
this.loop = function() {
qs.setGlobalChangeHandler(null);
};
// pass through ...
this.show = function() { qs.show(); };
this.hide = function() { qs.hide(); };
this.toggleVisibility = function() { qs.toggleVisibility(); };
this.setPosition = function(x, y) {
qs.setPosition(x, y);
return this;
};
// Extend Quicksettings
// so it can magically create a GUI for parameters passed by name
qs.bindParams = function(object, params) {
// iterate over all the arguments
for(var i = 0; i < params.length; i++) {
var arg = params[i];
var val = object[arg];
var typ = typeof val;
//console.log(typ, arg, val);
// don't need to show the sliders for range min, max and step of a property
var sliderConfigRegEx = /^(.*min|.*max|.*step)$/i;
if( sliderConfigRegEx.test(arg)){
continue;
}
switch(typ) {
case 'object':
// color triple ?
if(val instanceof Array && val.length === 3 && typeof val[0] === 'number') {
// create color according to the current color mode of the current sketch
var c = sketch.color(val[0], val[1], val[2]);
// get decimal RGB values
var c2 = c.levels.slice(0,3);
// create HTML color code
var vcolor = '#' + c2.map(function(value) {
return ('0' + value.toString(16)).slice(-2);
}).join('');
this.bindColor(arg, vcolor, object);
} else {
// multiple choice drop down list
this.bindDropDown(arg, val, object);
object[arg] = val[0];
}
break;
case 'number':
// values as defined by magic variables or gui.sliderRange()
var vmin = object[arg + 'Min'] || object[arg + 'min'] || sliderMin;
var vmax = object[arg + 'Max'] || object[arg + 'max'] || sliderMax;
var vstep = object[arg + 'Step'] || object[arg + 'step'] || sliderStep;
// the actual values can still overrule the limits set by magic
var vmin = Math.min(val, vmin);
var vmax = Math.max(val, vmax);
// set the range
this.bindRange(arg, vmin, vmax, val, vstep, object);
break;
case 'string':
var HEX6 = /^#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})$/i;
if(HEX6.test(val)) {
// HTML color value (such as #ff0000)
this.bindColor(arg, val, object);
} else {
// String value
this.bindText(arg, val, object);
}
break;
case 'boolean':
this.bindBoolean(arg, object[arg], object);
break;
}
}
};
// bind params that are defined globally
qs.bindGlobals = function(params) {
this.bindParams(window, params);
};
}
// Just a Dummy object that provides the GUI interface
function DummyGui() {
var f = function() {};
this.addGlobals = f;
this.noLoop = f;
this.addObject = f;
this.show = f;
}
})();