From 2420ad56c10763144bbc30ceee511e31ace250bb Mon Sep 17 00:00:00 2001 From: Thomas Chandelle Date: Thu, 3 Nov 2016 13:10:24 +0100 Subject: [PATCH 1/3] If there is no features option, all features will be translated. --- src/ol/interaction/translate.js | 45 +++++++++++++++------------------ 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/src/ol/interaction/translate.js b/src/ol/interaction/translate.js index 555c65432c..c761f81ec8 100644 --- a/src/ol/interaction/translate.js +++ b/src/ol/interaction/translate.js @@ -1,6 +1,7 @@ goog.provide('ol.interaction.Translate'); goog.require('ol'); +goog.require('ol.Collection'); goog.require('ol.events.Event'); goog.require('ol.functions'); goog.require('ol.array'); @@ -88,9 +89,12 @@ ol.interaction.Translate.handleDownEvent_ = function(event) { if (!this.lastCoordinate_ && this.lastFeature_) { this.lastCoordinate_ = event.coordinate; ol.interaction.Translate.handleMoveEvent_.call(this, event); + + var features = this.features_ || new ol.Collection([this.lastFeature_]); + this.dispatchEvent( new ol.interaction.Translate.Event( - ol.interaction.Translate.EventType.TRANSLATESTART, this.features_, + ol.interaction.Translate.EventType.TRANSLATESTART, features, event.coordinate)); return true; } @@ -108,9 +112,12 @@ ol.interaction.Translate.handleUpEvent_ = function(event) { if (this.lastCoordinate_) { this.lastCoordinate_ = null; ol.interaction.Translate.handleMoveEvent_.call(this, event); + + var features = this.features_ || new ol.Collection([this.lastFeature_]); + this.dispatchEvent( new ol.interaction.Translate.Event( - ol.interaction.Translate.EventType.TRANSLATEEND, this.features_, + ol.interaction.Translate.EventType.TRANSLATEEND, features, event.coordinate)); return true; } @@ -129,22 +136,18 @@ ol.interaction.Translate.handleDragEvent_ = function(event) { var deltaX = newCoordinate[0] - this.lastCoordinate_[0]; var deltaY = newCoordinate[1] - this.lastCoordinate_[1]; - if (this.features_) { - this.features_.forEach(function(feature) { - var geom = feature.getGeometry(); - geom.translate(deltaX, deltaY); - feature.setGeometry(geom); - }); - } else if (this.lastFeature_) { - var geom = this.lastFeature_.getGeometry(); + var features = this.features_ || new ol.Collection([this.lastFeature_]); + + features.forEach(function(feature) { + var geom = feature.getGeometry(); geom.translate(deltaX, deltaY); - this.lastFeature_.setGeometry(geom); - } + feature.setGeometry(geom); + }); this.lastCoordinate_ = newCoordinate; this.dispatchEvent( new ol.interaction.Translate.Event( - ol.interaction.Translate.EventType.TRANSLATING, this.features_, + ol.interaction.Translate.EventType.TRANSLATING, features, newCoordinate)); } }; @@ -187,19 +190,13 @@ ol.interaction.Translate.handleMoveEvent_ = function(event) { * @private */ ol.interaction.Translate.prototype.featuresAtPixel_ = function(pixel, map) { - var found = null; - - var intersectingFeature = map.forEachFeatureAtPixel(pixel, + return map.forEachFeatureAtPixel(pixel, function(feature) { - return feature; + if (!this.features_ || + ol.array.includes(this.features_.getArray(), feature)) { + return feature; + } }, this, this.layerFilter_); - - if (this.features_ && - ol.array.includes(this.features_.getArray(), intersectingFeature)) { - found = intersectingFeature; - } - - return found; }; From 60e352fa0994de237a3a3b5b69473c729f919400 Mon Sep 17 00:00:00 2001 From: Thomas Chandelle Date: Wed, 9 Nov 2016 13:54:10 +0100 Subject: [PATCH 2/3] Make Translate options optional --- src/ol/interaction/translate.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ol/interaction/translate.js b/src/ol/interaction/translate.js index c761f81ec8..3b61e333dc 100644 --- a/src/ol/interaction/translate.js +++ b/src/ol/interaction/translate.js @@ -15,10 +15,10 @@ goog.require('ol.interaction.Pointer'); * @constructor * @extends {ol.interaction.Pointer} * @fires ol.interaction.Translate.Event - * @param {olx.interaction.TranslateOptions} options Options. + * @param {olx.interaction.TranslateOptions=} opt_options Options. * @api */ -ol.interaction.Translate = function(options) { +ol.interaction.Translate = function(opt_options) { ol.interaction.Pointer.call(this, { handleDownEvent: ol.interaction.Translate.handleDownEvent_, handleDragEvent: ol.interaction.Translate.handleDragEvent_, @@ -26,6 +26,7 @@ ol.interaction.Translate = function(options) { handleUpEvent: ol.interaction.Translate.handleUpEvent_ }); + var options = opt_options ? opt_options : {}; /** * @type {string|undefined} From 5d214567abbe1e98c108091a9d910291e1c52a98 Mon Sep 17 00:00:00 2001 From: Thomas Chandelle Date: Wed, 9 Nov 2016 14:07:11 +0100 Subject: [PATCH 3/3] Add test for Translate interaction, without features option --- test/spec/ol/interaction/translate.test.js | 98 ++++++++++++++++++++-- 1 file changed, 91 insertions(+), 7 deletions(-) diff --git a/test/spec/ol/interaction/translate.test.js b/test/spec/ol/interaction/translate.test.js index 2d6e3971de..e167f3afd5 100644 --- a/test/spec/ol/interaction/translate.test.js +++ b/test/spec/ol/interaction/translate.test.js @@ -77,29 +77,85 @@ describe('ol.interaction.Translate', function() { map.handleMapBrowserEvent(event); } + /** + * Tracks events triggered by the interaction as well as feature + * modifications. Helper function to + * @param {ol.Feature} feature Translated feature. + * @param {ol.interaction.Translate} interaction The interaction. + * @return {Array} events + */ + function trackEvents(feature, interaction) { + var events = []; + feature.on('change', function(event) { + events.push('change'); + }); + interaction.on('translatestart', function(event) { + events.push(event); + }); + interaction.on('translateend', function(event) { + events.push(event); + }); + return events; + } + + /** + * Validates the event array to verify proper event sequence. Checks + * that first and last event are correct TranslateEvents and that feature + * modifications event are in between. + * @param {Array} events The events. + * @param {Array} features The features. + */ + function validateEvents(events, features) { + + var startevent = events[0]; + var endevent = events[events.length - 1]; + + // first event should be translatestart + expect(startevent).to.be.an(ol.interaction.Translate.Event); + expect(startevent.type).to.eql('translatestart'); + + // last event should be translateend + expect(endevent).to.be.an(ol.interaction.Translate.Event); + expect(endevent.type).to.eql('translateend'); + + // make sure we get change events to events array + expect(events.length > 2).to.be(true); + // middle events should be feature modification events + for (var i = 1; i < events.length - 1; i++) { + expect(events[i]).to.equal('change'); + } + + // TranslateEvents should include the expected features + expect(startevent.features.getArray()).to.eql(features); + expect(endevent.features.getArray()).to.eql(features); + } + + describe('constructor', function() { it('creates a new interaction', function() { - var draw = new ol.interaction.Translate({ + var translate = new ol.interaction.Translate({ features: features }); - expect(draw).to.be.a(ol.interaction.Translate); - expect(draw).to.be.a(ol.interaction.Interaction); + expect(translate).to.be.a(ol.interaction.Translate); + expect(translate).to.be.a(ol.interaction.Interaction); }); }); - describe('moving features', function() { - var draw; + describe('moving features, with features option', function() { + var translate; beforeEach(function() { - draw = new ol.interaction.Translate({ + translate = new ol.interaction.Translate({ features: new ol.Collection([features[0]]) }); - map.addInteraction(draw); + map.addInteraction(translate); }); it('moves a selected feature', function() { + var events = trackEvents(features[0], translate); + simulateEvent('pointermove', 10, 20); simulateEvent('pointerdown', 10, 20); simulateEvent('pointerdrag', 50, -40); @@ -107,9 +163,13 @@ describe('ol.interaction.Translate', function() { var geometry = features[0].getGeometry(); expect(geometry).to.be.a(ol.geom.Point); expect(geometry.getCoordinates()).to.eql([50, 40]); + + validateEvents(events, [features[0]]); }); it('does not move an unselected feature', function() { + var events = trackEvents(features[0], translate); + simulateEvent('pointermove', 20, 30); simulateEvent('pointerdown', 20, 30); simulateEvent('pointerdrag', 50, -40); @@ -117,6 +177,30 @@ describe('ol.interaction.Translate', function() { var geometry = features[1].getGeometry(); expect(geometry).to.be.a(ol.geom.Point); expect(geometry.getCoordinates()).to.eql([20, -30]); + + expect(events).to.be.empty(); + }); + }); + + describe('moving features, without features option', function() { + var translate; + + beforeEach(function() { + translate = new ol.interaction.Translate(); + map.addInteraction(translate); + }); + + it('moves only targeted feature', function() { + var events = trackEvents(features[0], translate); + + simulateEvent('pointermove', 10, 20); + simulateEvent('pointerdown', 10, 20); + simulateEvent('pointerdrag', 50, -40); + simulateEvent('pointerup', 50, -40); + expect(features[0].getGeometry().getCoordinates()).to.eql([50, 40]); + expect(features[1].getGeometry().getCoordinates()).to.eql([20, -30]); + + validateEvents(events, [features[0]]); }); }); });