From 33cf4e6179222c6a2a644949e6516bfbca5f443a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Lemoine?= Date: Mon, 15 Dec 2014 17:31:41 +0100 Subject: [PATCH] Add a drag-feature example This example also demonstrates how to implement a custom interaction that inherits from ol.interaction.Pointer. --- examples/drag-features.html | 51 ++++++++++ examples/drag-features.js | 192 ++++++++++++++++++++++++++++++++++++ 2 files changed, 243 insertions(+) create mode 100644 examples/drag-features.html create mode 100644 examples/drag-features.js diff --git a/examples/drag-features.html b/examples/drag-features.html new file mode 100644 index 0000000000..109afa0074 --- /dev/null +++ b/examples/drag-features.html @@ -0,0 +1,51 @@ + + + + + + + + + + + Drag features example + + + + + +
+ +
+
+
+
+
+ +
+ +
+

Drag features example

+

Example of a drag features interaction.

+
+

See the drag-features.js source to see how this is done.

+
+
drag, feature, vector, editing
+
+ +
+ +
+ + + + + + + diff --git a/examples/drag-features.js b/examples/drag-features.js new file mode 100644 index 0000000000..faff5ae42b --- /dev/null +++ b/examples/drag-features.js @@ -0,0 +1,192 @@ +goog.require('ol.Feature'); +goog.require('ol.Map'); +goog.require('ol.View'); +goog.require('ol.geom.LineString'); +goog.require('ol.geom.Point'); +goog.require('ol.geom.Polygon'); +goog.require('ol.interaction'); +goog.require('ol.interaction.Pointer'); +goog.require('ol.layer.Tile'); +goog.require('ol.layer.Vector'); +goog.require('ol.source.TileJSON'); +goog.require('ol.source.Vector'); +goog.require('ol.style.Fill'); +goog.require('ol.style.Icon'); +goog.require('ol.style.Stroke'); +goog.require('ol.style.Style'); + + +/** + * Define a namespace for the application. + */ +window.app = {}; +var app = window.app; + + + +/** + * @constructor + * @extends {ol.interaction.Pointer} + */ +app.Drag = function() { + + ol.interaction.Pointer.call(this, { + handleDownEvent: app.Drag.prototype.handleDownEvent, + handleDragEvent: app.Drag.prototype.handleDragEvent, + handleMoveEvent: app.Drag.prototype.handleMoveEvent, + handleUpEvent: app.Drag.prototype.handleUpEvent + }); + + /** + * @type {ol.Pixel} + * @private + */ + this.coordinate_ = null; + + /** + * @type {string|undefined} + * @private + */ + this.cursor_ = 'pointer'; + + /** + * @type {ol.Feature} + * @private + */ + this.feature_ = null; + + /** + * @type {string|undefined} + * @private + */ + this.previousCursor_ = undefined; + +}; +ol.inherits(app.Drag, ol.interaction.Pointer); + + +/** + * @param {ol.MapBrowserEvent} evt Map browser event. + * @return {boolean} `true` to start the drag sequence. + */ +app.Drag.prototype.handleDownEvent = function(evt) { + var map = evt.map; + + var feature = map.forEachFeatureAtPixel(evt.pixel, + function(feature, layer) { + return feature; + }); + + if (feature) { + this.coordinate_ = evt.coordinate; + this.feature_ = feature; + } + + return !!feature; +}; + + +/** + * @param {ol.MapBrowserEvent} evt Map browser event. + */ +app.Drag.prototype.handleDragEvent = function(evt) { + var map = evt.map; + + var feature = map.forEachFeatureAtPixel(evt.pixel, + function(feature, layer) { + return feature; + }); + + var deltaX = evt.coordinate[0] - this.coordinate_[0]; + var deltaY = evt.coordinate[1] - this.coordinate_[1]; + + var geometry = /** @type {ol.geom.SimpleGeometry} */ + (this.feature_.getGeometry()); + geometry.translate(deltaX, deltaY); + + this.coordinate_[0] = evt.coordinate[0]; + this.coordinate_[1] = evt.coordinate[1]; +}; + + +/** + * @param {ol.MapBrowserEvent} evt Event. + */ +app.Drag.prototype.handleMoveEvent = function(evt) { + if (this.cursor_) { + var map = evt.map; + var feature = map.forEachFeatureAtPixel(evt.pixel, + function(feature, layer) { + return feature; + }); + var element = evt.map.getTargetElement(); + if (feature) { + if (element.style.cursor != this.cursor_) { + this.previousCursor_ = element.style.cursor; + element.style.cursor = this.cursor_; + } + } else if (this.previousCursor_ !== undefined) { + element.style.cursor = this.previousCursor_; + this.previousCursor_ = undefined; + } + } +}; + + +/** + * @param {ol.MapBrowserEvent} evt Map browser event. + * @return {boolean} `false` to stop the drag sequence. + */ +app.Drag.prototype.handleUpEvent = function(evt) { + this.coordinate_ = null; + this.feature_ = null; + return false; +}; + + +var pointFeature = new ol.Feature(new ol.geom.Point([0, 0])); + +var lineFeature = new ol.Feature( + new ol.geom.LineString([[-1e7, 1e6], [-1e6, 3e6]])); + +var polygonFeature = new ol.Feature( + new ol.geom.Polygon([[[-3e6, -1e6], [-3e6, 1e6], + [-1e6, 1e6], [-1e6, -1e6], [-3e6, -1e6]]])); + + +var map = new ol.Map({ + interactions: ol.interaction.defaults().extend([new app.Drag()]), + layers: [ + new ol.layer.Tile({ + source: new ol.source.TileJSON({ + url: 'http://api.tiles.mapbox.com/v3/mapbox.geography-class.jsonp' + }) + }), + new ol.layer.Vector({ + source: new ol.source.Vector({ + features: [pointFeature, lineFeature, polygonFeature] + }), + style: new ol.style.Style({ + image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({ + anchor: [0.5, 46], + anchorXUnits: 'fraction', + anchorYUnits: 'pixels', + opacity: 0.95, + src: 'data/icon.png' + })), + stroke: new ol.style.Stroke({ + width: 3, + color: [255, 0, 0, 1] + }), + fill: new ol.style.Fill({ + color: [0, 0, 255, 0.6] + }) + }) + }) + ], + target: 'map', + view: new ol.View({ + center: [0, 0], + zoom: 2 + }) +});