【笔记】《WebGL编程指南》学习-第2章WebGL入门(5-通过鼠标点击画点)
2017-09-22 23:58
477 查看
这一节的目标:在鼠标点击的位置上绘制出点来
运行结果:
老规矩,先来看一下示例程序
ClickedPoints.js
获取鼠标点击的位置并存储在一个数组中;
清空<canvas>
根据数组的每个元素,在相应的位置绘制点。
鼠标点击位置的信息存储在事件对象 ev 中,该对象传给了 click()函数,可以通过访问 ev.clientX 和 ev.clientY 来获取位置坐标。但是,由于以下两点原因,我们不能直接使用这两个坐标值:
鼠标点击位置坐标是在“浏览器客户区”(client area) 中的坐标,而不是在<canvas>中的。
<canvas>的坐标系统与 WebGL 的坐标系统,其原点位置和 Y 轴的正方向不一样。
首先,你需要将坐标从浏览器客户区坐标下转换到<canvas>坐标系下,然后再转换到 WebGL 坐标系下。
首先,获取<canvas> 浏览器客户区的中的坐标,rect.left 和 rect.top 是 <canvas> 的原点在浏览器客户区中的坐标。
那么 (x - rect.left) 和 (y - rect.top) 就可以将客户区坐标系下的坐标(x, y)转换为 <canvas> 坐标系下的坐标。
接下来,将 <canvas>坐标系下的坐标转换到 WebGL 坐标系统中,而WebGL的原点是在 <canvas> 的中心,<canvas>中心的坐标是(canvas.width/2, canvas.height/2)。
然后,你就可以使用((x-rect.left)- canvas.width/2)和 (canvas.height/2 - (y - rect.top))将<canvas>的原点平移到中心点。
因为 WebGL 中轴的坐标区间为 -1.0 到 1.0,所以最后一步我们将 x 坐标除以 canvas.width/2,将 y 坐标除以 canvas.height/2,将<canvas> 坐标映射到 WebGL坐标。
为什么要把鼠标每次点击的位置都记录下来,而不是仅仅记录最近一次鼠标点击的位置。这是因为WebGL使用的是颜色缓冲区。
WebGL 系统中的绘制操作实际上是在颜色缓冲区中进行绘制的,绘制结束后系统将缓冲区的内容显示在屏幕上,然后颜色缓冲区就会被重置。因为我们有必要将没vishubiao点击的位置记录下来。鼠标每次点击之后,程序都重新绘制了所有的点。
示例程序运行结果:
关于本小节后提到的实验:
在每次画点之前,不清空<canvas>会有什么结果。
在运行程序后,先看到黑色的背景,但第一次点击鼠标后,背景就变成了白色,然后绘制了一个红点。
这是因为在绘制点之后,颜色缓冲区就被 WebGL 重置为了默认的颜色(0.0, 0.0, 0.0, 0.0)。默认的颜色 alpha 分量是 0.0,也就是说默认背景色是透明的了。因此<canvas>就成透明的了,你就能通过<canvas>元素看到网页的背景颜色(白色)。
运行结果:
老规矩,先来看一下示例程序
ClickedPoints.js
//顶点着色器程序 //顶点着色器程序 var VSHADER_SOURCE = 'attribute vec4 a_Position;'+ 'void main(){'+ 'gl_Position=a_Position;'+ 'gl_PointSize=10.0;'+ '}'; //片元着色器程序 var FSHADER_SOURCE= 'void main(){'+ 'gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);'+ '}'; function main() { //获取canvas元素 var canvas = document.getElementById("webgl"); if(!canvas){ console.log("Failed to retrieve the <canvas> element"); return; } //获取WebGL绘图上下文 var gl = getWebGLContext(canvas); if(!gl){ console.log("Failed to get the rendering context for WebGL"); return; } //初始化着色器 if(!initShaders(gl,VSHADER_SOURCE,FSHADER_SOURCE)){ console.log("Failed to initialize shaders."); return; } //获取attribute变量存储位置 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; } canvas.onmousedown = function(ev){ click(ev,gl,canvas,a_Position); }; //指定清空<canvas>颜色 gl.clearColor(0.0, 0.0, 0.0, 1.0); //清空<canvas> gl.clear(gl.COLOR_BUFFER_BIT); } var g_points = []; function click(ev, gl, canvas, a_Position){ var x= ev.clientX; var y = ev.clientY; var rect = ev.target.getBoundingClientRect(); x = ((x - rect.left) - canvas.width / 2) / (canvas.width / 2); y = (canvas.height / 2 - (y - rect.top)) / (canvas.height / 2); //将坐标存储到g_points数组中 g_points.push(x); g_points.push(y); //清除<canvas> gl.clear(gl.COLOR_BUFFER_BIT); var len = g_points.length; for(var i = 0; i < len; i+=2){ //将点的位置传递到变量中 gl.vertexAttrib3f(a_Position, g_points[i], g_points[i+1], 0.0); //绘制点 gl.drawArrays(gl.POINTS, 0, 1); } }
注册事件响应函数
事件响应函数能够异步地响应用户在网页上的操作,如点击鼠标、按下键盘等等。为了使用事件响应函数,你需要对其进行注册。对待定的用户输入(比如点击鼠标),<canvas>有特定的属性与之对应,我们把事件处理函数注册在这些属性上。响应鼠标点击事件
在上面的JS文件中,click()这个函数主要完成了:获取鼠标点击的位置并存储在一个数组中;
清空<canvas>
根据数组的每个元素,在相应的位置绘制点。
var g_points = []; function click(ev, gl, canvas, a_Position){ var x= ev.clientX; var y = ev.clientY; var rect = ev.target.getBoundingClientRect(); x = ((x - rect.left) - canvas.width / 2) / (canvas.width / 2); y = (canvas.height / 2 - (y - rect.top)) / (canvas.height / 2); //将坐标存储到g_points数组中 g_points.push(x); g_points.push(y); //清除<canvas> gl.clear(gl.COLOR_BUFFER_BIT); var len = g_points.length; for(var i = 0; i < len; i+=2){ //将点的位置传递到变量中 gl.vertexAttrib3f(a_Position, g_points[i], g_points[i+1], 0.0); //绘制点 gl.drawArrays(gl.POINTS, 0, 1); } }
鼠标点击位置的信息存储在事件对象 ev 中,该对象传给了 click()函数,可以通过访问 ev.clientX 和 ev.clientY 来获取位置坐标。但是,由于以下两点原因,我们不能直接使用这两个坐标值:
鼠标点击位置坐标是在“浏览器客户区”(client area) 中的坐标,而不是在<canvas>中的。
<canvas>的坐标系统与 WebGL 的坐标系统,其原点位置和 Y 轴的正方向不一样。
首先,你需要将坐标从浏览器客户区坐标下转换到<canvas>坐标系下,然后再转换到 WebGL 坐标系下。
首先,获取<canvas> 浏览器客户区的中的坐标,rect.left 和 rect.top 是 <canvas> 的原点在浏览器客户区中的坐标。
那么 (x - rect.left) 和 (y - rect.top) 就可以将客户区坐标系下的坐标(x, y)转换为 <canvas> 坐标系下的坐标。
接下来,将 <canvas>坐标系下的坐标转换到 WebGL 坐标系统中,而WebGL的原点是在 <canvas> 的中心,<canvas>中心的坐标是(canvas.width/2, canvas.height/2)。
然后,你就可以使用((x-rect.left)- canvas.width/2)和 (canvas.height/2 - (y - rect.top))将<canvas>的原点平移到中心点。
因为 WebGL 中轴的坐标区间为 -1.0 到 1.0,所以最后一步我们将 x 坐标除以 canvas.width/2,将 y 坐标除以 canvas.height/2,将<canvas> 坐标映射到 WebGL坐标。
为什么要把鼠标每次点击的位置都记录下来,而不是仅仅记录最近一次鼠标点击的位置。这是因为WebGL使用的是颜色缓冲区。
WebGL 系统中的绘制操作实际上是在颜色缓冲区中进行绘制的,绘制结束后系统将缓冲区的内容显示在屏幕上,然后颜色缓冲区就会被重置。因为我们有必要将没vishubiao点击的位置记录下来。鼠标每次点击之后,程序都重新绘制了所有的点。
示例程序运行结果:
关于本小节后提到的实验:
在每次画点之前,不清空<canvas>会有什么结果。
在运行程序后,先看到黑色的背景,但第一次点击鼠标后,背景就变成了白色,然后绘制了一个红点。
这是因为在绘制点之后,颜色缓冲区就被 WebGL 重置为了默认的颜色(0.0, 0.0, 0.0, 0.0)。默认的颜色 alpha 分量是 0.0,也就是说默认背景色是透明的了。因此<canvas>就成透明的了,你就能通过<canvas>元素看到网页的背景颜色(白色)。
相关文章推荐
- 【笔记】《WebGL编程指南》学习-第2章WebGL入门(6-改变点的颜色))
- 【笔记】《WebGL编程指南》学习-第2章WebGL入门(1-用canvas画一个蓝色矩形)
- 【笔记】《WebGL编程指南》学习-第2章WebGL入门(2-WebGL的HelloWorld)
- 【笔记】《WebGL编程指南》学习-第2章WebGL入门(3-画一个点-版本1))
- 【笔记】《WebGL编程指南》学习-第2章WebGL入门(4-画一个点-版本2))
- Python核心编程(第二版)学习笔记01 【第2章 快速入门】
- hadoop编程入门学习笔记-2 通过示例程序理解hadoop
- Unity学习笔记——鼠标移动到物品上显示物品名字,点击后显示物品信息
- unity3D基础学习 通过判断鼠标点击的是否是目标物体,物体旋转,滑动滚轮缩放拉近视角
- WebGL通过鼠标点击绘点
- OpenGLES入门笔记:Rajawali学习(4)物体点击事件的实现
- OpenCV学习笔记——点击显示鼠标坐标
- (源码实例)通过层DIV实现,当鼠标放在链接上面,显示图片及文字 - 流星絮语 JAVA学习笔记 - CSDNBlog
- 算法导论学习笔记-第2章 算法入门
- Introduction to Algorithms 算法导论 第2章 算法入门 学习笔记及习题解答
- C# 2010 从入门到精通 学习笔记1 第2章 使用变量、操作符和表达式
- 学习笔记——文本框显示默认,点击后默认输入消失。鼠标离开后又出现
- AXURE 学习笔记 制作“鼠标点击时,输入框内文字消失”效果
- 蓝鸥Unity入门鼠标事件学习笔记
- C# 从入门到精通 学习笔记1 第2章 使用变量、操作符和表达式