[OpenLayers-Commits] r12431 - in sandbox/marcjansen/hold: examples lib/OpenLayers/Handler

commits-20090109 at openlayers.org commits-20090109 at openlayers.org
Thu Oct 20 05:39:41 EDT 2011


Author: marcjansen
Date: 2011-10-20 02:39:40 -0700 (Thu, 20 Oct 2011)
New Revision: 12431

Added:
   sandbox/marcjansen/hold/examples/mobile-hold.html
   sandbox/marcjansen/hold/examples/mobile-hold.js
Modified:
   sandbox/marcjansen/hold/examples/OpenLayers.Control.Clickhold.js
   sandbox/marcjansen/hold/lib/OpenLayers/Handler/Click.js
Log:
[hold-sandbox] dedicated example and enhancements to handler / control

Modified: sandbox/marcjansen/hold/examples/OpenLayers.Control.Clickhold.js
===================================================================
--- sandbox/marcjansen/hold/examples/OpenLayers.Control.Clickhold.js	2011-10-07 08:55:34 UTC (rev 12430)
+++ sandbox/marcjansen/hold/examples/OpenLayers.Control.Clickhold.js	2011-10-20 09:39:40 UTC (rev 12431)
@@ -28,10 +28,10 @@
     defaultHandlerOptions: {
         hold: true,
         single: true,
-        'double': false,
+        'double': true,
         pixelTolerance: 5,
         stopSingle: false,
-        stopDouble: false
+        stopDouble: true
     },
     
     /**
@@ -51,47 +51,77 @@
         OpenLayers.Control.prototype.initialize.apply(this, arguments);
         this.handler = new OpenLayers.Handler.Click(this, {
             'click': this.onSimpleclick,
-            'clickhold': this.onClickhold
+            'clickhold': this.onClickhold,
+            'dblclick': this.onDblClick
         }, this.handlerOptions);
     },
     
     /**
-     * APIMethod: onSimpleclick
+     * Method: onSimpleclick
      * Method to be called when a simple click/tap (not held long enough) 
      * occurs? The method will be called with two arguments:
      * 
      * event - <OpenLayers.Event> The OpenLayers.Event object
      * ms    - {Number} The number of milliseconds that the click/tap lasted
-     * 
-     * TODO: maybe fire events instead.
      */
     onSimpleclick: function(evt, ms){
-        /*
-        evt.ms = ms;
+        var lonlat = this.map.getLonLatFromViewPortPx(evt.xy);
+        var evtExtended = {
+            ms: ms,
+            evt: evt,
+            lonlat: lonlat
+        };
         this.events.triggerEvent(
-            "click", evt
+            "click", evtExtended
         );
-        */
-        var lonlat = this.map.getLonLatFromViewPortPx(evt.xy);
-	    alert('Klick (nach ' + ms + ' MS) auf Koordinate:' + "\n" 
-	        + lonlat.lon.toFixed(1) + ', ' + lonlat.lat.toFixed(1));
     },
     
     /**
-     * APIMethod: onClickhold
+     * Method: onClickhold
      * Method to be called when a held click/tap occurs? The method will be 
      * called with two arguments:
      * 
      * event - <OpenLayers.Event> The OpenLayers.Event object
      * ms    - {Number} The number of milliseconds that the click/tap lasted
-     * 
-     * TODO: maybe fire events instead.
      */
     onClickhold: function(evt, ms){
         var lonlat = this.map.getLonLatFromViewPortPx(evt.xy);
-	    alert('Klickhold (nach ' + ms + ' MS) auf Koordinate:' + "\n" 
-	       + lonlat.lon.toFixed(1) + ', ' + lonlat.lat.toFixed(1));
+        var evtExtended = {
+            ms: ms,
+            evt: evt,
+            lonlat: lonlat
+        };
+        this.events.triggerEvent(
+            "clickhold", evtExtended
+        );
     },
     
