summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2023-08-02 11:58:17 -0400
committerpommicket <pommicket@gmail.com>2023-08-02 11:58:17 -0400
commitacf6239d7cef85d37fa71e6495c3562a58aa8d4e (patch)
tree7f627c2369ddb90f8b1bce14845ebb020125f63e
parent94d836d9c7b84d59ffffc9ace926d8aca4368bbd (diff)
click widget type to set output
-rw-r--r--.eslintrc.json5
-rw-r--r--fractiform.js170
-rw-r--r--index.html8
3 files changed, 77 insertions, 106 deletions
diff --git a/.eslintrc.json b/.eslintrc.json
index 0d52951..2a790cd 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -33,6 +33,9 @@
{
"destructuring": "all"
}
- ]
+ ],
+ // prettier has control of indentation
+ "indent": ["off"],
+ "no-mixed-spaces-and-tabs": ["off"]
}
}
diff --git a/fractiform.js b/fractiform.js
index 261ec38..74501a9 100644
--- a/fractiform.js
+++ b/fractiform.js
@@ -28,6 +28,10 @@ let parsed_widgets;
const width = 1920,
height = 1920;
+const GLSL_FLOAT_TYPES = ['float', 'vec2', 'vec3', 'vec4'];
+const GLSL_FLOAT_TYPE_PAIRS = GLSL_FLOAT_TYPES.flatMap((x) =>
+ GLSL_FLOAT_TYPES.map((y) => [x, y]),
+);
const builtin_widgets = [
`
@@ -37,14 +41,12 @@ const builtin_widgets = [
//! x.name: input
//! x.id: input
` +
- ['float', 'vec2', 'vec3', 'vec4']
- .map(
- (type) => `
+ GLSL_FLOAT_TYPES.map(
+ (type) => `
${type} buffer(${type} x) {
return x;
}`,
- )
- .join('\n'),
+ ).join('\n'),
`
//! .name: Slider
//! .category: basic
@@ -76,16 +78,14 @@ float slider(float x, float min_val, float max_val) {
//! c.control: checkbox
//! c.description: clamp the mix input to the [0, 1] range
` +
- ['float', 'vec2', 'vec3', 'vec4']
- .map(
- (type) => `
+ GLSL_FLOAT_TYPES.map(
+ (type) => `
${type} mix_(${type} a, ${type} b, ${type} x, int c) {
if (c != 0) x = clamp(x, 0.0, 1.0);
return mix(a, b, x);
}
`,
- )
- .join('\n'),
+ ).join('\n'),
`
//! .name: Last frame
//! .category: basic
@@ -120,44 +120,38 @@ vec3 last_frame(vec2 pos, int wrap, int sample) {
//! bw.default: 1
` +
- ['float', 'vec2', 'vec3', 'vec4']
- .map(
- (type) => `
+ GLSL_FLOAT_TYPES.map(
+ (type) => `
${type} wtadd(${type} a, float aw, ${type} b, float bw) {
return a * aw + b * bw;
}
`,
- )
- .join('\n'),
+ ).join('\n'),
`
//! .name: Multiply
//! .category: math
//! .description: multiply two numbers, scale a vector by a number, or perform component-wise multiplication between vectors
` +
- ['float', 'vec2', 'vec3', 'vec4']
- .map(
- (type) => `
+ GLSL_FLOAT_TYPES.map(
+ (type) => `
${type} mul(${type} a, ${type} b) {
return a * b;
}
`,
- )
- .join('\n'),
+ ).join('\n'),
`
//! .name: Power
//! .category: math
//! .id: pow
//! .description: take one number to the power of another
` +
- ['float', 'vec2', 'vec3', 'vec4']
- .map(
- (type) => `
+ GLSL_FLOAT_TYPES.map(
+ (type) => `
${type} pow_(${type} a, ${type} b) {
return pow(a, b);
}
`,
- )
- .join('\n'),
+ ).join('\n'),
`
//! .name: Modulo
//! .category: math
@@ -166,15 +160,13 @@ ${type} pow_(${type} a, ${type} b) {
//! a.name: a
//! b.default: 1
` +
- ['float', 'vec2', 'vec3', 'vec4']
- .map(
- (type) => `
+ GLSL_FLOAT_TYPES.map(
+ (type) => `
${type} mod_(${type} a, ${type} b) {
return mod(a, b);
}
`,
- )
- .join('\n'),
+ ).join('\n'),
`
//! .name: Square
//! .category: geometry
@@ -225,20 +217,14 @@ ${type2} square(${type} pos, ${type2} inside, ${type2} outside, ${type} size) {
//! size.description: radius of the circle
` +
- ['float', 'vec2', 'vec3', 'vec4']
- .map((type) => {
- return ['float', 'vec2', 'vec3', 'vec4']
- .map(
- (type2) => `
+ GLSL_FLOAT_TYPE_PAIRS.map(
+ ([type, type2]) => `
${type2} circle(${type} pos, ${type2} inside, ${type2} outside, ${type} size) {
pos /= size;
return dot(pos, pos) < 1.0 ? inside : outside;
}
`,
- )
- .join('\n');
- })
- .join('\n'),
+ ).join('\n'),
`
//! .name: Comparator
//! .category: basic
@@ -256,15 +242,13 @@ ${type2} circle(${type} pos, ${type2} inside, ${type2} outside, ${type} size) {
//! greater.default: 1
//! greater.description: value to output if "Compare 1" ≥ "Compare 2"
` +
- ['float', 'vec2', 'vec3', 'vec4']
- .map(
- (type) => `
+ GLSL_FLOAT_TYPES.map(
+ (type) => `
${type} compare(float cmp1, float cmp2, ${type} less, ${type} greater) {
return cmp1 < cmp2 ? less : greater;
}
`,
- )
- .join('\n'),
+ ).join('\n'),
`
//! .name: Wave
//! .category: curves
@@ -288,9 +272,8 @@ ${type} compare(float cmp1, float cmp2, ${type} less, ${type} greater) {
//! nonneg.control: checkbox
` +
- ['float', 'vec2', 'vec3', 'vec4']
- .map(
- (type) => `
+ GLSL_FLOAT_TYPES.map(
+ (type) => `
${type} sine_wave(int type, ${type} t, ${type} period, ${type} amp, ${type} phase, ${type} center, int nonneg) {
${type} v = ${type}(0.0);
t = t / period - phase;
@@ -309,8 +292,7 @@ ${type} sine_wave(int type, ${type} t, ${type} period, ${type} amp, ${type} phas
return amp * v + center;
}
`,
- )
- .join('\n'),
+ ).join('\n'),
`
//! .name: Rotate 2D
//! .category: geometry
@@ -402,17 +384,15 @@ vec3 saturate(vec3 color, float amount) {
//! contrast.description: how much to change contrast by (−1 to 1 range)
` +
- ['float', 'vec2', 'vec3', 'vec4']
- .map(
- (type) => `
+ GLSL_FLOAT_TYPES.map(
+ (type) => `
${type} brightcont(${type} color, ${type} brightness, ${type} contrast) {
brightness = clamp(brightness, -1.0, 1.0);
contrast = clamp(contrast, -1.0, 1.0);
return clamp((contrast + 1.0) / (1.0 - contrast) * (color - 0.5) + (brightness + 0.5), 0.0, 1.0);
}
`,
- )
- .join('\n'),
+ ).join('\n'),
`
//! .name: Clamp
//! .category: basic
@@ -426,15 +406,13 @@ ${type} brightcont(${type} color, ${type} brightness, ${type} contrast) {
//! maximum.name: max
//! maximum.id: max
` +
- ['float', 'vec2', 'vec3', 'vec4']
- .map(
- (type) => `
+ GLSL_FLOAT_TYPES.map(
+ (type) => `
${type} clamp_(${type} x, ${type} minimum, ${type} maximum) {
return clamp(x, minimum, maximum);
}
`,
- )
- .join('\n'),
+ ).join('\n'),
`
//! .name: Rotate 3D
//! .id: rot3
@@ -475,15 +453,13 @@ vec3 rot3(vec3 v, vec3 axis, float angle) {
//! b2.description: positive endpoint of destination interval
` +
- ['float', 'vec2', 'vec3', 'vec4']
- .map(
- (type) => `
+ GLSL_FLOAT_TYPES.map(
+ (type) => `
${type} remap(${type} x, ${type} a1, ${type} b1, ${type} a2, ${type} b2) {
return (x - a1) / (b1 - a1) * (b2 - a2) + a2;
}
`,
- )
- .join('\n'),
+ ).join('\n'),
`
//! .name: Smoothstep
//! .id: smoothstep
@@ -504,15 +480,13 @@ ${type} remap(${type} x, ${type} a1, ${type} b1, ${type} a2, ${type} b2) {
//! out2.default: 1
` +
- ['float', 'vec2', 'vec3', 'vec4']
- .map(
- (type) => `
+ GLSL_FLOAT_TYPES.map(
+ (type) => `
${type} smoothst(${type} t, ${type} t1, ${type} t2, ${type} out1, ${type} out2) {
return mix(out1, out2, smoothstep(t1, t2, t));
}
`,
- )
- .join('\n'),
+ ).join('\n'),
`
//! .name: Arctangent
//! .id: arctan2
@@ -523,15 +497,13 @@ ${type} smoothst(${type} t, ${type} t1, ${type} t2, ${type} out1, ${type} out2)
//! x.default: 1
` +
- ['float', 'vec2', 'vec3', 'vec4']
- .map(
- (type) => `
+ GLSL_FLOAT_TYPES.map(
+ (type) => `
${type} arctan2(${type} y, ${type} x) {
return atan(y, x);
}
`,
- )
- .join('\n'),
+ ).join('\n'),
`
//! .name: Tangent
//! .id: tan
@@ -539,15 +511,13 @@ ${type} arctan2(${type} y, ${type} x) {
//! .description: The tangent function (radians)
` +
- ['float', 'vec2', 'vec3', 'vec4']
- .map(
- (type) => `
+ GLSL_FLOAT_TYPES.map(
+ (type) => `
${type} tang(${type} x) {
return tan(x);
}
`,
- )
- .join('\n'),
+ ).join('\n'),
`
//! .name: Arcsine
//! .id: arcsin
@@ -555,15 +525,13 @@ ${type} tang(${type} x) {
//! .description: The arcsine function (radians) — input will be clamped to [−1, 1]
` +
- ['float', 'vec2', 'vec3', 'vec4']
- .map(
- (type) => `
+ GLSL_FLOAT_TYPES.map(
+ (type) => `
${type} arcsin(${type} x) {
return asin(clamp(x, -1.0, 1.0));
}
`,
- )
- .join('\n'),
+ ).join('\n'),
`
//! .name: Sigmoid
//! .id: sigmoid
@@ -575,15 +543,13 @@ ${type} arcsin(${type} x) {
//! sharpness.description: scale factor for input value — higher = quicker transition from a to b
` +
- ['float', 'vec2', 'vec3', 'vec4']
- .map(
- (type) => `
+ GLSL_FLOAT_TYPES.map(
+ (type) => `
${type} sigmoid(${type} x, ${type} a, ${type} b, ${type} sharpness) {
return mix(a, b, 1.0 / (1.0 + exp(-sharpness * x)));
}
`,
- )
- .join('\n'),
+ ).join('\n'),
`
//! .name: Staircase (floor)
//! .id: floor
@@ -597,15 +563,13 @@ ${type} sigmoid(${type} x, ${type} a, ${type} b, ${type} sharpness) {
//! phase.description: proportion of a step to be added to input
//! phase.default: 0
` +
- ['float', 'vec2', 'vec3', 'vec4']
- .map(
- (type) => `
+ GLSL_FLOAT_TYPES.map(
+ (type) => `
${type} floorf(${type} x, ${type} stepw, ${type} steph, ${type} phase) {
return floor(x / stepw + phase) * steph;
}
`,
- )
- .join('\n'),
+ ).join('\n'),
];
function auto_update_enabled() {
@@ -1265,7 +1229,17 @@ function add_widget(func) {
if (info.description) {
title.title = info.description;
}
- title.appendChild(document.createTextNode(info.name + ' '));
+ const type = document.createElement('span');
+ type.classList.add('widget-type');
+ type.appendChild(document.createTextNode(info.name));
+ type.addEventListener('click', (e) => {
+ set_display_output_and_update_shader(root);
+ e.preventDefault();
+ });
+
+ title.appendChild(type);
+ title.appendChild(document.createTextNode(' '));
+
const name_input = document.createElement('div');
name_input.contentEditable = true;
name_input.spellcheck = false;
@@ -1393,12 +1367,6 @@ function add_widget(func) {
}
}
- root.addEventListener('click', (e) => {
- if (is_input(e.target)) return;
- set_display_output_and_update_shader(root);
- e.preventDefault();
- });
-
widgets_container.appendChild(root);
return root;
}
diff --git a/index.html b/index.html
index 053080e..a748cf4 100644
--- a/index.html
+++ b/index.html
@@ -133,11 +133,11 @@
cursor: pointer;
padding: 0.1em 0;
}
- .widget:hover {
- background: #fff3;
+ .widget[data-display="1"] .widget-type {
+ color: #ff0;
}
- .widget[data-display="1"] {
- background: #ff04;
+ .widget-type:hover {
+ color: #aa0;
}
.widget.dragging {
background: #aaf6;