WebGL+Three.js入门与实战(一)——1.4 通过鼠标控制绘制

实现鼠标跟随效果

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="../lib/index.js"></script>
		<style>
			*{
				margin: 0;
				padding: 0;
			}
			canvas{
				margin: 50px auto 0;
				display: block;
				background: yellow;
			}
		</style>
	</head>
	<body>
		<canvas id="cancas" width="400" height="400"></canvas>
	</body>
	<script>
		const ctx = document.getElementById('cancas')
		const gl = ctx.getContext('webgl')
		//着色器
		//创建着色器源码
		const VERTEX_SHADER_SOURCE = `
		 //必须要存在 main 函数
		 attribute vec4 aPosition;
		 void main() {
			 //要绘制的点的坐标
			 gl_Position = aPosition; //默认为 vec4(0.0,0.0,0.0,1.0);
			 //点的大小
			 gl_PointSize=40.0;
		 }
		 `; //顶点着色器
		const FRAGMENT_SHADER_SOURCE = `
		void main(){
			gl_FragColor=vec4(1.0,0.0,0.0,1.0);
		}
		`; //片元着色器
		//执行绘画
		const program=initShader(gl,VERTEX_SHADER_SOURCE,FRAGMENT_SHADER_SOURCE)
		// 获取attribute变量
		const aPosition=gl.getAttribLocation(program,'aPosition')
		gl.vertexAttrib1f(aPosition,0.0)
		gl.drawArrays(gl.POINTS, 0, 1);//重新绘制
		
		// onmousemove 鼠标跟随效果
		ctx.onmousemove=function(ev){
			//坐标
			const x =ev.clientX
			const y=ev.clientY
			const domPosition= ev.target.getBoundingClientRect()
			console.log(domPosition,ctx.offsetTop,ctx.offsetLeft)
			const domx=x-domPosition.left;
			const domy=y-domPosition.top;
			/*
			画布的宽度是400,对应的画布坐标系
			0 200 400
			webgl对应的X坐标系
			-1 0 1
			把画布X坐标系转化成webgl对应的坐标系
			需要先 -200 (当前画布的宽度)然后再除以200
			画布的高度是400,对应的画布坐标系
			0 200 400
			webgl对应的Y坐标系
			1 0 -1
			把画布Y坐标系转化成webgl对应的坐标系
			需要先让200(当前画布的高度) 减这个数,然后再/200
			*/
		   const halfWidth=ctx.offsetWidth/2
		   const halfHeight=ctx.offsetHeight/2
		   const clickX=(domx-halfWidth)/halfWidth
		   const clickY=(halfHeight-domy) / halfHeight
		   gl.vertexAttrib2f(aPosition,clickX,clickY)
		   gl.drawArrays(gl.POINTS, 0, 1);
		}
	</script>
</html>

提示:需要把画布坐标转换成webgl坐标才能进行绘画

实现绘画效果

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="../lib/index.js"></script>
		<style>
			*{
				margin: 0;
				padding: 0;
			}
			canvas{
				margin: 50px auto 0;
				display: block;
				background: yellow;
			}
		</style>
	</head>
	<body>
		<canvas id="cancas" width="400" height="400"></canvas>
	</body>
	<script>
		const ctx = document.getElementById('cancas')
		const gl = ctx.getContext('webgl')
		//着色器
		//创建着色器源码
		const VERTEX_SHADER_SOURCE = `
		 //必须要存在 main 函数
		 attribute vec4 aPosition;
		 void main() {
			 //要绘制的点的坐标
			 gl_Position = aPosition; //默认为 vec4(0.0,0.0,0.0,1.0);
			 //点的大小
			 gl_PointSize=10.0;
		 }
		 `; //顶点着色器
		const FRAGMENT_SHADER_SOURCE = `
		void main(){
			gl_FragColor=vec4(1.0,0.0,0.0,1.0);
		}
		`; //片元着色器
		//执行绘画
		const program=initShader(gl,VERTEX_SHADER_SOURCE,FRAGMENT_SHADER_SOURCE)
		// 获取attribute变量
		const aPosition=gl.getAttribLocation(program,'aPosition')
		const points=[];
		gl.vertexAttrib1f(aPosition,0.0)
		gl.drawArrays(gl.POINTS, 0, 1);//重新绘制
		
		// 绘画效果
		ctx.onmousemove=function(ev){
			//坐标
			const x =ev.clientX
			const y=ev.clientY
			const domPosition= ev.target.getBoundingClientRect()
			console.log(domPosition,ctx.offsetTop,ctx.offsetLeft)
			const domx=x-domPosition.left;
			const domy=y-domPosition.top;
			/*
			画布的宽度是400,对应的画布坐标系
			0 200 400
			webgl对应的X坐标系
			-1 0 1
			把画布X坐标系转化成webgl对应的坐标系
			需要先 -200 (当前画布的宽度)然后再除以200
			画布的高度是400,对应的画布坐标系
			0 200 400
			webgl对应的Y坐标系
			1 0 -1
			把画布Y坐标系转化成webgl对应的坐标系
			需要先让200(当前画布的高度) 减这个数,然后再/200
			*/
		   const halfWidth=ctx.offsetWidth/2
		   const halfHeight=ctx.offsetHeight/2
		   const clickX=(domx-halfWidth)/halfWidth
		   const clickY=(halfHeight-domy) / halfHeight
		   points.push({clickX,clickY})
		   for(let i=0;i<points.length;i++)
		   {
			   gl.vertexAttrib2f(aPosition,points[i].clickX,points[i].clickY)
			   gl.drawArrays(gl.POINTS, 0, 1);
		   }
		 
		}
	</script>
