1// 2 3(function() { 4 5 // list of guis 6 var guis = []; 7 8 // default slider params 9 var sliderMin = 0; 10 var sliderMax = 100; 11 var sliderStep = 1; 12 13 // default gui provider 14 var guiProvider = 'QuickSettings'; 15 16 const defaultLabel = 'p5.gui'; 17 18 // Create a GUI using QuickSettings (or DAT.GUI or ...) 19 // You only need to pass a reference to the sketch in instance mode 20 21 // Usually you will call createGui(this, 'label'); 22 p5.prototype.createGui = function(sketch, label, provider) { 23 24 // createGui(label) signature 25 if ((typeof sketch) === 'string') { 26 return this.createGui(label, sketch, provider); 27 } 28 29 // normally the sketch will just be embedded below the body 30 let parent = document.body; 31 32 if(sketch === undefined) { 33 // p5js global mode 34 sketch = window; 35 label = label || document.title || defaultLabel; 36 } else { 37 // p5js instance mode 38 parent = sketch.canvas.parentElement; 39 label = label || parent.id || defaultLabel; 40 } 41 42 if(!('color' in sketch)) { 43 console.error(`${parent.id}: You need to pass the p5 sketch to createGui in instance mode!`); 44 } 45 46 // default gui provider 47 provider = provider || guiProvider; 48 49 var gui; 50 51 // create a gui using the provider 52 if(provider === 'QuickSettings') { 53 if(QuickSettings) { 54 console.log('Creating p5.gui powered by QuickSettings.'); 55 gui = new QSGui(label, parent, sketch); 56 } else { 57 console.log('QuickSettings not found. Is the script included in your HTML?'); 58 gui = new DummyGui(label, parent, sketch); 59 } 60 } else { 61 console.log('Unknown GUI provider ' + provider); 62 gui = new DummyGui(label, parent, sketch); 63 } 64 65 // add it to the list of guis 66 guis.push(gui); 67 68 // return it 69 return gui; 70 71 }; 72 73 74 p5.prototype.removeGui = function(gui) { 75 // TODO: implement this 76 }; 77 78 // update defaults used for creation of sliders 79 p5.prototype.sliderRange = function(vmin, vmax, vstep) { 80 sliderMin = vmin; 81 sliderMax = vmax; 82 sliderStep = vstep; 83 }; 84 85 // extend default behaviour of noLoop() 86 p5.prototype.noLoop = function() { 87 this._loop = false; 88 for(var i = 0; i < guis.length; i++) { 89 guis[i].noLoop(); 90 } 91 }; 92 93 // extend default behaviour of loop() 94 p5.prototype.loop = function() { 95 for(var i = 0; i < guis.length; i++) { 96 guis[i].loop(); 97 } 98 this._loop = true; 99 this._draw(); 100 }; 101 102 103 // interface for quicksettings 104 function QSGui(label, parent, sketch) { 105 106 // hard code the position, it can be changed later 107 let x = 20; 108 let y = 20; 109 110 var qs = QuickSettings.create(x, y, label, parent); 111 112 // proxy all functions of quicksettings 113 this.prototype = qs; 114 115 // addGlobals(global1, global2, ...) to add the selected globals 116 this.addGlobals = function() { 117 qs.bindGlobals(arguments); 118 }; 119 120 // addObject(object) to add all params of the object 121 // addObject(object, param1, param2, ...) to add selected params 122 this.addObject = function() { 123 // get object 124 object = arguments[0]; 125 // convert arguments object to array 126 var params = []; 127 if(arguments.length > 1) { 128 params = Array.prototype.slice.call(arguments) 129 params = params.slice(1); 130 } 131 // if no arguments are provided take all keys of the object 132 if(params.length === 0) { 133 // won't work in Internet Explorer < 9 (use a polyfill) 134 params = Object.keys(object); 135 } 136 qs.bindParams(object, params); 137 }; 138 139 // noLoop() to call draw every time the gui changes when we are not looping 140 this.noLoop = function() { 141 qs.setGlobalChangeHandler(sketch._draw); 142 }; 143 144 this.loop = function() { 145 qs.setGlobalChangeHandler(null); 146 }; 147 148 // pass through ... 149 this.show = function() { qs.show(); }; 150 this.hide = function() { qs.hide(); }; 151 this.toggleVisibility = function() { qs.toggleVisibility(); }; 152 this.setPosition = function(x, y) { 153 qs.setPosition(x, y); 154 return this; 155 }; 156 157 // Extend Quicksettings 158 // so it can magically create a GUI for parameters passed by name 159 qs.bindParams = function(object, params) { 160 161 // iterate over all the arguments 162 for(var i = 0; i < params.length; i++) { 163 164 var arg = params[i]; 165 var val = object[arg]; 166 var typ = typeof val; 167 168 //console.log(typ, arg, val); 169 170 // don't need to show the sliders for range min, max and step of a property 171 var sliderConfigRegEx = /^(.*min|.*max|.*step)$/i; 172 if( sliderConfigRegEx.test(arg)){ 173 continue; 174 } 175 switch(typ) { 176 177 case 'object': 178 179 // color triple ? 180 if(val instanceof Array && val.length === 3 && typeof val[0] === 'number') { 181 // create color according to the current color mode of the current sketch 182 var c = sketch.color(val[0], val[1], val[2]); 183 // get decimal RGB values 184 var c2 = c.levels.slice(0,3); 185 // create HTML color code 186 var vcolor = '#' + c2.map(function(value) { 187 return ('0' + value.toString(16)).slice(-2); 188 }).join(''); 189 this.bindColor(arg, vcolor, object); 190 } else { 191 // multiple choice drop down list 192 this.bindDropDown(arg, val, object); 193 object[arg] = val[0]; 194 } 195 break; 196 197 case 'number': 198 199 // values as defined by magic variables or gui.sliderRange() 200 var vmin = object[arg + 'Min'] || object[arg + 'min'] || sliderMin;
201 var vmax = object[arg + 'Max'] || object[arg + 'max'] || sliderMax; 202 var vstep = object[arg + 'Step'] || object[arg + 'step'] || sliderStep; 203 204 // the actual values can still overrule the limits set by magic 205 var vmin = Math.min(val, vmin); 206 var vmax = Math.max(val, vmax); 207 208 // set the range 209 this.bindRange(arg, vmin, vmax, val, vstep, object); 210 211 break; 212 213 case 'string': 214 215 var HEX6 = /^#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})$/i; 216 if(HEX6.test(val)) { 217 // HTML color value (such as #ff0000) 218 this.bindColor(arg, val, object); 219 } else { 220 // String value 221 this.bindText(arg, val, object); 222 } 223 break; 224 225 case 'boolean': 226 227 this.bindBoolean(arg, object[arg], object); 228 break; 229 230 } 231 } 232 }; 233 234 // bind params that are defined globally 235 qs.bindGlobals = function(params) { 236 this.bindParams(window, params); 237 }; 238 239 } 240 241 // Just a Dummy object that provides the GUI interface 242 function DummyGui() { 243 var f = function() {}; 244 this.addGlobals = f; 245 this.noLoop = f; 246 this.addObject = f; 247 this.show = f; 248 } 249 250 251})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.