当前位置: 首页 > ops >正文

【第1章 基础知识】1.6 事件处理

文章目录

  • 前言
  • 一、鼠标事件
    • 将鼠标坐标转换为 Canvas 坐标
    • 示例-精灵表坐标查看器
  • 二、键盘事件
  • 三、触摸事件


前言

HTML5 应用程序是以事件来驱动的。可以在 HTML 元素上注册事件监听器,并编写用于响应这些事件的实现代码。几乎所有基于 Canvas 的应用程序都会处理鼠标或触摸事件,还有许多程序也会处理其他各种类型的事件,比如键盘事件或拖放事件。


一、鼠标事件

在 canvas 中检测鼠标事件是非常简单的:可以在 canvas 中增加一个事件监听器,当事件发生时,浏览器就会调用这个监听器。例如:

canvas.onmousedown = function(e) {}

此外,可以使用 addEventListener() 方法来注册监听器:

canvas.addEventListener('mousedown' ,function(e) {})

除了 onmousedown 之外,也可以使用 onmousemove、onmouseup 与 onmouseout 来注册监听器。

使用 onmousedown 这样的方式来注册监听器,比调用 addEventListener() 要稍微简单些。不过,如果要向某个鼠标事件注册许多个监听器的话,那么就得使用 addEventListener() 方法了。

addEventListener()方法允许你在一个元素上注册多个事件监听器,每个监听器都可以独立执行不同的函数。这与传统的on属性(如onclick、onmouseover等)不同,后者每次只能注册一个事件处理函数,如果再次使用on属性注册函数,之前的函数会被覆盖‌

将鼠标坐标转换为 Canvas 坐标

浏览器通过事件对象传递给监听器的鼠标坐标,是窗口坐标,而不是相对于 canvas 自身的坐标。大部分情况下,开发者需要知道的是发生鼠标事件的点相对于 canvas 的位置,而不是在整个窗口中的位置,所以必须进行坐标转换。转换工作是通过类似下面这样的windowToCanvas() 方法来完成的。

function windowToCanvas(canvas, x, y) {//获取canvas元素的边界框(bouding box)const bbox = canvas.getBoundingClientRect()return {x: x - bbox.left * (canvas.width / bbox.width),y: y - bbox.top * (canvas.height / bbox.height),}
}

示例-精灵表坐标查看器

此示例中,可以通过移动鼠标来观察屏幕中显示的坐标,以此确定精灵表中每张精灵图像的具体位置坐标。当用户移动鼠标时,应用程序会持续地更新精灵表上方的鼠标坐标,同时还会在屏幕上绘制辅助线。

