使用JavaScript动态更改背景颜色

时间:2018-05-12 23:00:32

标签: javascript html webgl

我想学习WebGL并开发一个项目。

enter image description here

数字会改变我的输入值。我写了这段代码。但我想用红绿模糊滑块值更改数字颜色。

<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
        };

在我的HTML页面中编码。

我为滑块值添加的JavaScript页面。但我不能改变片段着色器值。如何在JavaScript页面上更改HTML值的值?

List::sort

1 个答案:

答案 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>