官术网_书友最值得收藏!

Creating a visual compass to show the device direction

The geolocation and accelerometer plugins' API provides developers with the ability to receive coordinate and heading information from the device. We can use this information to build a custom compass tool that responds to the device movement.

How to do it…

  1. First, create a new PhoneGap project named compass by running the following command:
    phonegap create compass com.myapp.compass compass
    
  2. Add the device platform. You can choose to use Android, iOS, or both:
    cordova platform add ios
    cordova platform add android
    
  3. Add the device-orientation, device-motion, and geolocation plugins by running the following command:
    phonegap plugin add org.apache.cordova.device-motion
    phonegap plugin add org.apache.cordova.geolocation
    phonegap plugin add org.apache.cordova.device-orientation
    
  4. Open www/index.html and clean up unnecessary elements; so you have the following:
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8" />
            <meta name="format-detection" content="telephone=no" />
            <meta name="msapplication-tap-highlight" content="no" />
            <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
            <title>Compass</title>
        </head>
        <body>
    
            <script type="text/javascript" src="cordova.js"></script>
            <script type="text/javascript">
                // further code will be here
            </script>
        </body>
    </html>
  5. In this example, certain elements within the DOM will be referenced by class name. For this, the XUI JavaScript library (http://xuijs.com/) will be used. Add the script reference under the cordova reference:
    <script type="text/javascript" src="cordova.js"></script>
    <script type="text/javascript" src="xui.js"></script>
    
  6. Add a new div element within the body tag and give this the class attribute of container. This will hold the compass elements for display.
  7. The compass itself will be made up of two images. Both images will have an individual class name assigned to them, which will allow you to easily reference each of them within the JavaScript. Add these two within the container element.
  8. Next, write a new div element below the images with the id attribute set to heading. This will hold the text output from the compass response:
    <body>
        <div class="container">
    
                <img src="images/rose.png" class="rose" width="120" height="121" alt="rose" />
    
                <img src="images/compass.png" class="compass" width="200" height="200" alt="compass" />
    
            <div id="heading"></div>
    
        </div>
  9. With the initial layout complete, start writing the custom JavaScript code. First, define the deviceready event listener—as XUI is being used, this differs a little from other recipes within this chapter:
    var headingDiv;
    x$(document).on("deviceready", function () {
    });
  10. When you have a result to output to the user of the application, you want the data to be inserted into the div tag with the heading id attribute. XUI makes this a simple task; so update the headingDiv global variable to store this reference:
    x$(document).on("deviceready", function () {
        headingDiv = x$("#heading");
    });
  11. Now include the requests to the PhoneGap compass methods. We'll actually call two within the same function. First, obtain the current heading of the device for instant data, and then make a request through to watch the device heading, making the request every tenth of a second by using the frequency parameter; this will provide continual updates to ensure the compass is correct:
    navigator.compass.getCurrentHeading(onSuccess, onError);
    navigator.compass.watchHeading(onSuccess, onError, {frequency: 100});
  12. Both of these requests use the same onSuccess and onError method to handle output and data management. The onSuccess method will provide the returned data in the form of a heading object.
  13. You can use this returned data to set the HTML content of the heading element with the generated message string, using the headingDiv variable defined earlier.
  14. The visual compass also needs to respond to the heading information. Using XUI's CSS method, you can alter the transform properties of the rose image to rotate using the returned magneticHeading property. Here, reference the image by calling its individual class name, .rose:
    // Run after successful transaction
    // Let's display the compass data
    function onSuccess(heading) {
        headingDiv.html(
            'Heading: ' + heading.magneticHeading + '&#xb0; ' +
            convertToText(heading.magneticHeading) + '<br />' +
            'True Heading: ' + heading.trueHeading + '<br />' +
            'Accuracy: ' + heading.headingAccuracy
        );
    
        // Alter the CSS properties to rotate the rose image
        x$(".rose").css({
            "-webkit-transform":
            "rotate(-" + heading.magneticHeading + "deg)",
           "transform":
            "rotate(-" + heading.magneticHeading + "deg)"
        });
    
    }
  15. With the onSuccess handler in place, you now need to add the onError method to output a user-friendly message should you encounter any problems obtaining information:
    // Run if we face an error
    // obtaining the compass data
    function onError() {
        headingDiv.html(
            'There was an error trying to ' +
            'locate your current bearing.'
        );
    }
  16. When creating the message string in the onSuccess function, you made a call to a new function called convertToText. This accepts the magneticHeading value from the heading object and converts it into a text representation of the direction for display. Include this function outside the XUI deviceready block:
    // Accept the magneticHeading value
    // and convert into a text representation
    function convertToText(mh) {
        var textDirection;
        if (typeof mh !== "number") {
            textDirection = ''; 
        } else if (mh >= 337.5 || (mh >= 0 &&  mh <= 22.5)) {
            textDirection =  'N';
        } else if (mh >= 22.5 && mh <= 67.5) {
           textDirection =  'NE';
        } else if (mh >= 67.5 && mh <= 112.5) {
           textDirection =  'E';
        } else if (mh >= 112.5 && mh <= 157.5) {
           textDirection =  'SE';
        } else if (mh >= 157.5 && mh <= 202.5) {
           textDirection =  'S';
        } else if (mh >= 202.5 && mh <= 247.5) {
           textDirection =  'SW';
        } else if (mh >= 247.5 && mh <= 292.5) {
           textDirection =  'W';
        } else if (mh >= 292.5 && mh <= 337.5) {
           textDirection =  'NW';
        } else {
            textDirection =  textDirection;
        }
        return textDirection;
    }
  17. Now provide some CSS to position the two images on the screen and ensure the rose image is overlaying the compass image. Add a new <style> tag in <head> before the <title> tag:
    <style type="text/css">
        .container {
            position: relative;
            margin: 0 auto;
            width: 200px;
            overflow: hidden;
        }
    
        #heading {
            position: relative;
            font-size: 24px;
            font-weight: 200;
            text-shadow: 0 -1px 0 #eee;
            margin: 20px auto 20px auto;
            color: #111;
            text-align: center;
        }
        .compass {
            padding-top: 12px;
        }
        .rose {
            position: absolute;
            top: 53px;
            left: 40px;
            width: 120px;
            height: 121px;
        }
    </style>
    <title>Compass</title>
  18. Upon running the application on the device, the output will look something like this:
    How to do it…

