diff options
-rw-r--r-- | index.html | 57 | ||||
-rw-r--r-- | pugl.js | 41 |
2 files changed, 85 insertions, 13 deletions
@@ -85,6 +85,13 @@ input[type=submit]:active, button:active { background-color: #fff9; } + input[type=submit][disabled]:hover, + input[type=submit][disabled]:active, + button[disabled]:hover, + button[disabled]:active { + background-color: transparent; + cursor: not-allowed; + } input:focus, [contenteditable]:focus, button:focus { outline: 2px solid #77f; } @@ -207,6 +214,26 @@ input[type=number] { -moz-appearance: textfield; } + .img-button img, .img-button svg { + height: 2em; + display: block; + } + .img-button[disabled] img, + .img-button[disabled] svg { + filter: brightness(50%); + } + .ui-section { + margin: 0.3em; + } + .ui-section label { + margin: auto; + } + .inline-block { + display: inline-block; + } + .no-wrap { + whitespace: no-wrap; + } </style> <meta charset="utf-8"> <meta content="width=device-width,initial-scale=1" name="viewport"> @@ -227,19 +254,39 @@ <div id="title"> <img src="icon.png"> pugl </div> - <form action="#" method="dialog" id="code-form"> + <form action="#" method="dialog" id="code-form" class="ui-section inline-block"> <input type="text" placeholder="Code" id="code"> <input type="submit" value="import"> </form> - <form action="#" method="dialog" id="resolution-form"> + <form action="#" method="dialog" id="resolution-form" class="ui-section inline-block"> <input type="number" placeholder="width" id="resolution-x"> × <input type="number" placeholder="height" id="resolution-y"> <input type="submit" value="change resolution"> </form> - Add <input type="text" id="widget-search" placeholder="Search"> - <div id="widget-choices"></div> - <div id="widgets-container"></div> + <div class="ui-section"> + <div class="inline-block no-wrap"> + <button id="play" class="img-button" disabled> + <img alt="play" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiI+PHBhdGggZD0iTSA2IDI2IEwgMjYgMTYgTCA2IDYgeiIgZmlsbD0iI2ZmZiIgc3Ryb2tlPSJub25lIiAvPjwvc3ZnPgo="> + </button> + <button id="pause" class="img-button"> + <img alt="pause" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiI+CjxwYXRoIGQ9Ik0gNiA2IGwgMCAyMCBsIDcgMCBsIDAgLTIwIHogTSAxOSA2IGwgMCAyMCBsIDcgMCBsIDAgLTIwIHoiIGZpbGw9IiNmZmYiIHN0cm9rZT0ibm9uZSIgLz4KPC9zdmc+Cg=="> + </button> + <button id="step" class="img-button" disabled> + <img alt="step" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiI+CjxwYXRoIGQ9Ik0gNiA2IGwgMCAyMCBsIDQgMCBsIDAgLTIwIHogTSAxNCA2IGwgMTIgMTAgbCAtMTIgMTAgeiIgZmlsbD0iI2ZmZiIgc3Ryb2tlPSJub25lIiAvPgo8L3N2Zz4K"> + </button> + </div> + + <div class="inline-block no-wrap" title="automatically update display when anything is changed"> + <input id="auto-update" type="checkbox"> + <label for="auto-update">auto-update</label> + </div> + </div> + <div class="ui-section"> + Add <input type="text" id="widget-search" placeholder="Search"> + <div id="widget-choices"></div> + <div id="widgets-container"></div> + </div> </div> <div id="ui-resize"></div> @@ -2,11 +2,9 @@ /* TODO: +- reset button +- guide - about dialog -- pause -- settings: - - enable/disable auto-update - - resolution */ const APP_ID = 'dh3YgVZQdX1Q'; @@ -34,11 +32,12 @@ let widgets_container; let code_input; let error_element; let parsed_widgets; +let paused = false; const mouse_pos_ndc = Object.preventExtensions({ x: 0, y: 0 }); -let render_width = 1080, - render_height = 1080; +let render_width = 1080; +let render_height = 1080; 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]), @@ -910,7 +909,7 @@ float worley(vec3 p, vec3 freq) { ]; function auto_update_enabled() { - return true; + return document.getElementById('auto-update').checked; } function is_input(element) { @@ -2367,6 +2366,30 @@ function startup() { import_widgets(code_input.value); }); + const pause_element = document.getElementById('pause'); + const play_element = document.getElementById('play'); + const step_element = document.getElementById('step'); + function update_step_buttons() { + play_element.disabled = !paused; + pause_element.disabled = paused; + step_element.disabled = !paused; + } + + // ideally we would just put the initial state into the HTML + // but fucking firefox https://bugzilla.mozilla.org/show_bug.cgi?id=654072 + update_step_buttons(); + pause_element.addEventListener('click', () => { + paused = true; + update_step_buttons(); + }); + play_element.addEventListener('click', () => { + paused = false; + update_step_buttons(); + }); + step_element.addEventListener('click', () => { + perform_step(); + }); + gl = canvas.getContext('webgl2'); if (gl === null) { // support for very-old-but-not-ancient browsers @@ -2518,7 +2541,9 @@ function frame(time) { canvas.style.left = canvas_x + 'px'; canvas.style.top = canvas_y + 'px'; - perform_step(); + if (!paused) { + perform_step(); + } gl.bindFramebuffer(gl.FRAMEBUFFER, null); gl.viewport(0, 0, viewport_width, viewport_height); |