javascript - 在画布中支持触摸界面
问题描述
我使用画布,通过在 Javascript 中设置支持鼠标拖动:
canvas.onmousedown
canvas.onmouseup
canvas.onmousemove
这行得通..我可以用鼠标支持拖动操作。
但是,在 iOS Safari 浏览器上,用手指拖动不会触发鼠标功能。
相反,整个网页只是向上或向下滚动。
起初我以为添加ontouchmove
和其他人会解决这个问题。但事实并非如此。
移动设备上的浏览器如何判断触摸何时用于画布,何时用于浏览器自身?
canvas.ontouchmove = function(ev) {
var x = ev.touches[0].clientX;
var y = ev.touches[0].clientY;
if ( dragging) {
drag(canvas, x, y);
}
}
解决方案
有 touchstart、touchmove 和 touchend。如果您希望浏览器不响应触摸事件,那么您需要告诉它不响应它们。您可以通过使用addEventListener
而不是作为最后一个参数ontouchstart
传递来做到这一点。{passive: false}
否则浏览器在响应触摸事件之前不会等待 JavaScript。然后调用preventDefault
传递给处理程序的事件对象,告诉浏览器不要做正常的事情(滚动窗口)
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
canvas.addEventListener('touchstart', handleTouchStart, {passive: false});
canvas.addEventListener('touchmove', handleTouchMove);
function handleTouchStart(e) {
e.preventDefault();
}
function handleTouchMove(e) {
const rect = canvas.getBoundingClientRect();
const cssX = e.touches[0].clientX - rect.left;
const cssY = e.touches[0].clientY - rect.top;
const pixelX = cssX * canvas.width / rect.width;
const pixelY = cssY * canvas.height / rect.height;
ctx.fillStyle = `hsl(${performance.now() % 360 | 0},100%,50%)`;
ctx.fillRect(pixelX - 15, pixelY - 15, 30, 30);
}
canvas {
border: 1px solid black;
width: 300px;
height: 150px;
}
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<h1>spacing</h1>
<canvas width="600" height="300"></canvas>
<h1>spacing1</h1>
<h1>spacing2</h1>
<h1>spacing3</h1>
<h1>spacing4</h1>
<h1>spacing5</h1>
<h1>spacing6</h1>
<h1>spacing7</h1>
<h1>spacing8</h1>
<h1>spacing9</h1>
<h1>spacing10</h1>
<h1>spacing11</h1>
<h1>spacing12</h1>
<h1>spacing13</h1>
<h1>spacing14</h1>
请注意,如果您拖动手指以显示在画布上拖动时窗口不会滚动,则存在间距以确保窗口有足够的空间滚动。元标记在那里,因此移动设备上的浏览器显示出对移动设备更友好的比例。
推荐阅读
- javascript - 将存储在子组件中的函数中的值传递给 React 中的父组件
- javascript - 按钮事件侦听器未检测到来自 textarea 的字符串值
- wordpress - 激活插件后 WordPress 会发生什么
- react-table - React-table 无法在 Link 中传递 id
- netty - 扩展 Netty UDP 服务器
- java - MongoDB Java 驱动程序 - 聚合问题
- javascript - 为 Javascript / HTML 中的按钮设置事件处理程序
- c# - 两个类仅在一个内部类中有所不同。如何通过更少的努力从相同的基类派生它们?
- java - 不同方法和同一个类中的 Spring Boot 和 Bean 验证
- html - 当我使用 laravel 6.0 单击添加到卡片按钮时,我想将产品项目显示到购物车中?