Replace setTimeout(..., 0) calls with explicit forceLayout calls, tidier code.

This commit is contained in:
danzel
2012-07-25 14:03:23 +12:00
parent fbd46fd2b8
commit 7537fb0986
2 changed files with 105 additions and 102 deletions
+63 -65
View File
@@ -143,78 +143,76 @@ L.MarkerCluster.include(!L.DomUtil.TRANSITION ? {
L.FeatureGroup.prototype.addLayer.call(group, m);
}
setTimeout(function () {
group._animationStart();
this._group._forceLayout();
group._animationStart();
var initialLegOpacity = L.Browser.svg ? 0 : 0.3,
xmlns = L.Path.SVG_NS;
var initialLegOpacity = L.Browser.svg ? 0 : 0.3,
xmlns = L.Path.SVG_NS;
for (i = childMarkers.length - 1; i >= 0; i--) {
m = childMarkers[i];
m.setLatLng(map.layerPointToLatLng(positions[i]));
m.setOpacity(1);
//Add Legs. TODO: Fade this in!
leg = new L.Polyline([me._latlng, m._latlng], { weight: 1.5, color: '#222', opacity: initialLegOpacity });
map.addLayer(leg);
m._spiderLeg = leg;
//Following animations don't work for canvas
if (!L.Browser.svg) {
continue;
}
//How this works:
//http://stackoverflow.com/questions/5924238/how-do-you-animate-an-svg-path-in-ios
//http://dev.opera.com/articles/view/advanced-svg-animation-techniques/
//Animate length
var length = leg._path.getTotalLength();
leg._path.setAttribute("stroke-dasharray", length + "," + length);
var anim = document.createElementNS(xmlns, "animate");
anim.setAttribute("attributeName", "stroke-dashoffset");
anim.setAttribute("begin", "indefinite");
anim.setAttribute("from", length);
anim.setAttribute("to", 0);
anim.setAttribute("dur", 0.25);
leg._path.appendChild(anim);
anim.beginElement();
//Animate opacity
anim = document.createElementNS(xmlns, "animate");
anim.setAttribute("attributeName", "stroke-opacity");
anim.setAttribute("attributeName", "stroke-opacity");
anim.setAttribute("begin", "indefinite");
anim.setAttribute("from", 0);
anim.setAttribute("to", 0.5);
anim.setAttribute("dur", 0.25);
leg._path.appendChild(anim);
anim.beginElement();
}
me.setOpacity(0.3);
//Set the opacity of the spiderLegs back to their correct value
// The animations above override this until they complete.
// If the initial opacity of the spiderlegs isn't 0 then they appear before the animation starts.
if (L.Browser.svg) {
this._group._forceLayout();
for (i = childMarkers.length - 1; i >= 0; i--) {
m = childMarkers[i];
m = childMarkers[i]._spiderLeg;
m.setLatLng(map.layerPointToLatLng(positions[i]));
m.setOpacity(1);
//Add Legs. TODO: Fade this in!
leg = new L.Polyline([me._latlng, m._latlng], { weight: 1.5, color: '#222', opacity: initialLegOpacity });
map.addLayer(leg);
m._spiderLeg = leg;
//Following animations don't work for canvas
if (!L.Browser.svg) {
continue;
}
//How this works:
//http://stackoverflow.com/questions/5924238/how-do-you-animate-an-svg-path-in-ios
//http://dev.opera.com/articles/view/advanced-svg-animation-techniques/
//Animate length
var length = leg._path.getTotalLength();
leg._path.setAttribute("stroke-dasharray", length + "," + length);
var anim = document.createElementNS(xmlns, "animate");
anim.setAttribute("attributeName", "stroke-dashoffset");
anim.setAttribute("begin", "indefinite");
anim.setAttribute("from", length);
anim.setAttribute("to", 0);
anim.setAttribute("dur", 0.25);
leg._path.appendChild(anim);
anim.beginElement();
//Animate opacity
anim = document.createElementNS(xmlns, "animate");
anim.setAttribute("attributeName", "stroke-opacity");
anim.setAttribute("attributeName", "stroke-opacity");
anim.setAttribute("begin", "indefinite");
anim.setAttribute("from", 0);
anim.setAttribute("to", 0.5);
anim.setAttribute("dur", 0.25);
leg._path.appendChild(anim);
anim.beginElement();
m.options.opacity = 0.5;
m._path.setAttribute('stroke-opacity', 0.5);
}
me.setOpacity(0.3);
}
//Set the opacity of the spiderLegs back to their correct value
// The animations above override this until they complete.
// Doing this at 250ms causes some minor flickering on FF, so just do it immediately
// If the initial opacity of the spiderlegs isn't 0 then they appear before the animation starts.
if (L.Browser.svg) {
setTimeout(function () {
for (i = childMarkers.length - 1; i >= 0; i--) {
m = childMarkers[i]._spiderLeg;
m.options.opacity = 0.5;
m._path.setAttribute('stroke-opacity', 0.5);
}
}, 0);
}
setTimeout(function () {
group._animationEnd();
}, 250);
}, 0);
setTimeout(function () {
group._animationEnd();
}, 250);
},
_animationUnspiderfy: function () {
+42 -37
View File
@@ -305,28 +305,26 @@ L.MarkerClusterGroup.include(!L.DomUtil.TRANSITION ? {
});
//Immediately fire an event to update the opacity and locations (If we immediately set it they won't animate)
setTimeout(function () {
var j, n;
this._forceLayout();
var j, n;
//Update opacities
me._topClusterLevel._recursivelyBecomeVisible(bounds, depthToStartAt + depthToDescend);
//TODO Maybe? Update markers in _recursivelyBecomeVisible
for (j in me._layers) {
if (me._layers.hasOwnProperty(j)) {
n = me._layers[j];
//Update opacities
me._topClusterLevel._recursivelyBecomeVisible(bounds, depthToStartAt + depthToDescend);
//TODO Maybe? Update markers in _recursivelyBecomeVisible
for (j in me._layers) {
if (me._layers.hasOwnProperty(j)) {
n = me._layers[j];
if (!(n instanceof L.MarkerCluster) && n._icon) {
n.setOpacity(1);
}
if (!(n instanceof L.MarkerCluster) && n._icon) {
n.setOpacity(1);
}
}
}
//update the positions of the just added clusters/markers
me._topClusterLevel._recursively(bounds, depthToStartAt, 0, function (c) {
c._recursivelyRestoreChildPositions(depthToDescend);
});
}, 0);
//update the positions of the just added clusters/markers
me._topClusterLevel._recursively(bounds, depthToStartAt, 0, function (c) {
c._recursivelyRestoreChildPositions(depthToDescend);
});
this._inZoomAnimation++;
@@ -361,10 +359,9 @@ L.MarkerClusterGroup.include(!L.DomUtil.TRANSITION ? {
var me = this;
//Immediately fire an event to update the opacity (If we immediately set it they won't animate)
setTimeout(function () {
marker._recursivelyBecomeVisible(bounds, depthToStartAt);
}, 0);
//Update the opacity (If we immediately set it they won't animate)
this._forceLayout();
marker._recursivelyBecomeVisible(bounds, depthToStartAt);
//TODO: Maybe use the transition timing stuff to make this more reliable
//When the animations are done, tidy up
@@ -383,28 +380,36 @@ L.MarkerClusterGroup.include(!L.DomUtil.TRANSITION ? {
if (newCluster !== layer) {
if (newCluster._childCount > 2) { //Was already a cluster
this._forceLayout();
this._animationStart();
var backupLatlng = layer.getLatLng();
layer.setLatLng(newCluster._latlng);
layer.setOpacity(0);
setTimeout(function () {
L.FeatureGroup.prototype.removeLayer.call(me, layer);
layer.setLatLng(backupLatlng);
var backupLatlng = layer.getLatLng();
layer.setLatLng(newCluster._latlng);
layer.setOpacity(0);
setTimeout(function () {
L.FeatureGroup.prototype.removeLayer.call(me, layer);
layer.setLatLng(backupLatlng);
me._animationEnd();
}, 250);
}, 0);
me._animationEnd();
}, 250);
} else { //Just became a cluster
setTimeout(function () {
me._animationStart();
me._animationZoomOutSingle(newCluster, 0, 1);
}, 0);
this._forceLayout();
me._animationStart();
me._animationZoomOutSingle(newCluster, 0, 1);
}
}
},
//Force a browser layout of stuff in the map
// Should apply the current opacity and location to all elements so we can update them again for an animation
_forceLayout: function () {
//In my testing this works, infact offsetWidth of any element seems to work.
//Could loop all this._layers and do this for each _icon if it stops working
L.Util.falseFn(document.body.offsetWidth);
}
});