2015-11-27 8 views
6

मेरे पास एक कोड है जो (x, y) को नए माउस (x, y) समन्वय से समन्वयित करता है। यह डेस्कटॉप ब्राउज़र में ठीक काम करता है, लेकिन किसी कारण से यह मोबाइल ब्राउज़र में काम नहीं करता है। मैंने टच इवेंट श्रोताओं को जोड़ा है लेकिन मुझे लगता है कि समन्वय कुछ गलत हो रहे हैं। यहाँ मेरा कोड:कैनवास मोबाइल वेब पर टच स्थिति प्राप्त करें

function getMouse(e) { 
    var element = canvas, offsetX = 0, offsetY = 0; 
    if (element.offsetParent) { 
     do { 
     offsetX += element.offsetLeft; 
     offsetY += element.offsetTop; 
     } while ((element = element.offsetParent)); 
    } 

    mx = (e.pageX - offsetX) - LINE_WIDTH; 
    my =(e.pageY - offsetY)- LINE_WIDTH; 
    } 
    function mouseDown(e){ 
    getMouse(e); 
    clear(fctx); 
    var l = lines.length; 
    for (var i = l-1; i >= 0; i--) { 
     draw(fctx,lines[i]); 
     var imageData = fctx.getImageData(mx, my, 1, 1); 
     if (imageData.data[3] > 0) { 
     selectedObject = lines[i]; 
     isDrag = true; 
     canvas.onmousemove = drag; 
     clear(fctx); 
     } 
    } 
    } 
    function mouseUp(){ 
    isDrag = false; 
    } 
    canvas.onmousedown = mouseDown; 
    canvas.onmouseup = mouseUp; 
    canvas.addEventListener('touchstart', mouseDown, false); 
    canvas.addEventListener('touchend', mouseUp, false); 

आप काम कर हिस्सा यहाँ देख सकते हैं: http://codepen.io/nirajmchauhan/pen/yYdMJR

उत्तर

3

स्पर्श घटनाओं से उत्पन्न माउस घटनाओं

ठीक थोड़ी देर के लिए यहां यह सवाल देखा और कोई भी आ रहा है एक उत्तर के साथ आगे मैं एक दे दूंगा।

माउस ईवेंट के विपरीत टच ईवेंट यूआई के संपर्क के कई बिंदुओं को शामिल करते हैं। इसे समायोजित करने के लिए स्पर्श घटनाएं टचपॉइंट्स की एक सरणी प्रदान करती हैं। चूंकि एक माउस दो स्थानों पर एक बार नहीं हो सकता है क्योंकि दो इंटरैक्शन तरीकों को वास्तव में सर्वोत्तम उपयोगकर्ता अनुभव के लिए अलग से संभाला जाना चाहिए। ओपी के रूप में आप यह पता लगाने के बारे में नहीं पूछते कि डिवाइस स्पर्श या माउस संचालित है या नहीं, मैंने इसे किसी अन्य व्यक्ति से पूछने के लिए छोड़ दिया है।

दोनों

माउस और टच घटनाओं हैंडलिंग रह सकते हैं। किसी डिवाइस पर माउस या टच इवेंट्स के लिए श्रोताओं को जोड़ना जिसमें कोई नहीं है या दूसरा कोई मुद्दा नहीं है। गायब इनपुट इंटरफेस बस किसी भी घटना उत्पन्न नहीं करता है। यह आपके पृष्ठ के लिए एक पारदर्शी समाधान लागू करना आसान बनाता है।

यह उस इंटरफ़ेस पर आता है जो आप इंटरफ़ेस को पसंद करते हैं और उस इंटरफ़ेस को अनुकरण करते हैं जब हार्डवेयर इसके लिए अनुपलब्ध होता है। इस मामले में मैं माउस को बनाए गए किसी भी स्पर्श ईवेंट से अनुकरण करूंगा।

कार्यक्रम प्रोग्रामेटिक रूप से बनाना।

कोड ईवेंट बनाने और प्रेषण करने के लिए MouseEvent ऑब्जेक्ट का उपयोग करता है। इसका उपयोग करना आसान है और वास्तविक माउस घटनाओं से घटनाएं अलग-अलग हैं। MouseEvents goto के विस्तृत विवरण के लिए MDN MouseEvent

इसकी सबसे बुनियादी स्थिति में।

एक माउस क्लिक ईवेंट बनाएं और यह दस्तावेज़

var event = new MouseEvent("click", {'view': window, 'bubbles': true,'cancelable': true}); 
    document.dispatchEvent(event); 

आप अलग-अलग तत्वों को घटना प्रेषण कर सकते हैं करने के लिए प्रेषण।