示例-精灵表坐标查看器

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><title>精灵表坐标查看器Sprite Sheets</title><style>body {background: #dddddd;}#canvas {position: absolute;left: 0px;top: 50px;margin: 20px;background: #ffffff;border: thin inset rgba(100, 150, 230, 0.5);cursor: pointer;}#readout {margin-top: 10px;margin-left: 15px;color: blue;}</style></head><body><!--用来显示当前精灵表坐标--><div id="readout"></div><p>加载一个图片,移动鼠标,获取基于canvas鼠标处精灵表坐标</p><canvas id="canvas" width="500" height="250">Canvas not supported</canvas></body><script>var canvas = document.getElementById('canvas'),context = canvas.getContext('2d'),readout = document.getElementById('readout'),spritesheet = new Image()//Function……/*** 窗口坐标转化为基于Canvas的坐标* @param canvas* @param x* @param y* @returns {{x: number, y: number}}*/function windowToCanvas(canvas, x, y) {//获取canvas元素的边界框(bouding box)var bbox = canvas.getBoundingClientRect()return {x: x - bbox.left * (canvas.width / bbox.width),y: y - bbox.top * (canvas.height / bbox.height),}}/*** 绘制背景条纹线*/function drawBackground() {var VERTICAL_LINE_SOACING = 12,i = context.canvas.heightcontext.clearRect(0, 0, canvas.width, canvas.height)context.strokeStyle = 'lightgray'context.lineWidth = 0.5//预留出顶部4个网格线高的长度供图片占位,从地部划线,从下往上while (i > VERTICAL_LINE_SOACING * 4) {context.beginPath()context.moveTo(0, i)context.lineTo(canvas.width, i)context.stroke()i -= VERTICAL_LINE_SOACING}}/*** 绘制精灵表*/function drawSpritesheet() {//将图片画到画布上context.drawImage(spritesheet, 0, 0)}/*** 绘制光标跟随网格线* @param x* @param y*/function drawGuidelines(x, y) {context.strokeStyle = 'rgba(0,0,230,0.8)'context.lineWidth = 0.5drawVerticalLine(x)drawHorizontalLine(y)}function updateReadout(x, y) {//四舍五入到0位小数并输出到#readout元素中readout.innerHTML = '(' + x.toFixed(0) + ',' + y.toFixed(0) + ')'}/*** 绘制水平跟随线* @param y*/function drawHorizontalLine(y) {context.beginPath()context.moveTo(0, y + 0.5)context.lineTo(context.canvas.width, y + 0.5)context.stroke()}/*** 绘制垂直跟随线* @param x*/function drawVerticalLine(x) {context.beginPath()context.moveTo(x + 0.5, 0)context.lineTo(x + 0.5, context.canvas.height)context.stroke()}//Event handlers……canvas.onmousemove = function (e) {var loc = windowToCanvas(canvas, e.clientX, e.clientY)drawBackground()drawSpritesheet()drawGuidelines(loc.x, loc.y)updateReadout(loc.x, loc.y)}//Initialization//设置图片路径spritesheet.src = 'running-sprite-sheet.png'//加载图片之后画精灵表spritesheet.onload = function (ev) {drawSpritesheet()}//画背景drawBackground()</script>
</html>

二、键盘事件

在浏览器窗口按下某个按键时,浏览器会生成键盘事件。这些事件发生在当前拥有焦点的HTML元素上,如果没有元素拥有焦点,那么事件将会上移至windows和document对象。

一共有三种键盘事件:

  • keydown
  • keypress
  • keyup

canvas 是一个不可获取焦点的元素,所以在 canvas 元素上新增键盘事件监听器是徒劳的。如果想要检测键盘事件的话,你应该在 document 或 window 对象上新增键盘事件监听器,代码如下:

window.addEventListener('keydown', function(e) {},true);

键盘事件常用于文本输入、游戏操作场景中。


三、触摸事件

随着智能手机与平板电脑的出现,HTML 规范也加入了对触摸事件的支持。要了解更多有关触摸事件处理的信息,请参阅本书的第11章。

http://www.xdnf.cn/news/9297.html

相关文章:

  • 嵌入式自学第二十九天(5.27)
  • 北京大学 | DeepSeek内部研讨资料:AI工具深度测评与选型指南,319页
  • 系统编程day05
  • 基于 STM32 的智慧农业温室控制系统设计与实现
  • 学习python day9
  • DeviceNET转EtherCAT协议转换网关解读
  • Qwen3内置提示词模板解读
  • 数据库大学实验一
  • 投影机三色光源和单色光源实拍对比:一场视觉体验的终极较量
  • 知识图谱系列(4):查询与推理技术
  • 第四十七篇-Tesla P40+Qwen3-30B-A3B部署与测试
  • 什么是PLM软件?离散制造业和流程制造业的主流PLM介绍、国产PLM应用案例
  • 5月27日星期二今日早报简报微语报早读
  • RuoYi前后端分离框架集成Jasypt实现配置信息加密
  • Kubernetes简介及常用命令
  • 高效大电流缓启动电路设计
  • Manus,AGI 要来临了吗?
  • 电子电路:欧姆定律和电流量子化有关系吗?
  • 深入剖析机器学习之波士顿房价案例
  • 易境通海外仓系统:如何提高仓库尾程派送环节效率?
  • 「Python教案」循环语句的使用
  • 离子风机如何保障汽车电子智造组装车间良品率
  • C语言数据存储
  • 操作系统——第四章(文件共享、保护、层级结构、系统布局..)
  • Docker+MobaXterm+x11实现容器UI界面转发本地
  • Python map()函数详解:批量数据处理的瑞士军刀
  • STM32 Keil工程搭建 (手动搭建)流程 2025年5月27日07:42:09
  • STM32之IIC(重点)和OLED屏
  • Spring Boot整合JWT实现认证与授权
  • screen开启和删除session会话