minor code cleanup, more destructive point operations

This commit is contained in:
mourner 2012-08-10 22:40:55 +03:00
parent 7627d39700
commit 8980f2d224
10 changed files with 91 additions and 59 deletions

View File

@ -1,5 +1,5 @@
/*
* L.DomUtil contains various utility functions for working with DOM
* L.DomUtil contains various utility functions for working with DOM.
*/
L.DomUtil = {
@ -8,48 +8,51 @@ L.DomUtil = {
},
getStyle: function (el, style) {
var value = el.style[style];
if (!value && el.currentStyle) {
value = el.currentStyle[style];
}
if (!value || value === 'auto') {
var css = document.defaultView.getComputedStyle(el, null);
value = css ? css[style] : null;
}
return (value === 'auto' ? null : value);
return value === 'auto' ? null : value;
},
getViewportOffset: function (element) {
var top = 0,
left = 0,
el = element,
docBody = document.body;
docBody = document.body,
pos;
do {
top += el.offsetTop || 0;
left += el.offsetLeft || 0;
pos = L.DomUtil.getStyle(el, 'position');
if (el.offsetParent === docBody &&
L.DomUtil.getStyle(el, 'position') === 'absolute') {
break;
}
if (L.DomUtil.getStyle(el, 'position') === 'fixed') {
top += docBody.scrollTop || 0;
if (el.offsetParent === docBody && pos === 'absolute') { break; }
if (pos === 'fixed') {
top += docBody.scrollTop || 0;
left += docBody.scrollLeft || 0;
break;
}
el = el.offsetParent;
} while (el);
el = element;
do {
if (el === docBody) {
break;
}
if (el === docBody) { break; }
top -= el.scrollTop || 0;
top -= el.scrollTop || 0;
left -= el.scrollLeft || 0;
el = el.parentNode;
@ -59,15 +62,19 @@ L.DomUtil = {
},
create: function (tagName, className, container) {
var el = document.createElement(tagName);
el.className = className;
if (container) {
container.appendChild(el);
}
return el;
},
disableTextSelection: function () {
if (document.selection && document.selection.empty) {
document.selection.empty();
}
@ -94,12 +101,12 @@ L.DomUtil = {
},
removeClass: function (el, name) {
function replaceFn(w, match) {
if (match === name) {
return '';
}
if (match === name) { return ''; }
return w;
}
el.className = el.className
.replace(/(\S+)\s*/g, replaceFn)
.replace(/(^\s+|\s+$)/, '');
@ -130,6 +137,7 @@ L.DomUtil = {
},
testProp: function (props) {
var style = document.documentElement.style;
for (var i = 0; i < props.length; i++) {
@ -141,7 +149,7 @@ L.DomUtil = {
},
getTranslateString: function (point) {
// On webkit browsers (Chrome/Safari/MobileSafari/Android) using translate3d instead of translate
// on WebKit browsers (Chrome/Safari/iOS Safari/Android) using translate3d instead of translate
// makes animation smoother as it ensures HW accel is used. Firefox 13 doesn't care
// (same speed either way), Opera 12 doesn't support translate3d
@ -153,6 +161,7 @@ L.DomUtil = {
},
getScaleString: function (scale, origin) {
var preTranslateStr = L.DomUtil.getTranslateString(origin),
scaleStr = ' scale(' + scale + ') ',
postTranslateStr = L.DomUtil.getTranslateString(origin.multiplyBy(-1));
@ -160,8 +169,10 @@ L.DomUtil = {
return preTranslateStr + scaleStr + postTranslateStr;
},
setPosition: function (el, point, disable3D) {
setPosition: function (el, point, disable3D) { // (HTMLElement, Point[, Boolean])
el._leaflet_pos = point;
if (!disable3D && L.Browser.any3d) {
el.style[L.DomUtil.TRANSFORM] = L.DomUtil.getTranslateString(point);
@ -176,14 +187,21 @@ L.DomUtil = {
},
getPosition: function (el) {
// this method is only used for elements previously positioned using setPosition,
// so it's safe to cache the position for performance
return el._leaflet_pos;
}
};
L.Util.extend(L.DomUtil, {
TRANSITION: L.DomUtil.testProp(['transition', 'webkitTransition', 'OTransition', 'MozTransition', 'msTransition']),
TRANSFORM: L.DomUtil.testProp(['transform', 'WebkitTransform', 'OTransform', 'MozTransform', 'msTransform'])
});
L.DomUtil.TRANSITION_END = (L.DomUtil.TRANSITION === 'webkitTransition' || L.DomUtil.TRANSITION === 'OTransition' ?
L.DomUtil.TRANSITION + 'End' : 'transitionend');
// prefix style property names
L.DomUtil.TRANSFORM = L.DomUtil.testProp(
['transform', 'WebkitTransform', 'OTransform', 'MozTransform', 'msTransform']);
L.DomUtil.TRANSITION = L.DomUtil.testProp(
['transition', 'webkitTransition', 'OTransition', 'MozTransition', 'msTransition']);
L.DomUtil.TRANSITION_END =
L.DomUtil.TRANSITION === 'webkitTransition' || L.DomUtil.TRANSITION === 'OTransition' ?
L.DomUtil.TRANSITION + 'End' : 'transitionend';

View File

@ -8,10 +8,17 @@ L.Point = function (/*Number*/ x, /*Number*/ y, /*Boolean*/ round) {
};
L.Point.prototype = {
clone: function () {
return new L.Point(this.x, this.y);
},
// non-destructive, returns a new point
add: function (point) {
return this.clone()._add(L.point(point));
},
// destructive, used directly for performance in situations where it's safe to modify existing point
_add: function (point) {
this.x += point.x;
this.y += point.y;
@ -22,35 +29,36 @@ L.Point.prototype = {
return this.clone()._subtract(L.point(point));
},
// destructive subtract (faster)
_subtract: function (point) {
this.x -= point.x;
this.y -= point.y;
return this;
},
divideBy: function (num, round) {
return new L.Point(this.x / num, this.y / num, round);
divideBy: function (num) {
return this.clone()._divideBy(num);
},
multiplyBy: function (num, round) {
return new L.Point(this.x * num, this.y * num, round);
_divideBy: function (num) {
this.x /= num;
this.y /= num;
return this;
},
distanceTo: function (point) {
point = L.point(point);
multiplyBy: function (num) {
return this.clone()._multiplyBy(num);
},
var x = point.x - this.x,
y = point.y - this.y;
return Math.sqrt(x * x + y * y);
_multiplyBy: function (num) {
this.x *= num;
this.y *= num;
return this;
},
round: function () {
return this.clone()._round();
},
// destructive round
_round: function () {
this.x = Math.round(this.x);
this.y = Math.round(this.y);
@ -67,8 +75,13 @@ L.Point.prototype = {
return this;
},
clone: function () {
return new L.Point(this.x, this.y);
distanceTo: function (point) {
point = L.point(point);
var x = point.x - this.x,
y = point.y - this.y;
return Math.sqrt(x * x + y * y);
},
toString: function () {

View File

@ -94,10 +94,11 @@ L.ImageOverlay = L.Class.extend({
scale = map.getZoomScale(e.zoom),
nw = this._bounds.getNorthWest(),
se = this._bounds.getSouthEast(),
topLeft = map._latLngToNewLayerPoint(nw, e.zoom, e.center),
size = map._latLngToNewLayerPoint(se, e.zoom, e.center).subtract(topLeft),
currentSize = map.latLngToLayerPoint(se).subtract(map.latLngToLayerPoint(nw)),
origin = topLeft.add(size.subtract(currentSize).divideBy(2));
size = map._latLngToNewLayerPoint(se, e.zoom, e.center)._subtract(topLeft),
currentSize = map.latLngToLayerPoint(se)._subtract(map.latLngToLayerPoint(nw)),
origin = topLeft._add(size._subtract(currentSize)._divideBy(2));
image.style[L.DomUtil.TRANSFORM] = L.DomUtil.getTranslateString(origin) + ' scale(' + scale + ') ';
},
@ -105,7 +106,7 @@ L.ImageOverlay = L.Class.extend({
_reset: function () {
var image = this._image,
topLeft = this._map.latLngToLayerPoint(this._bounds.getNorthWest()),
size = this._map.latLngToLayerPoint(this._bounds.getSouthEast()).subtract(topLeft);
size = this._map.latLngToLayerPoint(this._bounds.getSouthEast())._subtract(topLeft);
L.DomUtil.setPosition(image, topLeft);

View File

@ -104,8 +104,8 @@ L.Map.include({
var p = L.Path.CLIP_PADDING,
size = this.getSize(),
panePos = L.DomUtil.getPosition(this._mapPane),
min = panePos.multiplyBy(-1)._subtract(size.multiplyBy(p)),
max = min.add(size.multiplyBy(1 + p * 2));
min = panePos.multiplyBy(-1)._subtract(size.multiplyBy(p)._round()),
max = min.add(size.multiplyBy(1 + p * 2)._round());
this._pathViewport = new L.Bounds(min, max);
}

View File

@ -205,6 +205,6 @@ L.Handler.PolyEdit = L.Handler.extend({
p1 = map.latLngToLayerPoint(marker1.getLatLng()),
p2 = map.latLngToLayerPoint(marker2.getLatLng());
return map.layerPointToLatLng(p1._add(p2).divideBy(2));
return map.layerPointToLatLng(p1._add(p2)._divideBy(2));
}
});

View File

@ -211,7 +211,7 @@ L.Map = L.Class.extend({
if (!this._loaded) { return this; }
var offset = oldSize.subtract(this.getSize()).divideBy(2, true);
var offset = oldSize._subtract(this.getSize())._divideBy(2)._round();
if (animate === true) {
this.panBy(offset);
@ -318,7 +318,7 @@ L.Map = L.Class.extend({
this._sizeChanged = false;
}
return this._size;
return this._size.clone();
},
getPixelBounds: function () {
@ -620,7 +620,7 @@ L.Map = L.Class.extend({
},
_getNewTopLeftPoint: function (center, zoom) {
var viewHalf = this.getSize().divideBy(2);
var viewHalf = this.getSize()._divideBy(2);
// TODO round on display, not calculation to increase precision?
return this.project(center, zoom)._subtract(viewHalf)._round();
},
@ -631,7 +631,7 @@ L.Map = L.Class.extend({
},
_getCenterLayerPoint: function () {
return this.containerPointToLayerPoint(this.getSize().divideBy(2));
return this.containerPointToLayerPoint(this.getSize()._divideBy(2));
},
_getCenterOffset: function (center) {

View File

@ -17,7 +17,7 @@ L.Map.include(!L.DomUtil.TRANSITION ? {} : {
if (!this.options.zoomAnimation) { return false; }
var scale = this.getZoomScale(zoom),
offset = this._getCenterOffset(center).divideBy(1 - 1 / scale);
offset = this._getCenterOffset(center)._divideBy(1 - 1 / scale);
// if offset does not exceed half of the view
if (!this._offsetIsWithinView(offset, 1)) { return false; }

View File

@ -80,7 +80,7 @@ L.Map.Drag = L.Handler.extend({
},
_onViewReset: function () {
var pxCenter = this._map.getSize().divideBy(2),
var pxCenter = this._map.getSize()._divideBy(2),
pxWorldCenter = this._map.latLngToLayerPoint(new L.LatLng(0, 0));
this._initialWorldOffset = pxWorldCenter.subtract(pxCenter).x;

View File

@ -41,17 +41,17 @@ L.Map.ScrollWheelZoom = L.Handler.extend({
if (!delta) { return; }
var newZoom = zoom + delta,
newCenter = this._getCenterForScrollWheelZoom(this._lastMousePos, newZoom);
newCenter = this._getCenterForScrollWheelZoom(newZoom);
map.setView(newCenter, newZoom);
},
_getCenterForScrollWheelZoom: function (mousePos, newZoom) {
_getCenterForScrollWheelZoom: function (newZoom) {
var map = this._map,
scale = map.getZoomScale(newZoom),
viewHalf = map.getSize().divideBy(2),
centerOffset = mousePos.subtract(viewHalf).multiplyBy(1 - 1 / scale),
newCenterPoint = map._getTopLeftPoint().add(viewHalf).add(centerOffset);
viewHalf = map.getSize()._divideBy(2),
centerOffset = this._lastMousePos._subtract(viewHalf)._multiplyBy(1 - 1 / scale),
newCenterPoint = map._getTopLeftPoint()._add(viewHalf)._add(centerOffset);
return map.unproject(newCenterPoint);
}

View File

@ -24,7 +24,7 @@ L.Map.TouchZoom = L.Handler.extend({
p2 = map.mouseEventToLayerPoint(e.touches[1]),
viewCenter = map._getCenterLayerPoint();
this._startCenter = p1.add(p2).divideBy(2, true);
this._startCenter = p1._add(p2)._divideBy(2);
this._startDist = p1.distanceTo(p2);
this._moved = false;
@ -48,7 +48,7 @@ L.Map.TouchZoom = L.Handler.extend({
p2 = map.mouseEventToLayerPoint(e.touches[1]);
this._scale = p1.distanceTo(p2) / this._startDist;
this._delta = p1.add(p2).divideBy(2, true).subtract(this._startCenter);
this._delta = p1._add(p2)._divideBy(2)._subtract(this._startCenter);
if (this._scale === 1) { return; }