document.getElementById("someButton").dispatchEvent(event); 

घटना सुनने के लिए यह वास्तविक माउस को सुनने जैसा ही है।

document.getElementById("someButton").addEventListener(function(event){ 
     // your code 
)); 

MouseEvent समारोह में दूसरा तर्क ईवेंट के बारे में अतिरिक्त जानकारी जोड़ सकते हैं जहां है। उदाहरण के लिए clientX और clientY माउस की स्थिति, या which या buttons कहें जिसके लिए बटन/एस दबाया जा रहा है।

यदि आपने कभी mouseEvent पर देखा है तो आपको पता चलेगा कि बहुत सारे गुण हैं। तो माउस ईवेंट में जो भी आप भेजते हैं वह इस बात पर निर्भर करेगा कि आपका ईवेंट श्रोता क्या उपयोग कर रहा है।

टच ईवेंट।

टच ईवेंट माउस के समान हैं। touchstart, touchmove, और touchend है। वे अलग-अलग होते हैं कि वे प्रत्येक बिंदु के संपर्क के लिए स्थानों की एक सरणी प्रदान करते हैं। निश्चित नहीं है कि अधिकतम क्या है लेकिन इस उत्तर के लिए हम केवल एक में रूचि रखते हैं। पूर्ण विवरण के लिए MDN touchEvent देखें।

हमें जो करना है वह स्पर्श घटनाओं के लिए है जिसमें केवल एक संपर्क बिंदु शामिल है जिसे हम उसी स्थान पर संबंधित माउस ईवेंट जेनरेट करना चाहते हैं। यदि टच इवेंट एक से अधिक संपर्क बिंदु देता है, तो हम नहीं जान सकते कि उनका इच्छित फोकस किस प्रकार है ताकि हम उन्हें अनदेखा कर सकें।

function touchEventHandler(event){ 
    if (event.touches.length > 1){ // Ignor multi touch events 
     return; 
    } 
} 

तो अब हम जानते स्पर्श एक संपर्क हम माउस स्पर्श घटनाओं में जानकारी के आधार पर ईवेंट बनाने के बारे में जा सकते हैं कि।

मूल बात

touch = event.changedTouches[0]; // get the position information 
if(type === "touchmove"){   
    mouseEventType = "mousemove"; // get the name of the mouse event 
            // this touch will emulate 
}else 
if(type === "touchstart"){ 
    mouseEventType = "mousedown";  // mouse event to create 
}else 
if(type === "touchend"){ 
    mouseEventType = "mouseup";  // ignore mouse up if click only 
} 

var mouseEvent = new MouseEvent(// create event 
    mouseEventType, // type of event 
    { 
     'view': event.target.ownerDocument.defaultView, 
     'bubbles': true, 
     'cancelable': true, 
     'screenX':touch.screenX, // get the touch coords 
     'screenY':touch.screenY, // and add them to the 
     'clientX':touch.clientX, // mouse event 
     'clientY':touch.clientY, 
}); 
// send it to the same target as the touch event contact point. 
touch.target.dispatchEvent(mouseEvent); 

अब अपने माउस श्रोताओं एक उपयोगकर्ता केवल एक स्थान पर उपकरण को स्पर्श जब mousedown, mousemove, mouseup घटनाओं प्राप्त होगा।

अब तक क्लिक

सभी अच्छे गुम लेकिन वहाँ एक माउस घटना याद आ रही है, उस रूप में अच्छी तरह जरूरत है। "ऑनक्लिक" मुझे यकीन नहीं है कि एक समतुल्य स्पर्श घटना है और जैसे ही मैंने देखा है कि हमें यह तय करने के लिए पर्याप्त जानकारी है कि टच इवेंट्स का एक सेट क्लिक पर विचार किया जा सकता है या नहीं।

यह इस बात पर निर्भर करेगा कि प्रारंभ और अंत स्पर्श घटनाएं कितनी दूर हैं, कुछ पिक्सेल से अधिक और इसकी एक ड्रैग है। यह भी कितना समय पर निर्भर करेगा। (हालांकि माउस के समान नहीं) मुझे लगता है कि लोग क्लिक के लिए टैप करते हैं, जबकि एक माउस को आयोजित किया जा सकता है, रिलीज पर संरचना के बदले, या रद्द करने के लिए खींचें, ऐसा नहीं है कि लोग टच इंटरफ़ेस का उपयोग कैसे करते हैं।

