locked
MSPointerDown, MSPointerMove and MSPointerUp vs mousedown, mousemove and mouse up RRS feed

  • Question

  • HEllo guys.

    So, here's the story: I've got an app which draws rectangles in an svg element in response to mouse movement (just the traditional stuff: a new figure is started when the left mouse button is down and it ends when you release the mouse). Now, I'm under the impression that this stuff in Metro Apps should be done in the MSPointerDown, MSPointerMove and MSPointerUp events, right? So, I've went ahead and I've changed the name of the events:

    area = document.getElementById("areaDesenho");
    area.addEventListener("MSPointerDown", pointerDown);
    area.addEventListener("MSPointerMove", pointerMove);
    area.addEventListener("MSPointerUp", pointerUp);

    NOw, I have only made one small change: instead of using a boolean, I'm using the pointerId to check if the pointerdown event should update my svg rect or not. Here's my current code:

    var pointerID = null;
        
    function pointerDown(evt) {
        if (evt.pointerType === 4 && evt.button !== 1) {
            return;
        }


        retangulo.x = evt.offsetX;
        retangulo.y = evt.offsetY;
        retangulo.atualizaFigura(figuraAuxiliar);
        area.appendChild(figuraAuxiliar);
        pointerID = evt.pointerId;
    }
       
    function pointerMove(evt) {
        if (evt.pointerId !== pointerID) return;
            
        retangulo.width = evt.offsetX - retangulo.x;
        retangulo.height = evt.offsetY - retangulo.y;
        retangulo.atualizaFigura(figuraAuxiliar);
        retangulo.log();
    }
    function pointerUp(evt) {
        figuraAuxiliar = inicializaFigura();
        retangulo.efetuaReset();
        pointerID = null;
    }               

    Now, the problem: Not sure why, but for it to work I need to doubleclick at start! 

    If I only click once and start drawing by dragging the mouse, I see nothing. Since I'm logging info, I can see two or three calls coming from the pointer down event and then it stops. If I release the mouse's button, then the pointer down code starts firing again!

    So, I've went ahead and disabled mouse events (prevenMouseEvent). Since I'm not doing any kind of mouse event handling in my app, I'm not sure on why I need to call this method. For instance, I've looked at the ink sample and this method is not being used there. 

    Is this a bug? 

    Thanks.




    Luis Abreu

    Tuesday, March 13, 2012 10:48 PM

Answers

