forked from mikael-lovqvist/websperiments
Add grid color and opacity controls
Edge shader now takes u_edge_color and u_edge_opacity uniforms. Grid section added to sidebar with a color picker and opacity slider. Blending enabled around edge draw call to support sub-1 opacity. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -133,6 +133,19 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h3>Grid</h3>
|
||||||
|
<div class="param" style="margin-top:6px">
|
||||||
|
<label>Color</label>
|
||||||
|
<div id="grid-color-btn" style="flex:1; height:22px; border:1px solid #1e3448; cursor:pointer; border-radius:2px;" title="Pick color…"></div>
|
||||||
|
</div>
|
||||||
|
<div class="param">
|
||||||
|
<label>Opacity</label>
|
||||||
|
<input type="range" id="grid-opacity" min="0" max="1" step="0.01" value="1">
|
||||||
|
<span class="val" id="grid-opacity-val">1.00</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<h3>Noise</h3>
|
<h3>Noise</h3>
|
||||||
<div style="display:flex; gap:3px; margin-top:6px; flex-wrap:wrap">
|
<div style="display:flex; gap:3px; margin-top:6px; flex-wrap:wrap">
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ const spin = new Spin_State();
|
|||||||
const paint = new Paint_State();
|
const paint = new Paint_State();
|
||||||
const undo_state = new Undo_State();
|
const undo_state = new Undo_State();
|
||||||
const env = new Env_State();
|
const env = new Env_State();
|
||||||
|
const grid_state = { color: [0.05, 0.05, 0.05], opacity: 1.0 };
|
||||||
let current_geo = null;
|
let current_geo = null;
|
||||||
let current_palette = DEFAULT_PALETTE;
|
let current_palette = DEFAULT_PALETTE;
|
||||||
let building = false;
|
let building = false;
|
||||||
@@ -681,10 +682,15 @@ function render_frame(ts) {
|
|||||||
gl.disable(gl.POLYGON_OFFSET_FILL);
|
gl.disable(gl.POLYGON_OFFSET_FILL);
|
||||||
gl.useProgram(edge_prog);
|
gl.useProgram(edge_prog);
|
||||||
gl.uniformMatrix4fv(gl.getUniformLocation(edge_prog, 'u_mvp'), false, mvp);
|
gl.uniformMatrix4fv(gl.getUniformLocation(edge_prog, 'u_mvp'), false, mvp);
|
||||||
|
gl.uniform3fv(gl.getUniformLocation(edge_prog, 'u_edge_color'), grid_state.color);
|
||||||
|
gl.uniform1f(gl.getUniformLocation(edge_prog, 'u_edge_opacity'), grid_state.opacity);
|
||||||
|
gl.enable(gl.BLEND);
|
||||||
|
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
||||||
const ep = gl.getAttribLocation(edge_prog, 'a_pos');
|
const ep = gl.getAttribLocation(edge_prog, 'a_pos');
|
||||||
gl.bindBuffer(gl.ARRAY_BUFFER, edge_pos_buf); gl.enableVertexAttribArray(ep); gl.vertexAttribPointer(ep, 3, gl.FLOAT, false, 0, 0);
|
gl.bindBuffer(gl.ARRAY_BUFFER, edge_pos_buf); gl.enableVertexAttribArray(ep); gl.vertexAttribPointer(ep, 3, gl.FLOAT, false, 0, 0);
|
||||||
gl.drawArrays(gl.LINES, 0, edge_verts);
|
gl.drawArrays(gl.LINES, 0, edge_verts);
|
||||||
gl.disableVertexAttribArray(ep);
|
gl.disableVertexAttribArray(ep);
|
||||||
|
gl.disable(gl.BLEND);
|
||||||
|
|
||||||
|
|
||||||
gl.enable(gl.POLYGON_OFFSET_FILL);
|
gl.enable(gl.POLYGON_OFFSET_FILL);
|
||||||
@@ -1073,6 +1079,42 @@ function _hsl_to_rgb(h,s,l) {
|
|||||||
sync_env_ui();
|
sync_env_ui();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Grid UI wiring
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
{
|
||||||
|
const btn = document.getElementById('grid-color-btn');
|
||||||
|
const opacity = document.getElementById('grid-opacity');
|
||||||
|
const opacity_val = document.getElementById('grid-opacity-val');
|
||||||
|
|
||||||
|
const hex_from = c => {
|
||||||
|
const h = v => Math.round(Math.min(v, 1) * 255).toString(16).padStart(2, '0');
|
||||||
|
return `#${h(c[0])}${h(c[1])}${h(c[2])}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
btn.style.background = hex_from(grid_state.color);
|
||||||
|
btn.addEventListener('click', () => {
|
||||||
|
color_dialog_open({
|
||||||
|
get: () => hex_from(grid_state.color),
|
||||||
|
set: hex => {
|
||||||
|
const r = parseInt(hex.slice(1, 3), 16) / 255;
|
||||||
|
const g = parseInt(hex.slice(3, 5), 16) / 255;
|
||||||
|
const b = parseInt(hex.slice(5, 7), 16) / 255;
|
||||||
|
grid_state.color = [r, g, b];
|
||||||
|
btn.style.background = hex;
|
||||||
|
request_render();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
opacity.addEventListener('input', () => {
|
||||||
|
grid_state.opacity = parseFloat(opacity.value);
|
||||||
|
opacity_val.textContent = grid_state.opacity.toFixed(2);
|
||||||
|
request_render();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Keyboard shortcuts
|
// Keyboard shortcuts
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -1,2 +1,4 @@
|
|||||||
precision mediump float;
|
precision mediump float;
|
||||||
void main() { gl_FragColor = vec4(0.05, 0.05, 0.05, 1.0); }
|
uniform vec3 u_edge_color;
|
||||||
|
uniform float u_edge_opacity;
|
||||||
|
void main() { gl_FragColor = vec4(u_edge_color, u_edge_opacity); }
|
||||||
|
|||||||
Reference in New Issue
Block a user