Pointers complete code

This topic has not yet been rated - Rate this topic

This topic provides the complete code sample used in Quickstart: Pointers.

This topic contains these sections:

Download location

This sample is not available for download.

Technologies

Programming languagesCSS, HTML, JavaScript
Programming modelsWindows Runtime

Requirements

Minimum supported clientWindows 8
Minimum supported serverWindows Server 2012
Minimum required SDKMicrosoft Visual Studio Express 2012 for Windows 8

View the code ()

default.css


body {
    overflow: hidden;
    position: relative;
}

#grid {
    display: -ms-grid;
    height: 100vh; /* 100% of viewport height */
    -ms-grid-columns: 4fr 1fr; /* 2 columns */
    -ms-grid-rows: 1fr 320px 1fr;  /* 3 rows */
    -ms-touch-action: none; /* Disable panning and zooming */
}
#top {
    -ms-grid-row: 1;
    -ms-grid-column: 1;
}
#targetContainer {
    -ms-grid-row: 2;
    -ms-grid-column: 1;
    -ms-grid-row-align: center;
    -ms-grid-column-align: center;
    -ms-touch-action: none; /* Disable panning and zooming */
}
#bottom {
    -ms-grid-row: 3;
    -ms-grid-column: 1;
    -ms-grid-column-align: center;
}
#eventLog {
    -ms-grid-row: 1;
    -ms-grid-column: 2; 
    -ms-grid-row-span: 3;
    padding: 10px;
    background-color: black;
    color: white;
}
#target {
    width: 640px;
    height: 320px;
    border: none;
    padding: 0px;
    margin: 0px;
    -ms-transform-origin: 0% 0%;
    -ms-touch-action: none; /* Disable panning and zooming */
}


default.html


<html>
<head>
    <meta charset="utf-8" />
    <title>PointerInput</title>
    
    <!-- WinJS references -->
    <link href="//Microsoft.WinJS.1.0/css/ui-dark.css" rel="stylesheet" />
    <script src="//Microsoft.WinJS.1.0/js/base.js"></script>
    <script src="//Microsoft.WinJSo.1.0/js/ui.js"></script>

    <!-- PointerInput references -->
    <link href="/css/default.css" rel="stylesheet" />
    <script src="/js/default.js"></script>
</head>
<body id="app">
    <div id="grid">
        <div id="targetContainer">
            <div id="target"></div>
        </div>
        <div id="bottom">
        </div>
        <div id="eventLog"></div>
    </div>
</body>
</html>


default.js


