diff options
author | pommicket <pommicket@gmail.com> | 2023-06-27 12:12:57 -0400 |
---|---|---|
committer | pommicket <pommicket@gmail.com> | 2023-06-27 12:12:57 -0400 |
commit | cf17787c40d00d54fa14b92232c273157347c771 (patch) | |
tree | 246cd8b0dc68a5b1c37cfcf0dd0552f1d223c934 /fractiform.js | |
parent | f3d0672365a81ca95bb9783552d5d1e9fed6e60f (diff) |
tooltips
Diffstat (limited to 'fractiform.js')
-rw-r--r-- | fractiform.js | 62 |
1 files changed, 48 insertions, 14 deletions
diff --git a/fractiform.js b/fractiform.js index cd40e79..7ef2c2f 100644 --- a/fractiform.js +++ b/fractiform.js @@ -37,13 +37,18 @@ let width = 1920, height = 1920; const widget_info = { 'mix': { name: 'Mix', + tooltip: 'weighted average of two inputs', inputs: [ {name: 'source 1', id: 'src1'}, {name: 'source 2', id: 'src2'}, {name: 'mix', id: 'mix'}, ], - controls: [{name: 'clamp mix', id: 'clamp', type: 'checkbox'}], - outputs: [{name: 'out', id: 'out'}], + controls: [ + {name: 'clamp mix', id: 'clamp', type: 'checkbox', tooltip: 'clamp the mix input to the [0, 1] range'} + ], + outputs: [ + {name: 'out', id: 'out', tooltip: 'mix × (source 1) + (1 - mix) × (source 2)'} + ], func: function(state, inputs) { let src1 = inputs.src1; let src2 = inputs.src2; @@ -71,12 +76,13 @@ const widget_info = { }, 'prev': { name: 'Last frame', - inputs: [{name: 'pos', id: 'pos'}], + tooltip: 'sample from the previous frame', + inputs: [{name: 'pos', id: 'pos', tooltip: 'position to sample — bottom-left corner is (0, 0), top-right corner is (1, 1)'}], controls: [ - {name: 'wrap mode', id: 'wrap', type: 'checkbox'}, - {name: 'sample mode', id: 'sample', type: 'select:linear|nearest'}, + {name: 'wrap mode', id: 'wrap', type: 'select:clamp|wrap', tooltip: 'how to deal with the input components if they go outside [0, 1]'}, + {name: 'sample mode', id: 'sample', type: 'select:linear|nearest', tooltip: 'how positions in between pixels should be sampled'}, ], - outputs: [{name: 'out', id: 'out'}], + outputs: [{name: 'out', id: 'out', tooltip: 'the color from the previous frame'}], func: function(state, inputs) { let pos = inputs.pos; if (pos.type !== 'vec2') { @@ -84,16 +90,25 @@ const widget_info = { } let vpos = state.next_variable(); state.add_code(`vec2 ${vpos} = ${pos.code};\n`); - if (inputs.wrap) { + switch (inputs.wrap) { + case 'wrap': state.add_code(`${vpos} = mod(${vpos}, 1.0);\n`); + break; + case 'clamp': + state.add_code(`${vpos} = clamp(${vpos}, 0.0, 1.0);\n`); + break; + default: + console.error('bad wrap mode:', inputs.wrap); + break; } + switch (inputs.sample) { case 'linear': break; case 'nearest': state.add_code(`${vpos} = floor(0.5 + ${vpos} * u_texture_size) * (1.0 / u_texture_size);\n`); break; default: - console.error('bad sample method:', inputs['sample method']); + console.error('bad sample method:', inputs.sample); break; } let v = state.next_variable(); @@ -112,6 +127,7 @@ const widget_info = { }, 'mul': { name: 'Multiply', + tooltip: 'multiply two numbers, scale a vector by a number, or perform component-wise multiplication between vectors', inputs: [{name: 'a', id: 'a'}, {name: 'b', id: 'b'}], controls: [], outputs: [{name: 'out', id: 'out'}], @@ -129,6 +145,7 @@ const widget_info = { }, 'mod': { name: 'Modulo', + tooltip: 'wrap a value at a certain limit', inputs: [{name: 'a', id: 'a'}, {name: 'b', id: 'b'}], controls: [], outputs: [{name: 'out', id: 'out'}], @@ -147,11 +164,12 @@ const widget_info = { }, 'square': { name: 'Square', + tooltip: 'select between two inputs depending on whether a point lies within a square (or cube in 3D)', inputs: [ - {name: 'pos', id: 'pos'}, - {name: 'inside', id: 'inside'}, - {name: 'outside', id: 'outside'}, - {name: 'size', id: 'size'} + {name: 'pos', id: 'pos', tooltip: 'point to test'}, + {name: 'inside', id: 'inside', tooltip: 'source to use if pos lies inside the square'}, + {name: 'outside', id: 'outside', tooltip: 'source to use if pos lies outside the square'}, + {name: 'size', id: 'size', tooltip: 'radius of the square'}, ], controls: [], outputs: [{name: 'out', id: 'out'}], @@ -403,6 +421,9 @@ function add_widget(func) { { // title let title = document.createElement('div'); title.classList.add('widget-title'); + if ('tooltip' in info) { + title.title = info.tooltip; + } title.appendChild(document.createTextNode(info.name)); if (func !== 'output') { let name_input = document.createElement('input'); @@ -428,7 +449,7 @@ function add_widget(func) { } // inputs - for (let input of info.inputs) { + info.inputs.forEach(function (input) { let container = document.createElement('div'); container.classList.add('in'); console.assert('id' in input, 'input missing ID', input); @@ -438,12 +459,15 @@ function add_widget(func) { input_element.id = 'gen-input-' + (++html_id); let label = document.createElement('label'); label.htmlFor = input_element.id; + if ('tooltip' in input) { + label.title = input.tooltip; + } label.appendChild(document.createTextNode(input.name)); container.appendChild(input_element); container.appendChild(document.createTextNode(' ')); container.appendChild(label); root.appendChild(container); - } + }); // controls for (let control of info.controls) { @@ -475,6 +499,9 @@ function add_widget(func) { let label = document.createElement('label'); label.htmlFor = input.id; label.appendChild(document.createTextNode(control.name)); + if ('tooltip' in control) { + label.title = control.tooltip; + } container.appendChild(input); container.appendChild(document.createTextNode(' ')); container.appendChild(label); @@ -491,6 +518,9 @@ function add_widget(func) { let span = document.createElement('span'); span.classList.add('out'); span.appendChild(document.createTextNode(output.name)); + if ('tooltip' in output) { + span.title = output.tooltip; + } container.appendChild(span); }); root.appendChild(container); @@ -905,10 +935,14 @@ void main() { framebuffer_color_texture = gl.createTexture(); sampler_texture = gl.createTexture(); + // add widget buttons for (let id of widget_ids_sorted_by_name) { let widget = widget_info[id]; let button = document.createElement('button'); button.classList.add('widget-choice'); + if ('tooltip' in widget) { + button.title = widget.tooltip; + } button.appendChild(document.createTextNode(widget.name)); widget_choices.appendChild(button); button.addEventListener('click', function (e) { |