diff --git a/src/MarkerCluster.js b/src/MarkerCluster.js index c2e5f101d..551532967 100644 --- a/src/MarkerCluster.js +++ b/src/MarkerCluster.js @@ -77,43 +77,45 @@ L.MarkerCluster = L.Marker.extend({ }, //layer: The layer to try add + //returns: + // true: was able to put this marker in, but don't know its current visible parents position + // false: wasn't able to put this marker in + // a Marker/MarkerCluster: the visible parent of the marker (or the marker itself if it should be visible) _recursivelyAddLayer: function (layer, zoom) { - var childReturn = null, - added = false; + var result = false; if (!this._haveGeneratedChildClusters && this._canAcceptPosition(layer.getLatLng(), zoom)) { //Don't need to cluster it in as we haven't clustered this._addChild(layer); - added = true; + result = true; } else { for (var i = this._childClusters.length - 1; i >= 0; i--) { var c = this._childClusters[i]; //Recurse into children where their bounds fits the layer or they can just take it if (c._bounds.contains(layer.getLatLng()) || c._canAcceptPosition(layer.getLatLng(), zoom + 1)) { - childReturn = c._recursivelyAddLayer(layer, zoom + 1); - if (childReturn !== false) { - added = true; + result = c._recursivelyAddLayer(layer, zoom + 1); + if (result) { break; } } } - //Couldn't add it to a child, but it should be part of us - if (!added && this._canAcceptPosition(layer.getLatLng(), zoom)) { + //Couldn't add it to a child, but it should be part of us (this._zoom -> we are the root node) + if (!result && (this._canAcceptPosition(layer.getLatLng(), zoom) || this._zoom)) { //Add to ourself instead - var newCluster = this._group._clusterOne(this._markers, layer, zoom); - if (newCluster && newCluster._markers[0]._icon) { - //Remove children and add cluster - newCluster._recursivelyRemoveChildrenFromMap(newCluster._bounds, 0); - newCluster._addToMap(); - } - this._addChild(newCluster || layer); + result = this._group._clusterOne(this._markers, layer, zoom); - added = true; + if (result) { + result._baseInit(); + this._addChild(result); + } else { + this._addChild(layer); + result = true; + } } - if (added) { + if (result) { this._childCount++; if (this._icon) { this.setIcon(this._group.options.iconCreateFunction(this._childCount)); @@ -121,16 +123,15 @@ L.MarkerCluster = L.Marker.extend({ } } - if (!added) { - if (this._zoom) { //Means we are the root node, we get it anyway - this._addChild(layer); + if (result === true) { + if (this._icon) { + result = this; + } else if ((this._markers.length > 0 && this._markers[0]._icon) || (this._childClusters.length > 1 && this._childClusters[0]._icon)) { + result = layer; } - console.log('not added'); - return false; - } else { - console.log('added ' + (this._icon ? this._latlng : childReturn)); - return this._icon ? this._latlng : childReturn; } + + return result; }, _canAcceptPosition: function (latlng, zoom) { diff --git a/src/MarkerClusterGroup.js b/src/MarkerClusterGroup.js index 8260595bf..ca4cf4302 100644 --- a/src/MarkerClusterGroup.js +++ b/src/MarkerClusterGroup.js @@ -130,33 +130,41 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({ } var me = this, - position; + newCluster; //If we have already clustered we'll need to add this one to a cluster - L.FeatureGroup.prototype.addLayer.call(this, layer); //TODO: If not animated maybe don't add it yet - position = this._topClusterLevel._recursivelyAddLayer(layer, this._topClusterLevel._zoom); + newCluster = this._topClusterLevel._recursivelyAddLayer(layer, this._topClusterLevel._zoom); - if (position) { - //TODO Tidy up - //this._animateSingleMarkerIn(layer, position); - setTimeout(function () { - me._animationStart.call(me); - - var backupLatlng = layer.getLatLng(); - - layer.setLatLng(position); + //TODO: This is the animated version + L.FeatureGroup.prototype.addLayer.call(this, layer); + if (newCluster != layer) { + if (newCluster._childCount > 2) { //Was already a cluster setTimeout(function () { - L.FeatureGroup.prototype.removeLayer.call(me, layer); - layer.setLatLng(backupLatlng); - //HACKS - map._mapPane.className = map._mapPane.className.replace(' leaflet-cluster-anim', ''); me._inZoomAnimation--; - }, 250); - }, 0); - } else { - //Do nothing, marker should be shown on map at own position at this level + me._animationStart.call(me); + + var backupLatlng = layer.getLatLng(); + layer.setLatLng(newCluster._latlng); + layer.setOpacity(0); + + setTimeout(function () { + L.FeatureGroup.prototype.removeLayer.call(me, layer); + layer.setLatLng(backupLatlng); + + //HACKS + map._mapPane.className = map._mapPane.className.replace(' leaflet-cluster-anim', ''); me._inZoomAnimation--; + }, 250); + }, 0); + + } else { //Just became a cluster + setTimeout(function () { + me._animationStart(); + me._animationZoomOutSingle(newCluster, 0, 1); + }, 0); + //newCluster._recursivelyAnimateChildrenInAndAddSelfToMap(newCluster._bounds, 0, 1); + } } return this; @@ -379,16 +387,21 @@ L.MarkerClusterGroup.include(!L.DomUtil.TRANSITION ? { me._inZoomAnimation--; }, 250); }, + _animationZoomOut: function (previousZoomLevel, newZoomLevel) { - var map = this._map, - bounds = this._getExpandedVisibleBounds(), - depthToStartAt = 1 + newZoomLevel - this._topClusterLevel._zoom, + var depthToStartAt = 1 + newZoomLevel - this._topClusterLevel._zoom, depthToAnimateIn = previousZoomLevel - newZoomLevel; + this._animationZoomOutSingle(this._topClusterLevel, depthToStartAt, depthToAnimateIn); + }, + _animationZoomOutSingle: function (marker, depthToStartAt, depthToAnimateIn) { + var map = this._map, + bounds = this._getExpandedVisibleBounds(); + console.log('animationZoomOut ' + depthToStartAt + ' ' + depthToAnimateIn); //Animate all of the markers in the clusters to move to their cluster center point - this._topClusterLevel._recursivelyAnimateChildrenInAndAddSelfToMap(bounds, depthToStartAt, depthToAnimateIn); + marker._recursivelyAnimateChildrenInAndAddSelfToMap(bounds, depthToStartAt, depthToAnimateIn); this._inZoomAnimation++; @@ -396,7 +409,7 @@ L.MarkerClusterGroup.include(!L.DomUtil.TRANSITION ? { //Immediately fire an event to update the opacity (If we immediately set it they won't animate) setTimeout(function () { - me._topClusterLevel._recursivelyBecomeVisible(bounds, depthToStartAt); + marker._recursivelyBecomeVisible(bounds, depthToStartAt); }, 0); //TODO: Maybe use the transition timing stuff to make this more reliable @@ -404,7 +417,7 @@ L.MarkerClusterGroup.include(!L.DomUtil.TRANSITION ? { setTimeout(function () { map._mapPane.className = map._mapPane.className.replace(' leaflet-cluster-anim', ''); - me._topClusterLevel._recursively(bounds, depthToStartAt, 0, null, function (c) { + marker._recursively(bounds, depthToStartAt, 0, null, function (c) { c._recursivelyRemoveChildrenFromMap(bounds, depthToAnimateIn - 1); }); me._inZoomAnimation--;