तो मैं टचस्टार्ट घटना का समय रिकॉर्ड करता हूं। event.timeStamp और जहां यह शुरू हुआ। फिर touchEnd घटना पर मुझे लगता है कि यह दूरी कितनी दूरीांतरित हो गई है और उस समय से। यदि वे दोनों सीमाओं के तहत हैं, तो मैंने माउस अप इवेंट के साथ माउस क्लिक इवेंट भी बनाया है।

तो यह स्पर्श घटनाओं को माउस घटनाओं में परिवर्तित करने का मूल तरीका है।

कुछ कोड

नीचे एक छोटे से एपीआई mouseTouch कहा जाता है कि मैं सिर्फ क्या समझा दिया है। इसमें एक साधारण ड्राइंग ऐप में आवश्यक सबसे बुनियादी माउस इंटरैक्शन शामिल हैं।

//        _______    _  
//        |__ __|    | |  
// _ __ ___ ___ _ _ ___ ___| | ___ _ _ ___| |__ 
// | '_ ` _ \/_ \| | |/__|/ _ \ |/ _ \| | | |/ __| '_ \ 
// | | | | | | (_) | |_| \__ \ __/ | (_) | |_| | (__| | | | 
// |_| |_| |_|\___/ \__,_|___/\___|_|\___/ \__,_|\___|_| |_| 
//                
//  
// Demonstration of a simple mouse emulation API using touch events. 

// Using touch to simulate a mouse. 
// Keeping it clean with touchMouse the only pubic reference. 
// See Usage instructions at bottom. 
var touchMouse = (function(){ 
    "use strict"; 
    var timeStart, touchStart, mouseTouch, listeningElement, hypot; 


    mouseTouch = {}; // the public object 
    // public properties. 
    mouseTouch.clickRadius = 3; // if touch start and end within 3 pixels then may be a click 
    mouseTouch.clickTime = 200; // if touch start and end in under this time in ms then may be a click 
    mouseTouch.generateClick = true; // if true simulates onClick event 
            // if false only generate mousedown, mousemove, and mouseup 
    mouseTouch.clickOnly = false; // if true on generate click events 
    mouseTouch.status = "Started."; // just for debugging 



    // ES6 new math function 
    // not sure the extent of support for Math.hypot so hav simple poly fill 
    if(typeof Math.hypot === 'function'){ 
     hypot = Math.hypot; 
    }else{ 
     hypot = function(x,y){ // Untested 
      return Math.sqrt(Math.pow(x,2)+Math.pow(y,2)); 
     }; 
    } 
    // Use the new API and MouseEvent object 
    function triggerMouseEvemt(type,fromTouch,fromEvent){ 
     var mouseEvent = new MouseEvent(
      type, 
      { 
       'view': fromEvent.target.ownerDocument.defaultView, 
       'bubbles': true, 
       'cancelable': true, 
       'screenX':fromTouch.screenX, 
       'screenY':fromTouch.screenY, 
       'clientX':fromTouch.clientX, 
       'clientY':fromTouch.clientY, 
       'offsetX':fromTouch.clientX, // this is for old Chrome 
       'offsetY':fromTouch.clientY, 
       'ctrlKey':fromEvent.ctrlKey, 
       'altKey':fromEvent.altKey, 
       'shiftKey':fromEvent.shiftKey, 
       'metaKey':fromEvent.metaKey, 
       'button':0, 
       'buttons':1, 
      }); 
     // to do. 
     // dispatch returns cancelled you will have to 
     // add code here if needed 
     fromTouch.target.dispatchEvent(mouseEvent); 
    } 

    // touch listener. Listens to Touch start, move and end. 
    // dispatches mouse events as needed. Also sends a click event 
    // if click falls within supplied thresholds and conditions 
    function emulateMouse(event) { 

     var type, time, touch, isClick, mouseEventType, x, y, dx, dy, dist; 
     event.preventDefault(); // stop any default happenings interfering 
     type = event.type ; // the type. 

     // ignore multi touch input 
     if (event.touches.length > 1){ 
      if(touchStart !== undefined){ // don't leave the mouse down 
       triggerMouseEvent("mouseup",event.changedTouches[0],event); 
      } 
      touchStart = undefined; 
      return; 
     } 
     mouseEventType = ""; 
     isClick = false; // default no click 
     // check for each event type I have the most numorus move event first, Good practice to always think about the efficancy for conditional coding. 
     if(type === "touchmove" && !mouseTouch.clickOnly){  // touchMove 
      touch = event.changedTouches[0]; 
      mouseEventType = "mousemove";  // not much to do just move the mouse 
     }else 
     if(type === "touchstart"){ 
      touch = touchStart = event.changedTouches[0]; // save the touch start for dist check 
      timeStart = event.timeStamp; // save the start time 
      mouseEventType = !mouseTouch.clickOnly?"mousedown":"";  // mouse event to create 
     }else 
     if(type === "touchend"){ // end check time and distance 
      touch = event.changedTouches[0]; 
      mouseEventType = !mouseTouch.clickOnly?"mouseup":"";  // ignore mouse up if click only 
      // if click generator active 
      if(touchStart !== undefined && mouseTouch.generateClick){ 
       time = event.timeStamp - timeStart; // how long since touch start 
       // if time is right 
       if(time < mouseTouch.clickTime){ 
        // get the distance from the start touch 
        dx = touchStart.clientX-touch.clientX; 
        dy = touchStart.clientY-touch.clientY; 
        dist = hypot(dx,dy); 
        if(dist < mouseTouch.clickRadius){ 
         isClick = true; 
        } 
       } 
      } 
     } 
     // send mouse basic events if any 
     if(mouseEventType !== ""){ 
      // send the event 
      triggerMouseEvent(mouseEventType,touch,event); 
     } 
     // if a click also generates a mouse click event 
     if(isClick){ 
      // generate mouse click 
      triggerMouseEvent("click",touch,event); 
     } 
    } 

    // remove events 
    function removeTouchEvents(){ 
     listeningElement.removeEventListener("touchstart", emulateMouse); 
     listeningElement.removeEventListener("touchend", emulateMouse); 
     listeningElement.removeEventListener("touchmove", emulateMouse); 
     listeningElement = undefined; 

    } 

    // start adds listeners and makes it all happen. 
    // element is optional and will default to document. 
    // or will Listen to element. 
    function startTouchEvents(element){ 
     if(listeningElement !== undefined){ // untested 
      // throws to stop cut and past useage of this example code. 
      // Overwriting the listeningElement can result in a memory leak. 
      // You can remove this condition block and it will work 
      // BUT IT IS NOT RECOGMENDED 

      throw new ReferanceError("touchMouse says!!!! API limits functionality to one element."); 
     } 
     if(element === undefined){ 
      element = document; 
     } 
     listeningElement = element; 
     listeningElement.addEventListener("touchstart", emulateMouse); 
     listeningElement.addEventListener("touchend", emulateMouse); 
     listeningElement.addEventListener("touchmove", emulateMouse); 
    } 

    // add the start event to public object. 
    mouseTouch.start = startTouchEvents; 
    // stops event listeners and remove them from the DOM 
    mouseTouch.stop = removeTouchEvents; 

    return mouseTouch; 

})(); 