+    onDblClick: function(evt, ms){
+        var lonlat = this.map.getLonLatFromViewPortPx(evt.xy);
+        var evtExtended = {
+            ms: ms,
+            evt: evt,
+            lonlat: lonlat
+        };
+        this.events.triggerEvent(
+            "dblclick", evtExtended
+        );
+    },
+    
+    /**
+     * 
+     *
+    onAfterClickhold: function(evt, ms){
+        var lonlat = this.map.getLonLatFromViewPortPx(evt.xy);
+        var evtExtended = {
+            ms: ms,
+            evt: evt,
+            lonlat: lonlat
+        };
+        this.events.triggerEvent(
+            "afterclickhold", evtExtended
+        );
+    },
+     */
     CLASS_NAME: "OpenLayers.Control.Clickhold"
 });
\ No newline at end of file

Added: sandbox/marcjansen/hold/examples/mobile-hold.html
===================================================================
--- sandbox/marcjansen/hold/examples/mobile-hold.html	                        (rev 0)
+++ sandbox/marcjansen/hold/examples/mobile-hold.html	2011-10-20 09:39:40 UTC (rev 12431)
@@ -0,0 +1,124 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>OpenLayers Mobile</title>
+        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
+        <meta name="apple-mobile-web-app-capable" content="yes">
+        <link rel="stylesheet" href="style.css" type="text/css">
+        <link rel="stylesheet" href="style.mobile.css" type="text/css">
+        <script src="../lib/OpenLayers.js?mobile"></script>
+        <script src="./OpenLayers.Control.Clickhold.js"></script>
+        <script src="mobile-hold.js"></script>
+        <style>
+            html, body {
+                margin  : 0;
+                padding : 0;
+                height  : 100%;
+                width   : 100%;
+            }
+            @media only screen and (max-width: 600px) {
+                html, body {
+                    height  : 117%;
+                }
+            }
+            #map {
+                margin   : 0;
+                padding  : 0;
+                width    : 100%;
+                position : relative;
+                height   : 250px;
+            }
+            .olControlAttribution {
+                position      : absolute;
+                font-size     : 10px;
+                bottom        : 0 !important;
+                right         : 0 !important;
+                background    : rgba(0,0,0,0.1);
+                font-family   : Arial;
+                padding       : 2px 4px;
+                border-radius : 5px 0 0 0;
+            }
+            div.olControlZoomPanel .olControlZoomInItemInactive,
+            div.olControlZoomPanel .olControlZoomOutItemInactive {
+                background: rgba(0,0,0,0.2);
+                position: absolute;
+            }
+            div.olControlZoomPanel .olControlZoomInItemInactive {
+                border-radius: 5px 5px 0 0;
+            }
+            div.olControlZoomPanel .olControlZoomOutItemInactive {
+                border-radius: 0 0 5px 5px ;
+                top: 37px;
+            }
+            div.olControlZoomPanel .olControlZoomOutItemInactive:after ,
+            div.olControlZoomPanel .olControlZoomInItemInactive:after{
+                font-weight: bold;
+                content   : '+';
+                font-size : 36px;
+                padding:  7px;
+                z-index: 2000;
+                color     : #fff;
+                line-height: 1em;
+            }
+            div.olControlZoomPanel .olControlZoomOutItemInactive:after{
+                content: '–';
+                line-height: 0.9em;
+                padding: 0 8px;
+            }
+            div.olControlZoomPanel .olControlZoomToMaxExtentItemInactive {
+                display: none;
+            }
+            #title, #tags, #shortdesc {
+                display: none;
+            }
+        </style>
+    </head>
+    <body>
+        <h1 id="title">Mobile Example with hold support</h1>
+        <div id="tags">
+            mobile hold clickhold taphold
+        </div>
+        <p id="shortdesc">
+            A mobile map which shows how to handle hold-events.
+        </p>
+        <div id="map"></div>
+        <div id="description">
+            <p>
+                This map shows how one can interact with taps the user places on
+                the map.
+            </p>
+            <p>
+                You can zoom in and out (through the plus and minus button), 
+                pan and pinch the above map, but in addition, when...</p>
+            <ul>
+                <li>
+                    ...the map is tapped on shortly, a red point is drawn at the
+                    tapped location,
+                </li>
+                <li>
+                    ...the map is tapped on for a longer time (~ 800 
+                    milliseconds, e.g. a taphold), a orange point is drawn at 
+                    the tapped location,
+                </li>
+                <li>
+                    ...the map is double-tapped, a purple point is drawn at the
+                    tapped location. 
+                </li>
+            </ul>
+            <p>
+                This is accomplished though a custom 
+                <a href="./OpenLayers.Control.Clickhold.js">Clickhold-control</a>,
+                that uses 'click', 'clickhold' and 'dblclick'-functionality of the
+                Click-handler. 
+            </p>
+            <p>
+                See the file <a href="./mobile-hold.js">mobile-hold.js</a> too 
+                see how to use the custom control.
+            </p>
+        </div>
+        <script>
+            init();
+        </script>
+    </body>
+</html>