How it works…

The watchHeading method from the PhoneGap API compass functionality retrieves periodic updates containing the current heading of the device at the interval specified as the value of the frequency variable passed through. If no interval is declared, a default value of 100 milliseconds (one-tenth of a second) is used.

With every successful request made on the continuous cycle, the onSuccess method is executed, and it formats the data for output onto the screen as well as making a change to the transform property of the graphical element to rotate in accordance with the heading.

The onSuccess method returns the obtained heading information in the form of the compassHeading object, which contains the following properties:

  • magneticHeading: This is a Number ranging from 0 to 359.99 that specifies a heading in degrees at a single moment in time.
  • trueHeading: This Number ranges from 0 to 359.99 and specifies the heading relative to the geographic North Pole in degrees.
  • headingAccuracy: This is a Number that indicates any deviation in degrees between the reported heading and the true heading values.
  • timestamp: This refers to the time in milliseconds at which the heading was determined.

See also

主站蜘蛛池模板: 十堰市| 长白| 明溪县| 高州市| 宜都市| 玛纳斯县| 南丹县| 当涂县| 永仁县| 买车| 巨野县| 徐闻县| 民丰县| 河西区| 沭阳县| 洞口县| 南昌县| 富阳市| 永城市| 广汉市| 沛县| 海林市| 吴川市| 滨州市| 西丰县| 宁波市| 克什克腾旗| 谷城县| 太和县| 普陀区| 临汾市| 旅游| 陕西省| 通江县| 惠水县| 朝阳市| 连山| 会同县| 桦南县| 景洪市| 高碑店市|