按左键或右键无法更改颜色

Having trouble changing color by pressing left or right button

本文关键字:颜色 右键      更新时间:2024-04-08

从左到右按钮更改颜色时遇到问题。按住鼠标左键并在画布内移动,应该会绘制出鼠标在按住鼠标右键时的红点和蓝点运动轨迹。

问题是:一旦你用左键和右键绘制,它就会改变左键绘制的颜色,反之亦然。

需要有关如何解决此问题的帮助或提示。非常感谢。

javascript:

// Vertex shader program
var VSHADER_SOURCE =
    'attribute vec4 a_Position;'n' +
    'void main() {'n' +
    '  gl_Position = a_Position;'n' +
    '  gl_PointSize = 10.0;'n' +
    '}'n';
// Fragment shader program
var FSHADER_SOURCE =
    'precision mediump float;'n' +
    'uniform vec4 u_FragColor;'n' + 
    'void main() {'n' +
    '  gl_FragColor = u_FragColor;'n' +
    '}'n';
 var mousePressed = false;      // Holds boolean if mouse is pressed down
 var leftClick = false;         // Holds boolean if left click is pressed down
 var rightClick = false;        // Holds boolean if right click is pressed down
 function main() 
 {
    // Retrieve <canvas> element
    var canvas = document.getElementById('webgl');
    // Get the rendering context for WebGL
    var gl = getWebGLContext(canvas);
    if (!gl) 
    {
        console.log('Failed to get the rendering context for WebGL');
        return;
    }
    // Initialize shaders
    if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) 
    {
        console.log('Failed to intialize shaders.');
        return;
    }
    // Get the storage location of a_Position
    var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
    if (a_Position < 0) 
    {
        console.log('Failed to get the storage location of a_Position');
        return;
    }
    // Get the storage location of u_FragColor
    var u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor');
    if (!u_FragColor) 
    {
        console.log('Failed to get the storage location of u_FragColor');
        return;
    }
    // Register function (event handler) to be called on a mouse mousePressed
    canvas.onmousedown = function(ev)
    { 
    console.log('f1 called');
        // Identify which click is being press down
        switch (ev.which)
        {
            case 1:         // leftClick click
            leftClick = true;
            break;
            case 3:         // rightClick click
            rightClick = true;
            break;
        }
        // Mouse click is being pressed down
        mousePressed = true;
        // call function
        //console.log('calling f1');
        //drawDots(ev, gl, canvas, a_Position, u_FragColor, false); 
        //drawDots(ev, gl, a_Position, u_FragColor, false); 
    };
    canvas.onmousemove = function(ev)
    {
        console.log('f2 called');
        if (mousePressed)
        {
            console.log('calling drawDots');
            drawDots(ev, gl, canvas, a_Position, u_FragColor, true); 
        }
            //drawDots(ev, gl, a_Position, u_FragColor, true);
    };
    canvas.onmouseup = function(ev)
    {
        console.log('f3 called');
        mousePressed = false;
        leftClick = false;
        rightClick = false;
    };
    // Specify the color for clearing <canvas>
    gl.clearColor(0.0, 0.0, 0.0, 1.0);
    console.log('clearColor call');
    // Clear <canvas>
    gl.clear(gl.COLOR_BUFFER_BIT);
    console.log('clear call');
}
var g_points = []; // The array for the position of a mouse mousePressed
function drawDots(ev, gl, canvas, a_Position, u_FragColor, down) 
//function drawDots(ev, gl, a_Position, u_FragColor, down)
{
    console.log('drawDots called');
    var rect = ev.target.getBoundingClientRect() ;
    var x = ev.clientX; // x coordinate of a mouse pointer
    var y = ev.clientY; // y coordinate of a mouse pointer
    x = ((x - rect.left) - canvas.width/2)/(canvas.width/2);
    y = (canvas.height/2 - (y - rect.top))/(canvas.height/2);
    // For left click
    if (down == true && leftClick == true)
    {
        console.log('called left');
        // Store the coordinates to g_points array
        g_points.push(x); g_points.push(y);
        // Clear <canvas>
        gl.clear(gl.COLOR_BUFFER_BIT);
        var len = g_points.length;
        for(var i = 0; i < len; i += 2) 
        {
            // Pass the position of a point to a_Position variable
            gl.uniform4f(u_FragColor, 1.0, 0.0, 0.0, 1.0);
            gl.vertexAttrib3f(a_Position, g_points[i], g_points[i+1], 0.0);

            // Draw
            gl.drawArrays(gl.POINTS, 0, 1);
        }
    }
    // Right click
    else if (down == true && rightClick == true)
    {
        console.log('called right');
        // Store the coordinates to g_points array
        g_points.push(x); g_points.push(y);
        // Clear <canvas>
        gl.clear(gl.COLOR_BUFFER_BIT);
        var len = g_points.length;
        for(var i = 0; i < len; i += 2) 
        {
            // Pass the position of a point to a_Position variable
            gl.uniform4f(u_FragColor, 0.0, 0.0, 1.0, 1.0);
            gl.vertexAttrib3f(a_Position, g_points[i], g_points[i+1], 0.0);

            // Draw
            gl.drawArrays(gl.POINTS, 0, 1);
        }
    }
}