Added: sandbox/marcjansen/hold/examples/mobile-hold.js
===================================================================
--- sandbox/marcjansen/hold/examples/mobile-hold.js	                        (rev 0)
+++ sandbox/marcjansen/hold/examples/mobile-hold.js	2011-10-20 09:39:40 UTC (rev 12431)
@@ -0,0 +1,84 @@
+// initialize map when page ready
+var map;
+
+// Get rid of address bar on iphone/ipod
+var fixSize = function() {
+    window.scrollTo(0,0);
+    document.body.style.height = '100%';
+    if (!(/(iphone|ipod)/.test(navigator.userAgent.toLowerCase()))) {
+        if (document.body.parentNode) {
+            document.body.parentNode.style.height = '100%';
+        }
+    }
+};
+setTimeout(fixSize, 700);
+setTimeout(fixSize, 1500);
+
+var init = function () {
+    var clickholdCtrl = new OpenLayers.Control.Clickhold({
+    	autoActivate: true
+    });
+    
+    clickholdCtrl.events.register('click', {}, function(evt) {
+        drawPoint(evt.lonlat, 'red', 'tap' /* + "\n" + evt.ms + " ms" */);
+    });
+    clickholdCtrl.events.register('clickhold', {}, function(evt) {
+        drawPoint(evt.lonlat, 'darkorange', 'taphold' /* + "\n" + evt.ms + " ms" */);
+    });
+    clickholdCtrl.events.register('dblclick', {}, function(evt) {
+        drawPoint(evt.lonlat, 'purple', 'dbltap' /* + "\n" + evt.ms + " ms" */);
+    });
+    
+    //clickholdCtrl.events.register('afterclickhold', {}, function(evt) {
+    //    console.log('afterclickhold', evt);
+    //});
+    
+    // create map
+    map = new OpenLayers.Map({ 
+        div: "map",
+        theme: null,
+        controls: [
+            new OpenLayers.Control.Attribution(),
+            new OpenLayers.Control.TouchNavigation({
+                dragPanOptions: {
+                    enableKinetic: true
+                }
+            }),
+            new OpenLayers.Control.ZoomPanel(),
+            clickholdCtrl
+        ],
+        layers: [
+            new OpenLayers.Layer.OSM("OpenStreetMap", null, {
+                transitionEffect: 'resize'
+            }),
+            new OpenLayers.Layer.Vector()
+        ],
+        center: new OpenLayers.LonLat(742000, 5861000),
+        zoom: 3
+    });
+};
+
+
+var drawPoint = function(lonlat, color, label) {
+    var layer = map.layers[map.layers.length-1],
+        geom = new OpenLayers.Geometry.Point(lonlat.lon, lonlat.lat);
+        attr = {},
+        style = {
+            fillColor: color,
+            fillOpacity: 0.65,
+            strokeColor: color,
+            strokeOpacity: 1,
+            strokeWidth: 2,
+            pointRadius: 10,
+            label: label,
+            labelAlign: 'cb',
+            labelXOffset: 0,
+            labelYOffset: -36,
+            fontColor: color,
+            fontSize: '13px',
+            fontFamily: 'Arial, sans-serif',
+            fontWeight: 'bold'
+        },
+        feature = new OpenLayers.Feature.Vector(geom, attr, style);
+    layer.addFeatures( [ feature ] );
+};

