我想学习WebGL并开发一个项目。
数字会改变我的输入值。我写了这段代码。但我想用红绿模糊滑块值更改数字颜色。
<div>
R: 0<input id="redSlider" type="range" min="0" max="1" step="0.1" value="1" oninput=redChange(this.value)/>1</div>
<div>
G: 0<input id="greenSlider" type="range" min="0" max="1" step="0.1" value="0" onChange="greensliderChange(this.value)"/>1</div>
<div>
B: 0<input id="blueSlider" type="range" min="0" max="1" step="0.1" value="0" onChange="changeColor(this.value, 2);"/>1</div>
<br>
代码my fragment-shader和
document.getElementById("redSlider").oninput = function(event) {
//red value
alert(redSlider);
};
document.getElementById("greenSlider").oninput = function(event) {
//green value
};
document.getElementById("blueSlider").oninput = function(event) {
//blue value
};
我为滑块值添加的JavaScript页面。但我不能改变片段着色器值。如何在JavaScript页面上更改HTML值的值?
List::sort
答案 0 :(得分:2)
有时很难找到答案。我只看了大约15页的“输入范围”,其中没有一个显示实际如何使用它的例子。所以我可以看到为什么很难找到一个例子而且我也可以看到,不幸的是,虽然我将在下面提供一个例子,但是因为这个问题不是关于“输入范围”而已经找到了
无论如何,您需要知道的第一件事是如何使用<input type="range">
。您需要添加一个事件监听器来监听'input' event。新值将位于滑块的value
属性中。
const redSlider = document.querySelector("#redSlider");
redSlider.addEventListener('input', updateRed);
function updateRed {
console.log(redSlider.value);
}
<input id="redSlider" type="range" min="0" max="1" step="0.1" value="1">
接下来查看您的示例,您希望显示每个滑块左侧的值。为此,我们必须在HTML中更新该值。我发现制作一个元素是最容易的。我将使用<span>
并将其textContent
属性设置为滑块的值。
const redSlider = document.querySelector("#redSlider");
const redValueElem = document.querySelector("#redValue");
redSlider.addEventListener('input', updateRed);
function updateRed() {
redValueElem.textContent = redSlider.value;
};
<div>
R: <span id="redValue"></span>
<input id="redSlider" type="range" min="0" max="1" step="0.1" value="1">
</div>
现在的问题是,因为值改变宽度,例如“0”,它不像“0.5”那样宽,输入类型=“范围”元素被移动。为了解决这个问题,我们需要添加一些CSS来为value元素提供固定的宽度
const redSlider = document.querySelector("#redSlider");
const redValueElem = document.querySelector("#redValue");
redSlider.addEventListener('input', updateRed);
function updateRed() {
redValueElem.textContent = redSlider.value;
};
.slider>span {
/* because span defaults to inline it can't have a width */
display: inline-block;
width: 2em;
}
<div class="slider">
R: <span id="redValue"></span>
<input id="redSlider" type="range" min="0" max="1" step="0.1" value="1">
</div>
所以现在你应该能够使你的3个滑块工作。
接下来,为了能够将值传递到着色器,您需要将其作为uniforms
precision mediump float;
uniform float myred;
uniform float mygreen;
uniform float myblue;
void main()
{
gl_FragColor = vec4(myred, mygreen, myblue, 1.0 );
}
然后,您需要查找这些制服的位置并将其设置为所需的颜色,然后调用绘图功能。
解释如何使用WebGL是一个非常大的主题。我建议你阅读these tutorials。
我还认为我应该提一下,你可能最好将颜色编辑成一组数值。
const myColor = [1, 0, 0];
这样可以更容易地编写代码以使其更具可重用性。它还可以更容易地将其传递给WebGL
uniform vec3 mycolor;
...
gl_FragColor = vec4(myColor, 1);
function setupRGBSliders(id, color, callback) {
const ranges = document.querySelectorAll(id + ' input');
const values = document.querySelectorAll(id + ' span');
ranges.forEach((rangeElem, ndx) => {
rangeElem.addEventListener('input', () => {
const value = rangeElem.value;
color[ndx] = value;
update();
callback();
});
});
function update() {
ranges.forEach((rangeElem, ndx) => {
rangeElem.value = color[ndx];
values[ndx].textContent = color[ndx];
});
}
update();
return update;
}
const myColor = [1, 0.5, 0.3];
setupRGBSliders('#mycolor', myColor, render);
const vs = `
void main() {
gl_Position = vec4(0, 0, 0, 1);
gl_PointSize = 100.0;
}
`;
const fs = `
precision mediump float;
uniform vec3 mycolor;
void main() {
gl_FragColor = vec4(mycolor, 1);
}
`;
const gl = document.querySelector("canvas").getContext("webgl");
const program = twgl.createProgram(gl, [vs, fs]); // using a helper because too much code
const mycolorLoc = gl.getUniformLocation(program, "mycolor");
render();
function render() {
gl.useProgram(program);
gl.uniform3fv(mycolorLoc, myColor);
const offset = 0;
const count = 1;
gl.drawArrays(gl.POINTS, offset, count);
}
.rgb span {
display: inline-block;
width: 2em;
}
<div id="mycolor" class="rgb">
<div>
R: <span></span>
<input type="range" min="0" max="1" step="0.1" value="1">
</div>
<div>
G: <span></span>
<input type="range" min="0" max="1" step="0.1" value="1">
</div>
<div>
B: <span></span>
<input type="range" min="0" max="1" step="0.1" value="1">
</div>
</div>
<canvas></canvas>
<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>