</html>

通过点击绘制多个点

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="../lib/index.js"></script>
		<style>
			*{
				margin: 0;
				padding: 0;
			}
			canvas{
				margin: 50px auto 0;
				display: block;
				background: yellow;
			}
		</style>
	</head>
	<body>
		<canvas id="cancas" width="400" height="400"></canvas>
	</body>
	<script>
		const ctx = document.getElementById('cancas')
		const gl = ctx.getContext('webgl')
		//着色器
		//创建着色器源码
		const VERTEX_SHADER_SOURCE = `
		 //必须要存在 main 函数
		 attribute vec4 aPosition;
		 void main() {
			 //要绘制的点的坐标
			 gl_Position = aPosition; //默认为 vec4(0.0,0.0,0.0,1.0);
			 //点的大小
			 gl_PointSize=10.0;
		 }
		 `; //顶点着色器
		const FRAGMENT_SHADER_SOURCE = `
		void main(){
			gl_FragColor=vec4(1.0,0.0,0.0,1.0);
		}
		`; //片元着色器
		//执行绘画
		const program=initShader(gl,VERTEX_SHADER_SOURCE,FRAGMENT_SHADER_SOURCE)
		// 获取attribute变量
		const aPosition=gl.getAttribLocation(program,'aPosition')
		const points=[];
		gl.vertexAttrib1f(aPosition,0.0)
		gl.drawArrays(gl.POINTS, 0, 1);//重新绘制
		
		// 通过点击绘制多个点
		ctx.onclick=function(ev){
			//坐标
			const x =ev.clientX
			const y=ev.clientY
			const domPosition= ev.target.getBoundingClientRect()
			console.log(domPosition,ctx.offsetTop,ctx.offsetLeft)
			const domx=x-domPosition.left;
			const domy=y-domPosition.top;
			/*
			画布的宽度是400,对应的画布坐标系
			0 200 400
			webgl对应的X坐标系
			-1 0 1
			把画布X坐标系转化成webgl对应的坐标系
			需要先 -200 (当前画布的宽度)然后再除以200
			画布的高度是400,对应的画布坐标系
			0 200 400
			webgl对应的Y坐标系
			1 0 -1
			把画布Y坐标系转化成webgl对应的坐标系
			需要先让200(当前画布的高度) 减这个数,然后再/200
			*/
		   const halfWidth=ctx.offsetWidth/2
		   const halfHeight=ctx.offsetHeight/2
		   const clickX=(domx-halfWidth)/halfWidth
		   const clickY=(halfHeight-domy) / halfHeight
		   points.push({clickX,clickY})
		   for(let i=0;i<points.length;i++)
		   {
			   gl.vertexAttrib2f(aPosition,points[i].clickX,points[i].clickY)
			   gl.drawArrays(gl.POINTS, 0, 1);
		   }
		 
		}
	</script>
</html>

整体流程

在这里插入图片描述

代码中的initShader方法是自己封装好的方法
请参考https://blog.csdn.net/qq_45013951/article/details/134637108
下面是WebGL+Three.js入门与实战的总体链接
1.1 绘制一个点
1.2 webgl坐标系
1.3 学习使用attribute变量-绘制一个水平移动的点
1.4 通过鼠标控制绘制
1.5 修改点的颜色
1.6 实现贪吃蛇游戏
2.1 使用缓冲区对象-绘制多个点

  • 12
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
"pan.baidu.com\ webgl three.js入门实战" 是一个涉及到网页图形技术 WebGL 和三维图形库 three.js 的学习和实践教程。 首先,WebGL 是一种基于 HTML5 的图形引擎,允许在网页中实现高性能的图形渲染。通过使用 WebGL,开发者可以在浏览器中创建出具有逼真效果和交互性的三维图形。因此,学习 Webgl 可以帮助我们理解如何构建出精美的图形界。 而 three.js 是一种基于 WebGL 的开源 JavaScript 3D 渲染库,为开发者提供了简化创建和渲染三维图形的方法和功能。它提供了丰富的内置函数和类,使得开发者可以轻松地创建出复杂的场景、模型和动画。因此,学习和掌握 Three.js 可以让我们更高效地开发出出色的 WebGL 三维图形项目。 "pan.baidu.com\webgl three.js入门实战" 这个教程可能包含以下内容:介绍 WebGL 技术的基础知识和概念,如绘制图形的渲染管线、顶着色器和片元着色器等。同时,它也会介绍如何使用 Three.js 库来简化代码的编写,实现鼠标交互、相机控制和灯光效果等。 在实战部分,教程可能会提供一些具体的案例和项目,让学习者通过实际动手操作来加深对 WebGLThree.js 的理解和掌握。这些实战项目可能包括创建一个简单的三维场景、导入和展示三维模型、实现纹理贴图和光照效果等。 总的来说,"pan.baidu.com\webgl three.js入门实战" 是一个为初学者提供学习和实践 WebGLThree.js 技术的教程。通过学习这个教程,我们可以掌握 WebGL 技术的基础知识和概念,并且学会使用 Three.js 库来创建出精美的三维图形网页。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值