// How to use 

touchMouse.start(); // done using defaults will emulate mouse on the entier page 

// For one element and only clicks 
// HTML 
<input value="touch click me" id="touchButton" type="button"></input> 
// Script 
var el = document.getElementById("touchButton"); 
if(el !== null){ 
    touchMouse.clickOnly = true; 
    touchMouse.start(el); 
} 

// For drawing on a canvas 
<canvas id="touchCanvas"></canvas> 
// script 
var el = document.getElementById("touchButton"); 
if(el !== null){ 
    touchMouse.generateClick = false; // no mouse clicks please 
    touchMouse.start(el); 
} 

// For switching elements call stop then call start on the new element 
// warning touchMouse retained a reference to the element you 
// pass it with start. Dereferencing touchMouse will not delete it. 
// Once you have called start you must call stop in order to delete it. 

// API 
//--------------------------------------------------------------- 
// To dereference call the stop method if you have called start . Then dereference touchMouse 
// Example 
touchMouse.stop(); 
touchMouse = undefined; 


// Methods. 
//--------------------------------------------------------------- 
// touchMouse.start(element); // element optional. Element is the element to attach listeners to. 
           // Calling start a second time without calling stop will 
           // throw a reference error. This is to stop memory leaks. 
           // YOU Have been warned... 

// touchMouse.stop();   // removes listeners and dereferences any DOM objects held 
//--------------------------------------------------------------- 
// Properties 
// mouseTouch.clickRadius = 3; // Number. Default 3. If touch start and end within 3 pixels then may be a click 
// mouseTouch.clickTime = 200; // Number. Default 200. If touch start and end in under this time in ms then may be a click 
// mouseTouch.generateClick; // Boolean. Default true. If true simulates onClick event 
//         // if false only generate mousedown, mousemove, and mouseup 
// mouseTouch.clickOnly;  // Boolean. Default false. If true only generate click events Default false 
// mouseTouch.status;   // String. Just for debugging kinda pointless really. 

तो आशा है कि यह आपके कोड के साथ आपकी सहायता करे।

संबंधित मुद्दे