(function () {
    "use strict";

    var
    // For this example, we track simultaneous contacts in case the 
    // number of contacts has reached the maximum supported by the device.
    // Depending on the device, additional contacts might be ignored 
    // (PointerPressed not fired). 
    numActiveContacts = 0,

    // The input target.
    target,

    // Pointer info (array of pointer Ids and pointer types).
    pInfo,

    // Target background colors corresponding to various pointer states.
    pointerColor = {
        hover: "rgb(255, 255, 102)",
        down: "rgb(0, 255, 0)",
        up: "rgb(255, 0, 0)",
        cancel: "rgb(0,0,0)",
        out: "rgb(127,127,127)",
        over: "rgb(0,0,255)"
    },

    // The event log (updated on each event).
    eventLog;

    function initialize() {
        // Configure the target.
        eventLog = document.getElementById("eventLog");
        target = document.getElementById("target");
        setTarget();
    }

    function setTarget() {
        //  Set up the target position and size.
        target.style.backgroundColor = pointerColor.out;

        // Expando dictionary property to track active contacts. An entry is added 
        // during MSPointerDown/MSPointerHover/MSPointerOver events and removed 
        // during MSPointerUp/MSLostPointerCapture/MSPointerCancel/MSPointerOut events.
        target.pointers = [];
        pInfo = [];

        // Declare pointer event handlers.
        target.addEventListener("MSPointerDown", onMSPointerDown, true);
        target.addEventListener("MSPointerHover", onMSPointerHover, true);
        target.addEventListener("MSPointerOver", onMSPointerOver, true);
        target.addEventListener("MSPointerUp", onMSPointerUp, true);
        target.addEventListener("MSPointerOut", onMSPointerOut, true);
        target.addEventListener("MSPointerCancel", onMSPointerCancel, true);
        target.addEventListener("MSLostPointerCapture", onMSLostPointerCapture, true);
        target.addEventListener("MSPointerMove", onMSPointerMove, true);
        target.addEventListener("wheel", onMouseWheel, false);
    }

    // MSPointerDown and MSPointerUp events do not always occur in pairs. 
    // Listen for and handle any event that might conclude a pointer down action 
    // (such as MSPointerUp, MSPointerOut, MSPointerCancel, and MSLostPointerCapture).
    // For this example, we track the number of contacts in case the 
    // number of contacts has reached the maximum supported by the device.
    // Depending on the device, additional contacts might be ignored 
    // (PointerPressed not fired). 
    function onMSPointerDown(e) {
        e.cancelBubble = true;

        // Check if the number of supported contacts is exceeded.
        var touchCapabilities = new Windows.Devices.Input.TouchCapabilities();
        if ((touchCapabilities.touchPresent != 0) & (numActiveContacts > touchCapabilities.contacts)) {
            return;
        }

        // Update event details and target UI.
        eventLog.innerText += "\nDown: " + e.pointerId;
        target.style.backgroundColor = pointerColor.down;

        // Check if pointer already exists (if hover/over occurred prior to down).
        for (var i in target.pointers) {
            if (target.pointers[i][0] === e.pointerId) {
                return;
            }
        }

        // Push new pointer Id onto expando target pointers array.
        pInfo.push(e.pointerId, e.pointerType);
        target.pointers.push(pInfo);

        // Ensure that the element continues to receive MSPointerEvents 
        // even if the contact moves off the element. 
        // Capturing the current pointer can improve usability by reducing 
        // the touch precision required when interacting with an element.
        // Note: Only the assigned pointer is affected. 
        target.msSetPointerCapture(e.pointerId);

        // Display pointer details.
        createInfoPop(e);
    }

    function onMSPointerUp(e) {
        e.cancelBubble = true;

        // Update event details.
        eventLog.innerText += "\nUp: " + e.pointerId;

        // If event source is mouse pointer and the pointer is still 
        // over the target, retain pointer and pointer details.
        // Return without removing pointer from pointers dictionary.
        // For this example, we assume a maximum of one mouse pointer.
        if ((e.pointerType === e.MSPOINTER_TYPE_MOUSE) &
            (document.elementFromPoint(e.x, e.y) === target)) {
            target.style.backgroundColor = pointerColor.up;
            return;
        }

        // Ensure capture is released on a pointer up event.
        target.msReleasePointerCapture(e.pointerId);

        // Remove pointer from pointers dictionary.
        for (var i in target.pointers) {
            if (target.pointers[i][0] === e.pointerId) {
                target.pointers.splice(i, 1);
                var pointerInfoPop = document.getElementById("infoPop" + e.pointerId);
                if (pointerInfoPop === null)
                    return;
                pointerInfoPop.removeNode(true);
            }
        }

        // Update target UI.
        if (target.pointers.length === 0) {
            target.style.backgroundColor = pointerColor.up;
        }
    }

    function onMSPointerMove(e) {
        e.cancelBubble = true;

        // Multiple, simultaneous mouse button inputs are processed here.
        // Mouse input is associated with a single pointer assigned when 
        // mouse input is first detected. 
        // Clicking additional mouse buttons (left, wheel, or right) during 
        // the interaction creates secondary associations between those buttons 
        // and the pointer through the pointer pressed event. 
        // The pointer released event is fired only when the last mouse button 
        // associated with the interaction (not necessarily the initial button) 
        // is released. 
        // Because of this exclusive association, other mouse button clicks are 
        // routed through the pointer move event.          
        if (e.pointerType == e.MSPOINTER_TYPE_MOUSE) {
            // Mouse button states are extended PointerPoint properties.
            var pt = e.getCurrentPoint(e.currentTarget);
            var ptProperties = pt.properties;
            if (ptProperties.isLeftButtonPressed) {
                eventLog.innerText += "\nLeft button: " + e.pointerId;
            }
            if (ptProperties.isMiddleButtonPressed) {
                eventLog.innerText += "\nWheel button: " + e.pointerId;
            }
            if (ptProperties.isRightButtonPressed) {
                eventLog.innerText += "\nRight button: " + e.pointerId;
            }
        }

        // Display pointer details.
        updateInfoPop(e);
    }

    function onMSPointerOver(e) {
        e.cancelBubble = true;

        // Update event details and target UI.
        eventLog.innerText += "\nOver: " + e.pointerId;

        if (target.pointers.length === 0) {
            // Change background color of target when pointer contact detected.
            if (e.getCurrentPoint(e.currentTarget).isInContact) {
                // Pointer down occured outside target.
                target.style.backgroundColor = pointerColor.down;
            } else {
                // Pointer down occured inside target.
                target.style.backgroundColor = pointerColor.over;
            }
        }

        // Check if pointer already exists.
        for (var i in target.pointers) {
            if (target.pointers[i][0] === e.pointerId) {
                return;
            }
        }

        // Push new pointer Id onto expando target pointers array.
        pInfo.push(e.pointerId, e.pointerType);
        target.pointers.push(pInfo);

        // Ensure that the element continues to receive MSPointerEvents 
        // even if the contact moves off the element. 
        // Capturing the current pointer can improve usability by reducing 
        // the touch precision required when interacting with an element.
        // Note: Only the assigned pointer is affected. 
        target.msSetPointerCapture(e.pointerId);

        // Display pointer details.
        createInfoPop(e);
    }

    // Fires when pointer departs target detection (move and after up) or
    // a pointer in hover state departs detection range without making contact.
    // Note: Pointer capture is maintained until pointer up event.
    function onMSPointerOut(e) {
        e.cancelBubble = true;

        // Update event details.
        eventLog.innerText += "\nPointer out: " + e.pointerId;

        // Remove pointer from pointers dictionary.
        for (var i in target.pointers) {
            if (target.pointers[i][0] === e.pointerId) {
                target.pointers.splice(i, 1);
                var pointerInfoPop = document.getElementById("infoPop" + e.pointerId);
                if (pointerInfoPop === null)
                    return;
                pointerInfoPop.removeNode(true);

                // Update target UI.
                if (target.pointers.length === 0) {
                    target.style.backgroundColor = pointerColor.out;
                }
            }
        }
    }

    // Fires when a pen device pointer enters detection range.
    function onMSPointerHover(e) {
        e.cancelBubble = true;

        // Update event details and target UI.
        target.style.backgroundColor = pointerColor.hover;

        // Check if pointer already exists.
        for (var i in target.pointers) {
            if (target.pointers[i][0] === e.pointerId) {
                updateInfoPop(e);
                return;
            }
        }

        // Push new pointer Id onto expando target pointers array.
        pInfo.push(e.pointerId, e.pointerType);
        target.pointers.push(pInfo);
        //target.pointers.push(e.pointerId);

        // Display pointer details.
        createInfoPop(e);
    }

    function onMouseWheel(e) {
        // Check if a mouse pointer already exists.
        for (var i in target.pointers) {
            // Ensure existing pointer type is e.MSPOINTER_TYPE_MOUSE (4). 
            if (target.pointers[i][1] === 4) {
                e.pointerId = target.pointers[i][0];
                break;
            }
        }
        eventLog.innerText += "\nMouse wheel: " + e.pointerId;
        // For this example, we fire a corresponding pointer down event.
        onMSPointerDown(e);
    }

    // Fires for for various reasons, including: 
    //    - A touch contact is canceled by a pen coming into range of the surface.
    //    - The device doesn't report an active contact for more than 100ms.
    //    - The desktop is locked or the user logged off. 
    //    - The number of simultaneous contacts exceeded the number supported by the device.
    function onMSPointerCancel(e) {
        e.cancelBubble = true;

        // Update event details.
        eventLog.innerText += "\nPointer canceled: " + e.pointerId;

        // Ensure capture is released on a pointer cancel event.
        target.msReleasePointerCapture(e.pointerId);

        // Update target UI.
        if (target.pointers.length === 0) {
            target.style.backgroundColor = pointerColor.cancel;
        }

        // Remove pointer from pointers dictionary.
        for (var i in target.pointers) {
            if (target.pointers[i][0] === e.pointerId) {
                target.pointers.splice(i, 1);
                var pointerInfoPop = document.getElementById("infoPop" + e.pointerId);
                if (pointerInfoPop === null)
                    return;
                pointerInfoPop.removeNode(true);
            }
        }
    }

    // Fires for for various reasons, including: 
    //    - User interactions
    //    - Programmatic caputre of another pointer
    //    - Captured pointer was deliberately released
    // MSLostPointerCapture can fire instead of MSPointerUp. 
    function onMSLostPointerCapture(e) {
        e.cancelBubble = true;

        // Update event details.
        eventLog.innerText += "\nLost pointer capture: " + e.pointerId;

        // We need the device type to handle lost pointer capture from mouse input.
        // Use the getCurrentPoint method over currentPoint property to ensure
        // the coordinate space is in relation to the target element.
        // Note: getCurrentPoint and currentPoint are only available in the 
        // local compartment, they are not available in the web compartment.
        var ptTarget = e.getCurrentPoint(e.currentTarget);
        var ptContainer = e.getCurrentPoint(app);

        // If event source is mouse pointer and the pointer is still over 
        // the target, retain pointer and pointer details.
        // For this example, we assume only one mouse pointer.
        if ((ptTarget.pointerDevice.pointerDeviceType === Windows.Devices.Input.PointerDeviceType.mouse) &
            (document.elementFromPoint(ptContainer.position.x, ptContainer.position.y) === target)) {
            target.msSetPointerCapture(e.pointerId);
            return;
        }

        // Remove pointer from pointers dictionary.
        for (var i in target.pointers) {
            if (target.pointers[i][0] === e.pointerId) {
                target.pointers.splice(i, 1);
                var pointerInfoPop = document.getElementById("infoPop" + e.pointerId);
                if (pointerInfoPop === null)
                    return;
                pointerInfoPop.removeNode(true);
            }
        }

        // Update target UI.
        if (target.pointers.length === 0) {
            target.style.backgroundColor = pointerColor.cancel;
        }
    }

    // Create DIV and insert it into the document hierarchy to display pointer details.
    function createInfoPop(e) {
        var infoPop = document.createElement("div");
        infoPop.setAttribute("id", "infoPop" + e.pointerId);

        // Set screen position of DIV.
        var transform = (new MSCSSMatrix()).translate(e.offsetX + 20, e.offsetY + 20);
        infoPop.style.msTransform = transform;
        target.appendChild(infoPop);

        infoPop.innerText = queryPointer(e);
    }

    function updateInfoPop(e) {
        var infoPop = document.getElementById("infoPop" + e.pointerId);
        if (infoPop === null)
            return;

        // Set screen position of DIV.
        var transform = (new MSCSSMatrix()).translate(e.offsetX + 20, e.offsetY + 20);
        infoPop.style.msTransform = transform;
        infoPop.innerText = queryPointer(e);
    }


    // Get extended pointer data.
    function queryPointer(e) {
        // We get the extended pointer info through the getCurrentPoint method
        // of the event argument. (We recommend using getCurrentPoint 
        // to ensure the coordinate space is in relation to the target.)
        // Note: getCurrentPoint and currentPoint are only available in the 
        // local compartment, they are not available in the web compartment.
        var ptTargetProperties = e.getCurrentPoint(e.currentTarget).properties;

        var details = "Pointer Id: " + e.pointerId;
        switch (e.pointerType) {
            case e.MSPOINTER_TYPE_MOUSE:
                details += "\nPointer type: mouse";
                details += "\nLeft button: " + ptTargetProperties.isLeftButtonPressed;
                details += "\nRight button: " + ptTargetProperties.isRightButtonPressed;
                details += "\nWheel button: " + ptTargetProperties.isMiddleButtonPressed;
                details += "\nX1 button: " + ptTargetProperties.isXButton1Pressed;
                details += "\nX2 button: " + ptTargetProperties.isXButton2Pressed;
                break;
            case e.MSPOINTER_TYPE_PEN:
                details += "\nPointer type: pen";
                if (ptProperties.isInContact) {
                    details += "\nPressure: " + ptTargetProperties.pressure;
                    details += "\nrotation: " + ptTargetProperties.rotation;
                    details += "\nTilt X: " + ptTargetProperties.tiltX;
                    details += "\nTilt Y: " + ptTargetProperties.tiltY;
                    details += "\nBarrel button pressed: " + ptTargetProperties.isBarrelButtonPressed;
                }
                break;
            case e.MSPOINTER_TYPE_TOUCH:
                details += "\nPointer type: touch";
                details += "\nPressure: " + ptTargetProperties.pressure;
                details += "\nrotation: " + ptTargetProperties.rotation;
                details += "\nTilt X: " + ptTargetProperties.tiltX;
                details += "\nTilt Y: " + ptTargetProperties.tiltY;
                break;
            default:
                details += "\nPointer type: " + "n/a";
                break;
        }
        details += "\nPointer location (target): " + e.offsetX + ", " + e.offsetY;
        details += "\nPointer location (screen): " + e.screenX + ", " + e.screenY;

        return details;
    }

    document.addEventListener("DOMContentLoaded", initialize, false);

})();


 

 

Build date: 11/29/2012

Did you find this helpful?
(1500 characters remaining)
© 2013 Microsoft. All rights reserved.