2017-05-12 9 views
1

私はキャンバスのjavascriptでmousemoveイベントで背景を消去できます。touchmoveでタッチスクリーンのmousemoveイベントを動作させる方法は?

私はタッチスクリーン(モバイル)で同じ経験をしようとしています。 私のコードにmousemoveとtouchmoveイベントを同時に与えることができますか? touch[XXX]イベントにはclientXclientYプロパティが存在しないため、

(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://i-d-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>

+0

あなたは '$(要素).on( "のMouseMove touchstart"、機能(のようなもの){//}' – Jer

+0

を行うことができます。しかしjqueryのにコードを書き換えることjQuery' '付き...より良い方法が必要です! – Marcel

+0

toucheventsとeventListenersだけでなく、マウスやキーイベントなどでeventListenersを追加するだけです:[MDN:touch events using](https://developer.mozilla.org/en -US/docs/Web/API/Touch_events/Using_Touch_Events) –

答えて

2

あなたが同じイベントハンドラを使用することができますが、内部に、あなたは違ったイベントを処理する必要があります。

タッチイベントはマルチのタッチとすることができるので、これらの座標プロパティを持つtouchesの配列を保持します。

IMOより簡単な方法は、イベントハンドラを2つの異なるフェーズで分割することです。 イベントの座標を抽出するものと、これらの座標で何かを行うものです。

(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://i-d-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>

+0

簡単に動作します!スクロール/ズームの問題が最初にありましたが、Javaのコードを少し追加した document.body.addEventListener( 'touchstart'、function(e){e.preventDefault(); }); – Marcel

関連する問題