All replies

  • Hi Luis,

    Thanks for the thorough explanation.  Let's rewind a bit.  Is this a problem with those particular events only?  If you go back to the old mouse events does it work fine?

    -Jeff


    Jeff Sanders (MSFT)

    Wednesday, March 14, 2012 12:51 PM
    Moderator
  • Hello Jeff.

    Yes, the same code works perfectly with the mousedown, mousemove and mouseup events (instead of using the pointerId, I was using a boolean guard which was initialized to true in mousedown and set to false in mouseup). As I said, things stop working if I don't call the preventMouseEvent from within the pointer event handlers...


    Luis Abreu

    Thursday, March 15, 2012 10:02 AM
  • Thursday, March 15, 2012 2:53 PM
    Moderator
  • Hello Jeff.

    Have already read them. Besides the preventManipulation (which is not -ms-touch-action and that is working here in my sample), I haven't really seen any notice about needing to call preventeMouseEvent in order for my code to work.

    I've already added some code whcioh allows me to drag the rects, but if you want and if there's someone to take a look, I can pack a small sample and send it by email which reproduces the problem I'm facing here...

    thanks.


    Luis Abreu

    Thursday, March 15, 2012 10:55 PM
  • Hi Luis,

    Send me an email from here and we will connect for the transfer:  http://blogs.msdn.com/jpsanders/contact.aspx

    -Jeff


    Jeff Sanders (MSFT)

    Friday, March 16, 2012 1:32 PM
    Moderator
  • I'll build the simplest sample I can that reproduces the problem and I'll send it to you.

    thanks.


    Luis Abreu

    Friday, March 16, 2012 8:59 PM
  • Hello again Jeff.

    I think I'll just put the code I'm using here. To reproduce the problem you only need to copy/paste the code and comment the preventmouseevent method. Btw, the problems only happen when you use the mouse (ie, when using touch in the simulator, there's no need to call the preventmouseevent method).

    The HTML file has the following markup:

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>MSPointerDown</title>


        <!-- WinJS references -->
        <link href="//Microsoft.WinJS.0.6/css/ui-light.css" rel="stylesheet">
        <script src="//Microsoft.WinJS.0.6/js/base.js"></script>
        <script src="//Microsoft.WinJS.0.6/js/ui.js"></script>


        <!-- MSPointerDown references -->
        <link href="/css/default.css" rel="stylesheet">
        <script src="/js/default.js"></script>
    </head>
    <body>
         <svg id="areaDesenho">
        </svg>
    </body>
    </html>

    And here's the code of the js file:

    // For an introduction to the Blank template, see the following documentation:
    // http://go.microsoft.com/fwlink/?LinkId=232509
    (function () {
        "use strict";
        var retangulo = {
            x: 0, y: 0, width: 0, height: 0,
            obtemX: function () {
                return this.width < 0 ? this.x - Math.abs(this.width) : this.x;
            },
            obtemY: function () {
                return this.height < 0 ? this.y - Math.abs(this.height) : this.y;
            },
            obtemAltura: function () {
                return Math.abs(this.height);
            }
            ,
            obtemLargura: function () {
                return Math.abs(this.width);
            },
            efetuaReset: function () {
                this.x = this.y = this.width = this.height = 0;
            },
            atualizaFigura: function (figura) {
                figura.setAttributeNS(null, "x", this.obtemX());
                figura.setAttributeNS(null, "y", this.obtemY());
                figura.setAttributeNS(null, "width", this.obtemLargura());
                figura.setAttributeNS(null, "height", this.obtemAltura());
            },
            log: function () {
                console.log("x: " + this.x + "; y: " + this.y + " ---- width: " + this.width + "; height: " + this.height);
            }
        };
        
        var app = WinJS.Application;
        var area = null;
        var figuraAuxiliar = null;
        var pointerID = null;
        app.onactivated = function (eventObject) {
            area = document.getElementById("areaDesenho");
            area.addEventListener("MSPointerDown", pointerDown);
            area.addEventListener("MSPointerMove", pointerMove);
            area.addEventListener("MSPointerUp", pointerUp);
            figuraAuxiliar = inicializaFigura();
        };
        function inicializaFigura(tipoFigura) {
            var ret = document.createElementNS("http://www.w3.org/2000/svg", "rect");
            ret.setAttributeNS(null, "fill", "lightgray");
            return ret;
        }
        function pointerDown(evt) {
            console.log("in pointer down");
            if (evt.pointerType === 4 && evt.button !== 1) {
                return;
            }
            
            retangulo.x = evt.offsetX;
            retangulo.y = evt.offsetY;
            retangulo.atualizaFigura(figuraAuxiliar);
            area.appendChild(figuraAuxiliar);
            
            //evt.preventMouseEvent();//uncomment to see it working
            pointerID = evt.pointerId;
            evt.target.msSetPointerCapture(pointerID);
        }
        function pointerMove(evt) {
            console.log("in pointer move");
            if (evt.pointerId !== pointerID) return;
            //evt.preventMouseEvent();//uncomment to see it working
           
            retangulo.width = evt.offsetX - retangulo.x;
            retangulo.height = evt.offsetY - retangulo.y;
            retangulo.atualizaFigura(figuraAuxiliar);
            retangulo.log();
           
        }
        function pointerUp(evt) {
            console.log("in pointer up");
            //evt.preventMouseEvent();//uncomment to see it working
            figuraAuxiliar = inicializaFigura();
            retangulo.efetuaReset();
            
            pointerID = null;
        }


        app.oncheckpoint = function (eventObject) {
            // TODO: This application is about to be suspended. Save any state
            // that needs to persist across suspensions here. You might use the 
            // WinJS.Application.sessionState object, which is automatically
            // saved and restored across suspension. If you need to complete an
            // asynchronous operation before your application is suspended, call
            // eventObject.setPromise(). 
        };


        app.start();
    })();

    thanks again.


    Luis Abreu

    Monday, March 19, 2012 2:16 PM
  • I will check this out Luis,

    Thanks for the repro!

    -Jeff


    Jeff Sanders (MSFT)

    Monday, March 19, 2012 2:18 PM
    Moderator
  • I found what I believe to be a related bug and will investigate further.  Does your workaround prevent you from doing what you need to do in your application?

    -Jeff


    Jeff Sanders (MSFT)

    Monday, March 19, 2012 3:09 PM
    Moderator
  • Hello again Jeff.

    No. Since I'm writing all my code for touch and I still get the mouse for free, then there's no problem in my case (I'm not doing any thing on the traditional mouse events and everything is handled through the MSPOinterXXX events). I just mentioned it here because I've discovered it (without even looking for it :))  and I really thought that preventing mouse events was optional (and not mandatory).

    thanks.


    Luis Abreu

    Tuesday, March 20, 2012 10:17 AM
  • OK, thanks for reporting this Luis!

    -Jeff


    Jeff Sanders (MSFT)

    Tuesday, March 20, 2012 12:13 PM
    Moderator
  • Hello again.

    Jeff, what's the status of this bug? In my code, I've removed the preventDefault call (previously known as preventMouseEvent) and it seems like it's working...


    Luis Abreu

    Tuesday, June 5, 2012 11:50 AM
  • Should be fixed!

    Jeff Sanders (MSFT)

    Tuesday, June 5, 2012 1:09 PM
    Moderator
  • Yes, it's working. thanks.

    Luis Abreu

    Friday, June 8, 2012 2:24 PM