Modified: sandbox/marcjansen/hold/lib/OpenLayers/Handler/Click.js
===================================================================
--- sandbox/marcjansen/hold/lib/OpenLayers/Handler/Click.js	2011-10-07 08:55:34 UTC (rev 12430)
+++ sandbox/marcjansen/hold/lib/OpenLayers/Handler/Click.js	2011-10-20 09:39:40 UTC (rev 12431)
@@ -42,9 +42,9 @@
      * APIProperty: holdThreshold
      * 
      * The amount of milliseconds that need to pass for a click/tap to be 
-     * considered a hold. Defaults to 1000 milliseconds. 
+     * considered a hold. Defaults to 800 milliseconds. 
      */
-    holdThreshold: 1000,
+    holdThreshold: 800,
     
     /**
      * APIProperty: hold
@@ -180,6 +180,7 @@
     touchstart: function(evt) {
         if (this.hold) {
         	this.startedAt = this.getTimestamp();
+        	// this.bindHoldTimeout(evt);
         }
         if (!this.touch) {
             this.unregisterMouseListeners();
@@ -246,6 +247,7 @@
     mousedown: function(evt) {
     	if (this.hold) {
         	this.startedAt = this.getTimestamp();
+        	// this.bindHoldTimeout(evt);
         }
         this.down = this.getEventInfo(evt);
         this.last = this.getEventInfo(evt);
@@ -361,7 +363,11 @@
      */
     handleDouble: function(evt) {
         if (this["double"] && this.passesDblclickTolerance(evt)) {
-            this.callback("dblclick", [evt]);
+            var now, 
+                elapsedTime;
+                now = this.getTimestamp();
+                elapsedTime = now - this.startedAt;
+            this.callback("dblclick", [evt, elapsedTime]);
         }
     },
     
@@ -480,6 +486,7 @@
      * Clear the timer and set <timerId> to null.
      */
     clearTimer: function() {
+        // this.unbindHoldTimeout();
         if (this.timerId != null) {
             window.clearTimeout(this.timerId);
             this.timerId = null;
@@ -497,15 +504,15 @@
      */
     delayedCall: function(evt) {
         this.timerId = null;
+        // this.unbindHoldTimeout();
         if (evt) {
         	if (!this.hold) {
             	this.callback("click", [evt]);
         	} else {
-        		var now, elapsedTime;
+        		var now, 
+        		    elapsedTime;
         		now = this.getTimestamp();
-            
 	            elapsedTime = now - this.startedAt - this.delay;
-	                
 	            this.startedAt = null;
 	            if (elapsedTime > this.holdThreshold ) {
 	                this.callback("clickhold", [evt, elapsedTime]);
@@ -517,6 +524,48 @@
     },
     
     /**
+     * Method: bindHoldTimeout
+     * Creates an anonymous function that will execute after holdThreshold 
+     *     milliseconds and which eventually WILL call the defined "clickhold" 
+     *     callback.
+     *
+    bindHoldTimeout: function(evt) {
+        var me = this,
+            msTimeout = me.holdThreshold;
+        me.unbindHoldTimeout();
+        
+        var timeoutFunc = OpenLayers.Function.bind(
+            function(){
+                var self = this,
+                    now, 
+                    elapsedTime;
+                now = self.getTimestamp();
+                elapsedTime = now - self.startedAt;
+                    
+                self.callback("clickhold", [evt, elapsedTime]);
+            },
+            me
+        );
+        me.holdTimeout = window.setTimeout(timeoutFunc, msTimeout);
+    },
+     */
+    
+    /**
+     * Method: unbindHoldTimeout
+     * clears the holdcallback set in bindHoldTimeout. This has to happen, when
+     *     the handler is configured to handle click and hold, but a click
+     *     was captured. If we didn't clear the timeout, the clickhold event 
+     *     always fire.
+     *
+    unbindHoldTimeout: function() {
+        if (this.hold && this.holdTimeout) {
+            window.clearTimeout(this.holdTimeout);
+            this.holdTimeout = null;
+        }
+    },
+     */
+    
+    /**
      * Method: getTimestamp
      * 
      * Gets the current timestamp in milliseconds.



More information about the Commits mailing list