繁体   English   中英

如何使用touchmove使mousemove事件在触摸屏上正常工作?

[英]How to make mousemove event working for touchscreen with touchmove?

我正在使用画布JavaScript,在其中可以通过mousemove事件擦除背景...

现在,我正在尝试为触摸屏(移动设备)获得相同的体验。 如何同时给我的代码提供mousemove和touchmove事件?

 (function() { // Creates a new canvas element and appends it as a child // to the parent element, and returns the reference to // the newly created canvas element function createCanvas(parent, width, height) { var canvas = {}; canvas.node = document.createElement('canvas'); canvas.context = canvas.node.getContext('2d'); canvas.node.width = width || 100; canvas.node.height = height || 100; parent.appendChild(canvas.node); return canvas; } function init(container, width, height, fillColor) { var canvas = createCanvas(container, width, height); var ctx = canvas.context; // define a custom fillCircle method ctx.fillCircle = function(x, y, radius, fillColor) { /*this.fillStyle = fillColor; this.beginPath(); this.moveTo(x, y); this.arc(x, y, radius, 0, Math.PI * 2, false); this.fill();*/ var radgrad = ctx.createRadialGradient(x, y, 0, x, y, radius); radgrad.addColorStop(0, 'rgba(255,0,0,1)'); radgrad.addColorStop(0.8, 'rgba(255,0,0,.9)'); radgrad.addColorStop(1, 'rgba(255,0,0,0)'); // draw shape ctx.fillStyle = radgrad; ctx.fillRect(x - radius, y - radius, x + radius, y + radius); }; ctx.clearTo = function(fillColor) { ctx.fillStyle = fillColor; ctx.fillRect(0, 1, width, height); }; ctx.clearTo(fillColor || "#ddd"); // bind mouse events canvas.node.onmousemove = function(e) { if (!canvas.isDrawing) { return; } var x = e.pageX - this.offsetLeft; var y = e.pageY - this.offsetTop; var radius = 100; // or whatever var fillColor = '#ff0000'; ctx.globalCompositeOperation = 'destination-out'; ctx.fillCircle(x, y, radius, fillColor); }; canvas.node.onmouseenter = function(e) { canvas.isDrawing = true; }; } var container = document.getElementById('canvas'); init(container, 5000, 3000, '#f8fa58'); })(); 
 body { margin-left: -10vw; margin-top: -30vh; background: url(https://id-images.vice.com/images/articles/meta/2014/10/21/untitled-article-1413860640.jpg?crop=1xw:0.44513137557959814xh;0xw,0.14219474497681608xh&resize=2000:*&output-format=image/jpeg&output-quality=75) no-repeat center center fixed; -webkit-background-size: cover; -moz-background-size: cover; -o-background-size: cover; background-size: cover; } #canvas { z-index: -1; top: 2vh; left: -10vw; width: 110vw; height: 130vh; overflow: hidden; } 
 <div id="back"></div> <div id="canvas"></div> 

您可以使用相同的事件处理程序,但是在内部,您必须以不同的方式处理事件,因为touch[XXX]事件上没有clientXclientY属性。

触摸事件可以是多点触摸,因此它们确实包含具有这些坐标属性的touches数组。

IMO的一种更干净的方法是将事件处理程序分为两个不同的阶段:一个阶段提取事件的坐标,另一个阶段使用这些坐标进行操作。

 (function() { // a little verbose but... function handleMousemove(event){ var x = event.clientX; var y = event.clientY; draw(x, y); } function handleTouchmove(event){ event.preventDefault(); // we don't want to scroll var touch = event.touches[0]; var x = touch.clientX; var y = touch.clientY; draw(x, y); } // this one can be shared by both touch and move events function activateDrawing(event){ event.preventDefault(); canvas.isDrawing = true; } function draw(eventX, eventY){ var x = eventX - canvas.node.offsetLeft; var y = eventY - canvas.node.offsetTop; if (!canvas.isDrawing) { return; } var radius = 100; // or whatever var fillColor = '#ff0000'; ctx.globalCompositeOperation = 'destination-out'; ctx.fillCircle(x, y, radius, fillColor); } function createCanvas(parent, width, height) { var canvas = {}; canvas.node = document.createElement('canvas'); canvas.context = canvas.node.getContext('2d'); canvas.node.width = width || 100; canvas.node.height = height || 100; parent.appendChild(canvas.node); return canvas; } var canvas, ctx; // got it out to avoid nesting too deeply my handlers; function init(container, width, height, fillColor) { canvas = createCanvas(container, width, height); ctx = canvas.context; // define a custom fillCircle method ctx.fillCircle = function(x, y, radius, fillColor) { var radgrad = ctx.createRadialGradient(x, y, 0, x, y, radius); radgrad.addColorStop(0, 'rgba(255,0,0,1)'); radgrad.addColorStop(0.8, 'rgba(255,0,0,.9)'); radgrad.addColorStop(1, 'rgba(255,0,0,0)'); // draw shape ctx.fillStyle = radgrad; ctx.fillRect(x - radius, y - radius, x + radius, y + radius); }; ctx.clearTo = function(fillColor) { ctx.fillStyle = fillColor; ctx.fillRect(0, 1, width, height); }; ctx.clearTo(fillColor || "#ddd"); // bind mouse events canvas.node.onmousemove = throttle(handleMousemove); canvas.node.ontouchmove = throttle(handleTouchmove); canvas.node.onmouseenter = canvas.node.ontouchstart = throttle(activateDrawing); } var container = document.getElementById('canvas'); init(container, 5000, 3000, '#f8fa58'); /* Bonus : throttle these events so they don't fire too often */ function throttle(callback) { var active = false; // a simple flag var evt; // to keep track of the last event var handler = function(){ // fired only when screen has refreshed active = false; // release our flag callback(evt); } return function handleEvent(e) { // the actual event handler evt = e; // save our event at each call if (!active) { // only if we weren't already doing it active = true; // raise the flag requestAnimationFrame(handler); // wait for next screen refresh }; } } })(); 
 body { margin-left: -10vw; margin-top: -30vh; background: url(https://id-images.vice.com/images/articles/meta/2014/10/21/untitled-article-1413860640.jpg?crop=1xw:0.44513137557959814xh;0xw,0.14219474497681608xh&resize=2000:*&output-format=image/jpeg&output-quality=75) no-repeat center center fixed; -webkit-background-size: cover; -moz-background-size: cover; -o-background-size: cover; background-size: cover; } #canvas { z-index: -1; top: 2vh; left: -10vw; width: 110vw; height: 130vh; overflow: hidden; } 
 <div id="back"></div> <div id="canvas"></div> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM