【愚公系列】2023年12月 WEBGL专题-鼠标控制绘制

举报
愚公搬代码 发表于 2023/12/31 22:10:22 2023/12/31
【摘要】 🏆 作者简介,愚公搬代码🏆《头衔》:华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,51CTO博客专家等。🏆《近期荣誉》:2023年华为云十佳博主,2022年CSDN博客之星TOP2,2022年华为云十佳博主等。🏆《博客内容》:.NET、Java、...

🏆 作者简介,愚公搬代码
🏆《头衔》:华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,51CTO博客专家等。
🏆《近期荣誉》:2023年华为云十佳博主,2022年CSDN博客之星TOP2,2022年华为云十佳博主等。
🏆《博客内容》:.NET、Java、Python、Go、Node、前端、IOS、Android、鸿蒙、Linux、物联网、网络安全、大数据、人工智能、U3D游戏、小程序等相关领域知识。
🏆🎉欢迎 👍点赞✍评论⭐收藏

🚀前言

事件是指发生、发生或可能发生的事情或情况。在不同的领域和行业中,事件可能具有不同的定义和含义。例如,在计算机科学中,事件是计算机程序在运行时发生的事情或情况,如用户键入键盘上的键以触发计算机响应。在商业和市场营销中,事件可以是推出新产品,举办营销促销活动,或客户提出投诉和建议等。无论是哪个领域,事件都是需要记录、追踪、分析和处理的重要信息。

在计算机中,事件通常指任何已知的行动或情况变化。以下是一些常见的计算机事件:

  1. 键盘事件:键盘上的按键被按下或释放。

  2. 鼠标事件:鼠标被移动,按下或释放。

  3. 网络事件:计算机连接到或从网络中断开,或数据传输发生错误。

  4. 定时事件:计算机执行预定的任务或程序。

  5. 用户事件:用户执行某些操作,如单击按钮或输入文本。

  6. 硬件事件:硬件设备连接或断开,如插入或拔出USB驱动器。

  7. 软件事件:软件程序启动,关闭或发生错误。

  8. 系统事件:操作系统或其他系统软件发生错误或行为变化。

这些事件可以通过计算机的操作系统或应用程序来检测和响应。例如,用户单击按钮时,应用程序可以执行与该按钮相关的操作,而操作系统可以检测到网络连接断开并自动重新连接。

🚀一、鼠标控制绘制

🔎1.鼠标事件的整体流程

WEBGL鼠标事件的整体流程大致如下:

  1. 在JavaScript程序中创建一个WebGL上下文和画布元素;
  2. 为画布元素注册鼠标事件监听器;
  3. 实现鼠标事件监听器函数,包括鼠标移动、鼠标按下、鼠标释放等;
  4. 在事件监听器函数中获取鼠标位置,并将其转换为WebGL坐标系中的坐标;
  5. 根据鼠标事件的类型和坐标信息,对WebGL场景进行相应的操作,如旋转、平移、缩放等。

具体的实现方式和流程可能会因具体场景而有所不同,但以上步骤是整个流程的核心。

在这里插入图片描述

🔎2.案例

计算WEBGL点击位置的具体步骤如下:

  1. 获取鼠标点击事件的屏幕坐标位置,即event.clientX和event.clientY;
  2. 获取WebGL画布元素的矩形区域,即canvas.getBoundingClientRect(),该方法返回的矩形对象包括左上角的x和y坐标,宽度和高度;
  3. 计算出鼠标点击事件在画布元素上的坐标,即鼠标点击事件的屏幕坐标减去画布元素的左上角坐标;
  4. 将画布元素上的坐标转换成WebGL标准坐标系中的坐标,即将x、y坐标转换到[-1,1]的范围内,可通过以下公式实现:
var x = (event.clientX - rect.left) / canvas.clientWidth * 2 - 1;
var y = 1 - (event.clientY - rect.top) / canvas.clientHeight * 2;

其中,canvas.clientWidth和canvas.clientHeight分别是画布元素的宽度和高度,rect.left和rect.top分别是画布元素左上角在屏幕上的x和y坐标。

通过以上步骤,即可计算出WEBGL点击的位置。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>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="canvas" width="400" height="400">
    此浏览器不支持canvas
  </canvas>
</body>
</html>
<script>

  const ctx = document.getElementById('canvas')

  const gl = ctx.getContext('webgl')

  // 创建着色器源码
  const VERTEX_SHADER_SOURCE = `
    // 只传递顶点数据
    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)

  const aPosition = gl.getAttribLocation(program, 'aPosition');

  const points = []
  ctx.onclick = function(ev) {
    // 坐标
    const x = ev.clientX
    const y = ev.clientY

    const domPosition = ev.target.getBoundingClientRect();

    const domx = x - domPosition.left
    const domy = y - domPosition.top;

    /*
    0 200 400

    -1 0 1

    -200 0 200

    -1 0 1

    需要先 -200 (当前画布的宽度) 然后再 除以 200

    1 0 -1

    0 200 400

    200 0 -200 / 200

    需要先让 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>

在这里插入图片描述


🚀感谢:给读者的一封信

亲爱的读者,

我在这篇文章中投入了大量的心血和时间,希望为您提供有价值的内容。这篇文章包含了深入的研究和个人经验,我相信这些信息对您非常有帮助。

如果您觉得这篇文章对您有所帮助,我诚恳地请求您考虑赞赏1元钱的支持。这个金额不会对您的财务状况造成负担,但它会对我继续创作高质量的内容产生积极的影响。

我之所以写这篇文章,是因为我热爱分享有用的知识和见解。您的支持将帮助我继续这个使命,也鼓励我花更多的时间和精力创作更多有价值的内容。

如果您愿意支持我的创作,请扫描下面二维码,您的支持将不胜感激。同时,如果您有任何反馈或建议,也欢迎与我分享。

在这里插入图片描述

再次感谢您的阅读和支持!

最诚挚的问候, “愚公搬代码”

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。