mirror of
https://github.com/Leaflet/Leaflet.git
synced 2025-08-20 14:34:38 +00:00
merge Florian's pull, fixes, cleanup, circle click, added todos
This commit is contained in:
82
debug/vector/vector-canvas.html
Normal file
82
debug/vector/vector-canvas.html
Normal file
@ -0,0 +1,82 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Leaflet debug page</title>
|
||||
|
||||
<link rel="stylesheet" href="../../dist/leaflet.css" />
|
||||
<!--[if lte IE 8]><link rel="stylesheet" href="../../dist/leaflet.ie.css" /><![endif]-->
|
||||
|
||||
<link rel="stylesheet" href="../css/screen.css" />
|
||||
|
||||
<script src="../leaflet-include.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="map" style="width: 800px; height: 600px; border: 1px solid #ccc"></div>
|
||||
|
||||
<script src="route.js"></script>
|
||||
<script>
|
||||
var cloudmadeUrl = 'http://{s}.tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/997/256/{z}/{x}/{y}.png',
|
||||
cloudmade = new L.TileLayer(cloudmadeUrl, {maxZoom: 18});
|
||||
|
||||
for (var i = 0, latlngs = [], len = route.length; i < len; i++) {
|
||||
latlngs.push(new L.LatLng(route[i][0], route[i][1]));
|
||||
}
|
||||
var path = new L.Polyline(latlngs);
|
||||
|
||||
var map = new L.Map('map', {layers: [cloudmade]});
|
||||
|
||||
map.fitBounds(new L.LatLngBounds(latlngs));
|
||||
|
||||
map.addLayer(new L.Marker(latlngs[0]));
|
||||
map.addLayer(new L.Marker(latlngs[len - 1]));
|
||||
|
||||
var circleLocation = new L.LatLng(51.508, -0.11),
|
||||
circleOptions = {
|
||||
color: 'red',
|
||||
fillColor: 'blue',
|
||||
fillOpacity: 0.7
|
||||
};
|
||||
|
||||
var circle = new L.Circle(circleLocation, 500000, circleOptions);
|
||||
map.addLayer(circle);
|
||||
|
||||
circle.bindPopup('I am a circle');
|
||||
|
||||
map.addLayer(path);
|
||||
|
||||
var p1 = latlngs[0],
|
||||
p2 = latlngs[parseInt(len/4)],
|
||||
p3 = latlngs[parseInt(len/3)],
|
||||
p4 = latlngs[parseInt(len/2)],
|
||||
p5 = latlngs[len - 1],
|
||||
polygonPoints = [p1, p2, p3, p4, p5];
|
||||
|
||||
var h1 = new L.LatLng(p1.lat, p1.lng),
|
||||
h2 = new L.LatLng(p2.lat, p2.lng),
|
||||
h3 = new L.LatLng(p3.lat, p3.lng),
|
||||
h4 = new L.LatLng(p4.lat, p4.lng),
|
||||
h5 = new L.LatLng(p5.lat, p5.lng);
|
||||
|
||||
h1.lng += 20;
|
||||
h2.lat -= 5;
|
||||
h3.lat -= 5;
|
||||
h4.lng -= 10;
|
||||
h5.lng -= 8;
|
||||
h5.lat += 10;
|
||||
|
||||
var holePoints = [h5, h4, h3, h2, h1];
|
||||
|
||||
var polygon = new L.Polygon([polygonPoints, holePoints], {
|
||||
fillColor: "#333"
|
||||
});
|
||||
map.addLayer(polygon);
|
||||
|
||||
/*var hole = new L.Polygon([h1,h2,h3,h4,h5], {
|
||||
fillColor: "green"
|
||||
});
|
||||
map.addLayer(hole);
|
||||
*/
|
||||
path.bindPopup("Hello world");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -30,51 +30,9 @@
|
||||
map.addLayer(new L.Marker(latlngs[0]));
|
||||
map.addLayer(new L.Marker(latlngs[len - 1]));
|
||||
|
||||
var circleLocation = new L.LatLng(51.508, -0.11),
|
||||
circleOptions = {
|
||||
color: 'red',
|
||||
fillColor: 'blue',
|
||||
fillOpacity: 0.7
|
||||
};
|
||||
|
||||
var circle = new L.Circle(circleLocation, 500000, circleOptions);
|
||||
map.addLayer(circle);
|
||||
|
||||
map.addLayer(path);
|
||||
|
||||
var p1 = latlngs[0],
|
||||
p2 = latlngs[parseInt(len/4)],
|
||||
p3 = latlngs[parseInt(len/3)],
|
||||
p4 = latlngs[parseInt(len/2)],
|
||||
p5 = latlngs[len - 1],
|
||||
polygonPoints = [p1, p2, p3, p4, p5];
|
||||
|
||||
var h1 = new L.LatLng(p1.lat, p1.lng),
|
||||
h2 = new L.LatLng(p2.lat, p2.lng),
|
||||
h3 = new L.LatLng(p3.lat, p3.lng),
|
||||
h4 = new L.LatLng(p4.lat, p4.lng),
|
||||
h5 = new L.LatLng(p5.lat, p5.lng);
|
||||
|
||||
h1.lng += 20;
|
||||
h2.lat -= 5;
|
||||
h3.lat -= 5;
|
||||
h4.lng -= 10;
|
||||
h5.lng -= 8;
|
||||
h5.lat += 10;
|
||||
|
||||
var holePoints = [h5, h4, h3, h2, h1];
|
||||
|
||||
var polygon = new L.Polygon([polygonPoints, holePoints], {
|
||||
fillColor: "#333"
|
||||
});
|
||||
map.addLayer(polygon);
|
||||
|
||||
/*var hole = new L.Polygon([h1,h2,h3,h4,h5], {
|
||||
fillColor: "green"
|
||||
});
|
||||
map.addLayer(hole);
|
||||
*/
|
||||
path.bindPopup("Hello world");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
@ -27,6 +27,13 @@ L.Class.extend = function(/*Object*/ props) /*-> Class*/ {
|
||||
// add class name
|
||||
//proto.className = props;
|
||||
|
||||
//inherit parent's statics
|
||||
for (var i in this) {
|
||||
if (this.hasOwnProperty(i) && i != 'prototype') {
|
||||
NewClass[i] = this[i];
|
||||
}
|
||||
}
|
||||
|
||||
// mix static properties into the class
|
||||
if (props.statics) {
|
||||
L.Util.extend(NewClass, props.statics);
|
||||
@ -55,12 +62,5 @@ L.Class.extend = function(/*Object*/ props) /*-> Class*/ {
|
||||
L.Util.extend(this.prototype, props);
|
||||
};
|
||||
|
||||
//inherit parent's statics
|
||||
for (var i in this) {
|
||||
if (this.hasOwnProperty(i) && i != 'prototype') {
|
||||
NewClass[i] = this[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NewClass;
|
||||
};
|
@ -2,11 +2,29 @@
|
||||
* Circle canvas specific drawing parts.
|
||||
*/
|
||||
|
||||
L.Circle = L.Path.SVG || !L.Path.Canvas ? L.Circle : L.Circle.extend({
|
||||
_drawPath : function() {
|
||||
L.Circle = /*L.Path.SVG || !L.Path.Canvas ? L.Circle :*/ L.Circle.extend({
|
||||
_drawPath: function() {
|
||||
var p = this._point;
|
||||
|
||||
this._updateStyle();
|
||||
var p = this._point,
|
||||
r = this._radius;
|
||||
this._ctx.arc(p.x,p.y,r, 0,Math.PI*2);
|
||||
this._ctx.arc(p.x, p.y, this._radius, 0, Math.PI * 2);
|
||||
},
|
||||
|
||||
_initEvents: function() {
|
||||
if (this.options.clickable) {
|
||||
// TODO hand cursor
|
||||
// TODO mouseover, mouseout, dblclick
|
||||
this._map.on('click', this._onClick, this);
|
||||
}
|
||||
},
|
||||
|
||||
_onClick: function(e) {
|
||||
var p1 = this._point,
|
||||
p2 = e.layerPoint;
|
||||
|
||||
// TODO take strokeWidth into account
|
||||
if (p1.distanceTo(p2) <= this._radius) {
|
||||
this.fire('click', e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -6,36 +6,41 @@ L.Path.Canvas = (function() {
|
||||
return !!document.createElement('canvas').getContext;
|
||||
})();
|
||||
|
||||
L.Path = L.Path.SVG ? L.Path : !L.Path.Canvas ? L.Path.VML : L.Path.extend({
|
||||
/*
|
||||
* TODO define L.Path.Canvas as a separate class instead of extending L.Path,
|
||||
* and implement class factories for Polyline and Circle that choose the right
|
||||
* renderer based on constructor options
|
||||
*/
|
||||
|
||||
L.Path = /*L.Path.SVG ? L.Path : !L.Path.Canvas ? L.Path.VML :*/ L.Path.extend({
|
||||
initialize: function(options) {
|
||||
L.Util.setOptions(this, options);
|
||||
},
|
||||
|
||||
statics: {
|
||||
CLIP_PADDING: 0.02
|
||||
/*statics: {
|
||||
CLIP_PADDING: 0.02 // not sure if there's a need to set it to a small value
|
||||
},*/
|
||||
|
||||
options: {
|
||||
updateOnMoveEnd: true
|
||||
},
|
||||
|
||||
options : {
|
||||
updateOnMoveEnd: true
|
||||
_initElements: function() {
|
||||
this._initRoot();
|
||||
},
|
||||
|
||||
_initRoot: function() {
|
||||
if (!this._map._pathRoot) {
|
||||
this._map._pathRoot = document.createElement("canvas");
|
||||
this._ctx = this._map._pathRoot.getContext('2d');
|
||||
|
||||
this._map._panes.overlayPane.appendChild(this._map._pathRoot);
|
||||
var root = this._map._pathRoot;
|
||||
|
||||
if (!root) {
|
||||
root = this._map._pathRoot = document.createElement("canvas");
|
||||
this._map._panes.overlayPane.appendChild(root);
|
||||
|
||||
this._map.on('moveend', this._updateCanvasViewport, this);
|
||||
this._updateCanvasViewport();
|
||||
}
|
||||
else {
|
||||
this._ctx = this._map._pathRoot.getContext('2d');
|
||||
}
|
||||
},
|
||||
|
||||
_initStyle: function() {
|
||||
//NOOP.
|
||||
this._ctx = root.getContext('2d');
|
||||
},
|
||||
|
||||
_updateStyle: function() {
|
||||
@ -48,35 +53,32 @@ L.Path = L.Path.SVG ? L.Path : !L.Path.Canvas ? L.Path.VML : L.Path.extend({
|
||||
}
|
||||
},
|
||||
|
||||
_drawPath : function() {
|
||||
this._updateStyle();
|
||||
_drawPath: function() {
|
||||
var i, j, len, len2, point, drawMethod;
|
||||
|
||||
this._ctx.beginPath();
|
||||
|
||||
for (var i = 0, len = this._parts.length; i < len; i++) {
|
||||
for (var j=0;j<this._parts[i].length;j++) {
|
||||
var point = this._parts[i][j];
|
||||
|
||||
for (i = 0, len = this._parts.length; i < len; i++) {
|
||||
for (j = 0, len2 = this._parts[i].length; j < len2; j++) {
|
||||
point = this._parts[i][j];
|
||||
drawMethod = (j === 0 ? 'move' : 'line') + 'To';
|
||||
|
||||
if (j === 0) {
|
||||
if (i > 0) {
|
||||
this._ctx.closePath();
|
||||
}
|
||||
this._ctx.moveTo(point.x, point.y);
|
||||
}
|
||||
else {
|
||||
this._ctx.lineTo(point.x,point.y);
|
||||
}
|
||||
this._ctx[drawMethod](point.x, point.y);
|
||||
}
|
||||
// TODO refactor ugly hack
|
||||
if (this instanceof L.Polygon) {
|
||||
this._ctx.closePath();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
|
||||
_updatePath: function() {
|
||||
this._drawPath();
|
||||
|
||||
this._updateStyle();
|
||||
|
||||
if (this.options.fill) {
|
||||
this._ctx.globalAlpha = this.options.fillOpacity;
|
||||
this._ctx.closePath();
|
||||
this._ctx.fill();
|
||||
}
|
||||
|
||||
@ -85,6 +87,10 @@ L.Path = L.Path.SVG ? L.Path : !L.Path.Canvas ? L.Path.VML : L.Path.extend({
|
||||
this._ctx.stroke();
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO not sure if possible to implement, but a great optimization would be to do
|
||||
* 1 fill/stroke for all features with equal style instead of 1 for each feature
|
||||
*/
|
||||
},
|
||||
|
||||
_updateCanvasViewport: function() {
|
||||
@ -92,28 +98,16 @@ L.Path = L.Path.SVG ? L.Path : !L.Path.Canvas ? L.Path.VML : L.Path.extend({
|
||||
|
||||
var vp = this._map._pathViewport,
|
||||
min = vp.min,
|
||||
max = vp.max,
|
||||
width = max.x - min.x,
|
||||
height = max.y - min.y,
|
||||
root = this._map._pathRoot,
|
||||
pane = this._map._panes.overlayPane;
|
||||
size = vp.max.subtract(min),
|
||||
root = this._map._pathRoot;
|
||||
|
||||
// Hack to make flicker on drag end on mobile webkit less irritating
|
||||
// Unfortunately I haven't found a good workaround for this yet
|
||||
if (L.Browser.mobileWebkit) { pane.removeChild(root); }
|
||||
|
||||
//TODO check if it's works properly on mobile webkit
|
||||
L.DomUtil.setPosition(root, min);
|
||||
root.setAttribute('width', width); //Attention resets canvas, but not on mobile webkit!
|
||||
root.setAttribute('height', height);
|
||||
|
||||
var vp = this._map._pathViewport;
|
||||
this._ctx.translate(-vp.min.x, -vp.min.y);
|
||||
|
||||
|
||||
if (L.Browser.mobileWebkit) { pane.appendChild(root); }
|
||||
root.width = size.x;
|
||||
root.height = size.y;
|
||||
root.getContext('2d').translate(-min.x, -min.y);
|
||||
},
|
||||
|
||||
_initEvents :function() {
|
||||
//doesn't work currently.
|
||||
}
|
||||
// will be implemented for each of the children classes
|
||||
_initEvents: L.Util.falseFn
|
||||
});
|
||||
|
@ -54,5 +54,9 @@ L.Polygon = L.Polyline.extend({
|
||||
_getPathPartStr: function(points) {
|
||||
var str = L.Polyline.prototype._getPathPartStr.call(this, points);
|
||||
return str + (L.Path.SVG ? 'z' : 'x');
|
||||
},
|
||||
|
||||
_initEvents: function() {
|
||||
// TODO polygon events (through http://en.wikipedia.org/wiki/Point_in_polygon)
|
||||
}
|
||||
});
|
@ -108,5 +108,9 @@ L.Polyline = L.Path.extend({
|
||||
this._simplifyPoints();
|
||||
|
||||
L.Path.prototype._updatePath.call(this);
|
||||
},
|
||||
|
||||
_initEvents: function() {
|
||||
// TODO polyline events (through loop with pointToSegmentDistance)
|
||||
}
|
||||
});
|
Reference in New Issue
Block a user