Added DivIcon for lightweight div-based markers, and editable poly example

This commit is contained in:
mourner 2012-02-16 13:00:45 +02:00
parent e42f140970
commit 1a8a0ce632
8 changed files with 134 additions and 66 deletions

View File

@ -7,24 +7,29 @@ Leaflet Changelog
### Improvements ### Improvements
#### Breaking API changes
* Converted `Icon` properties (like `iconUrl`) to options, changed constructor signature to `Icon(options)`.
* Improved `TileLayer` constructor to interpolate URL template values from options (removed third `urlParams` argument).
* Replaced ugly control position constants (e.g. L.Control.Position.TOP_LEFT) with light strings ('topleft', 'bottomright', etc.)
* Removed `Map` `locateAndSetView` method (use `locate` with `setView: true` option)
#### API Improvements #### API Improvements
* Added `DivIcon` class that easily allows you to create lightweight div-based markers.
* Added `Icon` `className` option to assign a custom class to an icon.
* Added `Circle` `getBounds` method. [#440](https://github.com/CloudMade/Leaflet/issues/440) * Added `Circle` `getBounds` method. [#440](https://github.com/CloudMade/Leaflet/issues/440)
* Added public `redraw` method to vector layers (useful if you manipulate their `LatLng` points directly).
* Added `setPosition` and `getPosition` to all controls, as well as ability to pass certain position as an option when creating a control. * Added `setPosition` and `getPosition` to all controls, as well as ability to pass certain position as an option when creating a control.
* Made controls implementation easier (now more magic happens under the hood). * Made controls implementation easier (now more magic happens under the hood).
* Added `Map` `containerPointToLatLng` and `latLngToContainerPoint` methods. [#474](https://github.com/CloudMade/Leaflet/issues/474) * Added `Map` `containerPointToLatLng` and `latLngToContainerPoint` methods. [#474](https://github.com/CloudMade/Leaflet/issues/474)
* Added `containerPoint` property to `MouseEvent`. * Added `containerPoint` property to `MouseEvent`.
* Added chaining to `DomEvent` methods. * Added chaining to `DomEvent` methods.
* Fixed a bug where popup size was calculated incorrectly in IE.
#### Breaking API changes
* Improved `TileLayer` constructor to interpolate URL template values from options (removed third `urlParams` argument).
* Replaced ugly control position constants (e.g. L.Control.Position.TOP_LEFT) with light strings ('topleft', 'bottomright', etc.)
* Removed `Map` `locateAndSetView` method (use `locate` with `setView: true` option)
### Bug fixes ### Bug fixes
* Fixed a bug where popup size was calculated incorrectly in IE.
* Fixed a bug where cursor would flicker when dragging a marker.
* Fixed a bug where `TileLayer.WMS` wouldn't take `insertAtTheBottom` option into account (by [@bmcbride](https://github.com/bmcbride)). [#478](https://github.com/CloudMade/Leaflet/pull/478) * Fixed a bug where `TileLayer.WMS` wouldn't take `insertAtTheBottom` option into account (by [@bmcbride](https://github.com/bmcbride)). [#478](https://github.com/CloudMade/Leaflet/pull/478)
* Fixed a bug where marker click event would stop working if you dragged it and then disabled dragging. [#434](https://github.com/CloudMade/Leaflet/issues/434) * Fixed a bug where marker click event would stop working if you dragged it and then disabled dragging. [#434](https://github.com/CloudMade/Leaflet/issues/434)

View File

@ -57,6 +57,12 @@ var deps = {
desc: 'Markers to put on the map.' desc: 'Markers to put on the map.'
}, },
DivIcon: {
src: ['layer/marker/DivIcon.js'],
deps: ['Marker'],
desc: 'Lightweight div-based icon for markers.'
},
Popup: { Popup: {
src: ['layer/Popup.js', 'layer/marker/Marker.Popup.js', 'map/ext/Map.Popup.js'], src: ['layer/Popup.js', 'layer/marker/Marker.Popup.js', 'map/ext/Map.Popup.js'],
deps: ['Marker'], deps: ['Marker'],

View File

@ -62,6 +62,7 @@
'layer/Popup.js', 'layer/Popup.js',
'layer/marker/Icon.js', 'layer/marker/Icon.js',
'layer/marker/DivIcon.js',
'layer/marker/Marker.js', 'layer/marker/Marker.js',
'layer/marker/Marker.Popup.js', 'layer/marker/Marker.Popup.js',
'layer/marker/Marker.Drag.js', 'layer/marker/Marker.Drag.js',

View File

@ -5,9 +5,9 @@
<link rel="stylesheet" href="../../dist/leaflet.css" /> <link rel="stylesheet" href="../../dist/leaflet.css" />
<!--[if lte IE 8]><link rel="stylesheet" href="../../dist/leaflet.ie.css" /><![endif]--> <!--[if lte IE 8]><link rel="stylesheet" href="../../dist/leaflet.ie.css" /><![endif]-->
<link rel="stylesheet" href="../css/screen.css" /> <link rel="stylesheet" href="../css/screen.css" />
<script src="../leaflet-include.js"></script> <script src="../leaflet-include.js"></script>
</head> </head>
<body> <body>
@ -18,26 +18,36 @@
var cloudmadeUrl = 'http://{s}.tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/997/256/{z}/{x}/{y}.png', var cloudmadeUrl = 'http://{s}.tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/997/256/{z}/{x}/{y}.png',
cloudmade = new L.TileLayer(cloudmadeUrl, {maxZoom: 18}), cloudmade = new L.TileLayer(cloudmadeUrl, {maxZoom: 18}),
map = new L.Map('map', {layers: [cloudmade], center: new L.LatLng(50.5, 30.5), zoom: 15}); map = new L.Map('map', {layers: [cloudmade], center: new L.LatLng(50.5, 30.5), zoom: 15});
var latlngs = [];
latlngs.push(getRandomLatLng(map));
latlngs.push(getRandomLatLng(map));
latlngs.push(getRandomLatLng(map));
var path = new L.Polygon(latlngs);
console.log(latlngs);
var icon = new L.DivIcon({
var marker = new L.Marker(latlngs[0], {draggable: true}); iconSize: new L.Point(8, 8),
map.addLayer(marker); className: 'leaflet-div-icon leaflet-editing-icon'
marker.on('drag', function() {
latlngs[0] = marker.getLatLng();
path.setLatLngs(latlngs);
}); });
var latlngs = [],
path;
for (var i = 0; i < 5; i++) {
latlngs.push(getRandomLatLng(map));
(function (i) {
var marker = new L.Marker(latlngs[i], {
draggable: true,
icon: icon
});
map.addLayer(marker);
marker.on('drag', function() {
latlngs[i] = marker.getLatLng();
path.redraw();
});
}(i));
}
path = new L.Polygon(latlngs, {clickable: false});
map.addLayer(path); map.addLayer(path);
</script> </script>
</body> </body>
</html> </html>

97
dist/leaflet-src.js vendored
View File

@ -2167,19 +2167,21 @@ L.ImageOverlay = L.Class.extend({
L.Icon = L.Class.extend({ L.Icon = L.Class.extend({
iconUrl: L.ROOT_URL + 'images/marker.png', options: {
shadowUrl: L.ROOT_URL + 'images/marker-shadow.png', iconUrl: L.ROOT_URL + 'images/marker.png',
iconSize: new L.Point(25, 41),
iconAnchor: new L.Point(13, 41),
popupAnchor: new L.Point(0, -33),
iconSize: new L.Point(25, 41), shadowUrl: L.ROOT_URL + 'images/marker-shadow.png',
shadowSize: new L.Point(41, 41), shadowSize: new L.Point(41, 41),
shadowOffset: new L.Point(0, 0),
iconAnchor: new L.Point(13, 41), className: ''
popupAnchor: new L.Point(0, -33), },
initialize: function (iconUrl) { initialize: function (options) {
if (iconUrl) { L.Util.setOptions(this, options);
this.iconUrl = iconUrl;
}
}, },
createIcon: function () { createIcon: function () {
@ -2191,28 +2193,29 @@ L.Icon = L.Class.extend({
}, },
_createIcon: function (name) { _createIcon: function (name) {
var size = this[name + 'Size'], var img = this._createImg(this.options[name + 'Url']);
src = this[name + 'Url'], this._setIconStyles(img, name);
img; return img;
},
if (!src && (name === 'shadow')) { _setIconStyles: function (img, name) {
return null; var options = this.options,
size = options[name + 'Size'],
anchor = options.iconAnchor || size.divideBy(2, true);
if (name === 'shadow') {
anchor._add(options.shadowOffset);
} }
img = src ? this._createImg(src) img.className = 'leaflet-marker-' + name + ' ' + options.className;
: document.createElement('div');
img.className = 'leaflet-marker-' + name; img.style.marginLeft = (-anchor.x) + 'px';
img.style.marginTop = (-anchor.y) + 'px';
img.style.marginLeft = (-this.iconAnchor.x) + 'px'; if (options.iconSize) {
img.style.marginTop = (-this.iconAnchor.y) + 'px';
if (size) {
img.style.width = size.x + 'px'; img.style.width = size.x + 'px';
img.style.height = size.y + 'px'; img.style.height = size.y + 'px';
} }
return img;
}, },
_createImg: function (src) { _createImg: function (src) {
@ -2398,6 +2401,26 @@ L.Marker = L.Class.extend({
}); });
L.DivIcon = L.Icon.extend({
options: {
iconSize: new L.Point(12, 12),
iconAnchor: null,
popupAnchor: new L.Point(0, -8),
className: 'leaflet-div-icon'
},
createIcon: function () {
var div = document.createElement('div');
this._setIconStyles(div, 'icon');
return div;
},
createShadow: function () {
return null;
}
});
L.Popup = L.Class.extend({ L.Popup = L.Class.extend({
includes: L.Mixin.Events, includes: L.Mixin.Events,
@ -2608,7 +2631,7 @@ L.Marker.include({
bindPopup: function (content, options) { bindPopup: function (content, options) {
options = L.Util.extend({ options = L.Util.extend({
offset: this.options.icon.popupAnchor offset: this.options.icon.options.popupAnchor
}, options); }, options);
if (!this._popup) { if (!this._popup) {
@ -2850,11 +2873,12 @@ L.Path = L.Class.extend({
return this; return this;
}, },
_redraw: function () { redraw: function () {
if (this._map) { if (this._map) {
this.projectLatlngs(); this.projectLatlngs();
this._updatePath(); this._updatePath();
} }
return this;
} }
}); });
@ -3537,19 +3561,17 @@ L.Polyline = L.Path.extend({
setLatLngs: function (latlngs) { setLatLngs: function (latlngs) {
this._latlngs = latlngs; this._latlngs = latlngs;
this._redraw(); return this.redraw();
return this;
}, },
addLatLng: function (latlng) { addLatLng: function (latlng) {
this._latlngs.push(latlng); this._latlngs.push(latlng);
this._redraw(); return this.redraw();
return this;
}, },
spliceLatLngs: function (index, howMany) { spliceLatLngs: function (index, howMany) {
var removed = [].splice.apply(this._latlngs, arguments); var removed = [].splice.apply(this._latlngs, arguments);
this._redraw(); this.redraw();
return removed; return removed;
}, },
@ -3831,14 +3853,12 @@ L.Circle = L.Path.extend({
setLatLng: function (latlng) { setLatLng: function (latlng) {
this._latlng = latlng; this._latlng = latlng;
this._redraw(); return this.redraw();
return this;
}, },
setRadius: function (radius) { setRadius: function (radius) {
this._mRadius = radius; this._mRadius = radius;
this._redraw(); return this.redraw();
return this;
}, },
projectLatlngs: function () { projectLatlngs: function () {
@ -3921,8 +3941,7 @@ L.CircleMarker = L.Circle.extend({
setRadius: function (radius) { setRadius: function (radius) {
this._radius = radius; this._radius = radius;
this._redraw(); return this.redraw();
return this;
} }
}); });
@ -4322,6 +4341,7 @@ L.Draggable = L.Class.extend({
} }
L.DomEvent.removeListener(this._dragStartTarget, L.Draggable.START, this._onDown); L.DomEvent.removeListener(this._dragStartTarget, L.Draggable.START, this._onDown);
this._enabled = false; this._enabled = false;
this._moved = false;
}, },
_onDown: function (e) { _onDown: function (e) {
@ -4417,11 +4437,12 @@ L.Draggable = L.Class.extend({
_setMovingCursor: function () { _setMovingCursor: function () {
this._bodyCursor = document.body.style.cursor; this._bodyCursor = document.body.style.cursor;
document.body.style.cursor = 'move'; this._dragStartTarget.style.cursor = document.body.style.cursor = 'move';
}, },
_restoreCursor: function () { _restoreCursor: function () {
document.body.style.cursor = this._bodyCursor; document.body.style.cursor = this._bodyCursor;
this._dragStartTarget.style.cursor = '';
}, },
_simulateEvent: function (type, e) { _simulateEvent: function (type, e) {

7
dist/leaflet.css vendored
View File

@ -37,6 +37,13 @@
.leaflet-container img { .leaflet-container img {
max-width: none !important; max-width: none !important;
} }
.leaflet-div-icon {
background: #fff;
box-shadow: 0 0 6px #000;
}
.leaflet-editing-icon {
border-radius: 2px;
}
.leaflet-tile-pane { z-index: 2; } .leaflet-tile-pane { z-index: 2; }

2
dist/leaflet.js vendored

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,18 @@
L.DivIcon = L.Icon.extend({
options: {
iconSize: new L.Point(12, 12),
iconAnchor: null,
popupAnchor: new L.Point(0, -8),
className: 'leaflet-div-icon'
},
createIcon: function () {
var div = document.createElement('div');
this._setIconStyles(div, 'icon');
return div;
},
createShadow: function () {
return null;
}
});