对于添加到g_points中的每个点,您需要记住该点的创建颜色。因此,您可以创建另一个数组来跟踪点的颜色。

var g_points = []; // The array for the position of a mouse mousePressed
var g_colors = []; 

并在每次添加点时将颜色添加到数组中。

// Store the coordinates to g_points array
g_points.push(x); g_points.push(y);
// Store the color
g_colors.push([1.0, 0.0, 0.0, 1.0]);

然后更新for循环,为每个点使用给定的颜色。

for(var i = 0; i < len; i += 2) 
{
    // Pass the position of a point to a_Position variable
    gl.uniform4fv(u_FragColor, g_colors[i/2]);
    gl.vertexAttrib3f(a_Position, g_points[i], g_points[i+1], 0.0);

    // Draw
    gl.drawArrays(gl.POINTS, 0, 1);
}

请记住更新左键单击代码和右键单击代码以存储和使用颜色。

这是你的完整代码与修复:

// Vertex shader program
var VSHADER_SOURCE =
    'attribute vec4 a_Position;'n' +
    'void main() {'n' +
    '  gl_Position = a_Position;'n' +
    '  gl_PointSize = 10.0;'n' +
    '}'n';
// Fragment shader program
var FSHADER_SOURCE =
    'precision mediump float;'n' +
    'uniform vec4 u_FragColor;'n' + 
    'void main() {'n' +
    '  gl_FragColor = u_FragColor;'n' +
    '}'n';
 var mousePressed = false;      // Holds boolean if mouse is pressed down
 var leftClick = false;         // Holds boolean if left click is pressed down
 var rightClick = false;        // Holds boolean if right click is pressed down
 function main() 
 {
    // Retrieve <canvas> element
    var canvas = document.getElementById('webgl');
    canvas.oncontextmenu = function (e) {
        e.preventDefault();
    };
    // Get the rendering context for WebGL
    //var gl = getWebGLContext(canvas);
    var gl = canvas.getContext('webgl');
    if (!gl) 
    {
        console.log('Failed to get the rendering context for WebGL');
        return;
    }
    // Initialize shaders
    if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) 
    {
        console.log('Failed to intialize shaders.');
        return;
    }
    // Get the storage location of a_Position
    var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
    if (a_Position < 0) 
    {
        console.log('Failed to get the storage location of a_Position');
        return;
    }
    // Get the storage location of u_FragColor
    var u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor');
    if (!u_FragColor) 
    {
        console.log('Failed to get the storage location of u_FragColor');
        return;
    }
    // Register function (event handler) to be called on a mouse mousePressed
    canvas.onmousedown = function(ev)
    { 
    console.log('f1 called');
        // Identify which click is being press down
        switch (ev.which)
        {
            case 1:         // leftClick click
            leftClick = true;
            break;
            case 3:         // rightClick click
            rightClick = true;
            break;
        }
        // Mouse click is being pressed down
        mousePressed = true;
        // call function
        //console.log('calling f1');
        //drawDots(ev, gl, canvas, a_Position, u_FragColor, false); 
        //drawDots(ev, gl, a_Position, u_FragColor, false); 
    };
    canvas.onmousemove = function(ev)
    {
        console.log('f2 called');
        if (mousePressed)
        {
            console.log('calling drawDots');
            drawDots(ev, gl, canvas, a_Position, u_FragColor, true); 
        }
            //drawDots(ev, gl, a_Position, u_FragColor, true);
    };
    canvas.onmouseup = function(ev)
    {
        console.log('f3 called');
        mousePressed = false;
        leftClick = false;
        rightClick = false;
    };
    // Specify the color for clearing <canvas>
    gl.clearColor(0.0, 0.0, 0.0, 1.0);
    console.log('clearColor call');
    // Clear <canvas>
    gl.clear(gl.COLOR_BUFFER_BIT);
    console.log('clear call');
}
var g_points = []; // The array for the position of a mouse mousePressed
var g_colors = []; 
function drawDots(ev, gl, canvas, a_Position, u_FragColor, down) 
//function drawDots(ev, gl, a_Position, u_FragColor, down)
{
    console.log('drawDots called');
    var rect = ev.target.getBoundingClientRect() ;
    var x = ev.clientX; // x coordinate of a mouse pointer
    var y = ev.clientY; // y coordinate of a mouse pointer
    x = ((x - rect.left) - canvas.width/2)/(canvas.width/2);
    y = (canvas.height/2 - (y - rect.top))/(canvas.height/2);
    // For left click
    if (down == true && leftClick == true)
    {
        console.log('called left');
        // Store the coordinates to g_points array
        g_points.push(x); g_points.push(y);
        // Store the color
        g_colors.push([1.0, 0.0, 0.0, 1.0]);
        // Clear <canvas>
        gl.clear(gl.COLOR_BUFFER_BIT);
        var len = g_points.length;
        for(var i = 0; i < len; i += 2) 
        {
            // Pass the position of a point to a_Position variable
            gl.uniform4fv(u_FragColor, g_colors[i/2]);
            gl.vertexAttrib3f(a_Position, g_points[i], g_points[i+1], 0.0);
            // Draw
            gl.drawArrays(gl.POINTS, 0, 1);
        }
    }
    // Right click
    else if (down == true && rightClick == true)
    {
        console.log('called right');
        // Store the coordinates to g_points array
        g_points.push(x); g_points.push(y);
        // Store the color
        g_colors.push([0.0, 0.0, 1.0, 1.0]);
        // Clear <canvas>
        gl.clear(gl.COLOR_BUFFER_BIT);
        var len = g_points.length;
        for(var i = 0; i < len; i += 2) 
        {
            // Pass the position of a point to a_Position variable
            gl.uniform4fv(u_FragColor, g_colors[i/2]);
            gl.vertexAttrib3f(a_Position, g_points[i], g_points[i+1], 0.0);
            // Draw
            gl.drawArrays(gl.POINTS, 0, 1);
        }
    }
}
<html>
<script type="text/javascript">
function initShaders(gl, vertexStr, fragmentStr) {
    var fragmentShader = getShader(gl, fragmentStr, true);
    var vertexShader = getShader(gl, vertexStr, false);
    gl.program = gl.createProgram();
    gl.attachShader(gl.program, vertexShader);
    gl.attachShader(gl.program, fragmentShader);
    gl.linkProgram(gl.program);
    if (!gl.getProgramParameter(gl.program, gl.LINK_STATUS)) {
        alert("Could not initialise shaders");
    }
    gl.useProgram(gl.program);
    return true;
}
function getShader(gl, str, isFrag) {
    var shader;
    if (isFrag) {
        shader = gl.createShader(gl.FRAGMENT_SHADER);
    } else {
        shader = gl.createShader(gl.VERTEX_SHADER);
    }
    gl.shaderSource(shader, str);
    gl.compileShader(shader);
    if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
        alert(gl.getShaderInfoLog(shader));
        return null;
    }
    return shader;
}
</script>
<body onload="main();">
    <canvas id="webgl" style="border: none;" width="500" height="500"></canvas>
</body>
</html>