New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

leaflet-pegman

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

leaflet-pegman - npm Package Compare versions

Comparing version 0.0.6 to 0.0.7

leaflet-pegman.min.css

1043

leaflet-pegman.js

@@ -10,577 +10,674 @@ /**

L.Control.Pegman = L.Control.extend({
includes: L.Evented ? L.Evented.prototype : L.Mixin.Events,
options: {
position: 'bottomright', // position of control inside the map
clickableStreetViewLayer: false, // WARNING: when enabled it will violate Google ToS rules
theme: "leaflet-pegman-v3-default", // or "leaflet-pegman-v3-small"
logging: false, // enable console logging (debugging)
},
includes: L.Evented ? L.Evented.prototype : L.Mixin.Events,
options: {
position: 'bottomright', // position of control inside the map
clickableStreetViewLayer: false, // WARNING: when enabled it will violate Google ToS rules
theme: "leaflet-pegman-v3-default", // or "leaflet-pegman-v3-small"
logging: false, // enable console logging (debugging),
apiKey: '',
libraries: '',
},
initialize: function(options) {
L.Util.setOptions(this, options);
initialize: function(options) {
L.Util.setOptions(this, options);
// Grab Left/Right/Up/Down Direction of Mouse for Pegman Image
this._mousePos = {
direction: {},
old: {},
};
// Grab Left/Right/Up/Down Direction of Mouse for Pegman Image
this._mousePos = {
direction: {},
old: {},
};
this._pegmanMarkerCoords = null;
this._streetViewCoords = null;
this._streetViewLayerEnabled = false;
this._pegmanMarkerCoords = null;
this._streetViewCoords = null;
this._streetViewLayerEnabled = false;
this.options.clickableStreetViewLayer = typeof(L.gridLayer.googleMutant) === "undefined" || this.options.clickableStreetViewLayer;
this.options.clickableStreetViewLayer = typeof(L.gridLayer.googleMutant) === "undefined" || this.options.clickableStreetViewLayer;
this._dropzoneMapOpts = {
accept: '.draggable', // Only Accept Elements Matching this CSS Selector
overlap: 0.75, // Require a 75% Element Overlap for a Drop to be Possible
ondropactivate: L.bind(this.onDropZoneActivated, this),
ondragenter: L.bind(this.onDropZoneDragEntered, this),
ondragleave: L.bind(this.onDropZoneDragLeaved, this),
ondrop: L.bind(this.onDropZoneDropped, this),
ondropdeactivate: L.bind(this.onDropZoneDeactivated, this),
};
this._draggableMarkerOpts = {
inertia: false,
onmove: L.bind(this.onDraggableMove, this),
onend: L.bind(this.onDraggableEnd, this),
};
this._dropzoneMapOpts = {
accept: '.draggable', // Only Accept Elements Matching this CSS Selector
overlap: 0.75, // Require a 75% Element Overlap for a Drop to be Possible
ondropactivate: L.bind(this.onDropZoneActivated, this),
ondragenter: L.bind(this.onDropZoneDragEntered, this),
ondragleave: L.bind(this.onDropZoneDragLeaved, this),
ondrop: L.bind(this.onDropZoneDropped, this),
ondropdeactivate: L.bind(this.onDropZoneDeactivated, this),
};
this._draggableMarkerOpts = {
inertia: false,
onmove: L.bind(this.onDraggableMove, this),
onend: L.bind(this.onDraggableEnd, this),
};
this._pegmanMarkerOpts = {
draggable: true,
icon: L.icon({
className: "pegman-marker",
iconSize: [52, 52],
iconAnchor: [26, 13],
iconUrl: 'data:image/png;base64,' + "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAFElEQVR4XgXAAQ0AAABAMP1L30IDCPwC/o5WcS4AAAAASUVORK5CYII=",
}),
};
},
this._pegmanMarkerOpts = {
draggable: true,
icon: L.icon({
className: "pegman-marker",
iconSize: [52, 52],
iconAnchor: [26, 13],
iconUrl: 'data:image/png;base64,' + "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAFElEQVR4XgXAAQ0AAABAMP1L30IDCPwC/o5WcS4AAAAASUVORK5CYII=",
}),
};
this._lazyLoaderAdded = false;
},
onAdd: function(map) {
this._map = map;
onAdd: function(map) {
this._map = map;
this._container = L.DomUtil.create('div', 'leaflet-pegman pegman-control leaflet-bar');
this._pegman = L.DomUtil.create('div', 'pegman draggable drag-drop', this._container);
this._pegmanButton = L.DomUtil.create('div', 'pegman-button', this._container);
this._pegmanMarker = L.marker([0, 0], this._pegmanMarkerOpts);
this._panoDiv = L.DomUtil.create('div', 'pano-canvas', this._map._container);
this._container = L.DomUtil.create('div', 'leaflet-pegman pegman-control leaflet-bar');
this._pegman = L.DomUtil.create('div', 'pegman draggable drag-drop', this._container);
this._pegmanButton = L.DomUtil.create('div', 'pegman-button', this._container);
this._pegmanMarker = L.marker([0, 0], this._pegmanMarkerOpts);
this._panoDiv = L.DomUtil.create('div', 'pano-canvas', this._map._container);
if (this.options.theme) {
L.DomUtil.addClass(this._map._container, this.options.theme);
}
L.DomUtil.addClass(this._map._container, this.options.theme);
/********************************************************/
/* Google maps */
if (this.options.clickableStreetViewLayer) {
// @link https://developers.google.com/terms/api-services-user-data-policy
// You SHOULD NOT USE UNDOCUMENTED APIs without google's express permission.
this._googleStreetViewLayer = L.tileLayer('https://{s}.googleapis.com/vt?lyrs=svv&style=40,18&x={x}&y={y}&z={z}', {
attribution: 'Map data: &copy; <a href="https://www.google.com/intl/en/help/terms_maps.html">Google</a>',
subdomains: ['mts1', 'mts2', 'mts3'],
pane: "overlayPane",
});
this._mouseTileTracker = new this.MouseTileTracker(this._map);
} else {
// @link https://gitlab.com/IvanSanchez/Leaflet.GridLayer.GoogleMutant
// GoogleMutant SHOULD PROVIDE a ToS compliant way of loading Google Map's tiles into Leaflet
this._googleStreetViewLayer = L.gridLayer.googleMutant({
attribution: 'Map data: &copy; <a href="https://www.google.com/intl/en/help/terms_maps.html">Google</a>',
pane: "overlayPane",
//type: null, // (illegal?) workaround used to force a transparent background using null maptype_id
type: "roadmap",
styles: [{
"stylers": [{
"visibility": "off"
}]
}]
});
this._googleStreetViewLayer.addGoogleLayer('StreetViewCoverageLayer');
}
L.DomEvent.disableClickPropagation(this._panoDiv);
L.DomEvent.on(this._container, 'click mousedown touchstart dblclick', this._disableClickPropagation, this);
this._panorama = new google.maps.StreetViewPanorama(this._panoDiv, {
enableCloseButton: true,
});
this._container.addEventListener('mousedown', this._loadScripts.bind(this, true), false);
this._container.addEventListener('mouseover', this._loadScripts.bind(this, false), false);
this._streetViewService = new google.maps.StreetViewService();
this._loadInteractHandlers();
this._loadGoogleHandlers();
/* ******************************************************* */
L.DomEvent.on(document, 'mousemove', this.mouseMoveTracking, this);
L.DomEvent.on(document, 'keyup', this.keyUpTracking, this);
// Enable Draggable Element to be Dropped into Map Container
this._draggable = interact(this._pegman).draggable(this._draggableMarkerOpts);
this._dropzone = interact(this._map._container).dropzone(this._dropzoneMapOpts);
this._pegmanMarker.on("dragend", this.onPegmanMarkerDragged, this);
this._map.on("click", this.onMapClick, this);
this._map.on("layeradd", this.onMapLayerAdd, this);
this._draggable.styleCursor(false);
return this._container;
},
// Toggle on/off SV Layer on Pegman's Container single clicks
interact(this._container).on("tap", L.bind(this.toggleStreetViewLayer, this));
onRemove: function(map) {
this._googleStreetViewLayer.remove();
this._pegmanMarker.remove();
// Disable "mousedown touchstart dblclick" events
L.DomEvent.disableClickPropagation(this._container);
L.DomEvent.disableClickPropagation(this._panoDiv);
L.DomUtil.remove(this._panoDiv);
/* ******************************************************* */
L.DomEvent.off(document, 'mousemove', this.mouseMoveTracking, this);
L.DomEvent.off(document, 'keyup', this.keyUpTracking, this);
},
L.DomEvent.on(document, 'mousemove', this.mouseMoveTracking, this);
L.DomEvent.on(document, 'keyup', this.keyUpTracking, this);
/* ******************************************************* */
this._pegmanMarker.on("dragend", this.onPegmanMarkerDragged, this);
this._map.on("click", this.onMapClick, this);
this._map.on("layeradd", this.onMapLayerAdd, this);
_log: function(args) {
if (this.options.logging) {
console.log(args);
}
},
google.maps.event.addListener(this._panorama, 'closeclick', L.bind(this.onStreetViewPanoramaClose, this));
_addClasses: function(el, classNames) {
classNames = classNames.split(" ");
for (var s in classNames) {
L.DomUtil.addClass(el, classNames[s]);
}
},
return this._container;
},
_removeClasses: function(el, classNames) {
classNames = classNames.split(" ");
for (var s in classNames) {
L.DomUtil.removeClass(el, classNames[s]);
}
},
onRemove: function(map) {
this._googleStreetViewLayer.remove();
this._pegmanMarker.remove()
_removeAttributes: function(el, attrNames) {
for (var a in attrNames) {
el.removeAttribute(attrNames[a]);
}
},
L.DomUtil.remove(this._panoDiv);
_insertAfter: function(targetNode, newNode) {
targetNode.parentNode.insertBefore(newNode, targetNode.nextSibling);
},
L.DomEvent.off(document, 'mousemove', this.mouseMoveTracking, this);
L.DomEvent.off(document, 'keyup', this.keyUpTracking, this);
},
_translateElement: function(el, dx, dy) {
if (dx === false && dy === false) {
this._removeAttributes(this._pegman, ["style", "data-x", "data-y"]);
}
// Element's position is preserved within the data-x/data-y attributes
var x = (parseFloat(el.getAttribute('data-x')) || 0) + dx;
var y = (parseFloat(el.getAttribute('data-y')) || 0) + dy;
/* ******************************************************* */
// Translate element
el.style.webkitTransform = el.style.transform = 'translate(' + x + 'px, ' + y + 'px)';
_log: function(args) {
if (this.options.logging) {
console.log(args);
}
},
// Update position attributes
el.setAttribute('data-x', x);
el.setAttribute('data-y', y);
},
_addClasses: function(el, classNames) {
var classNames = classNames.split(" ");
for (var s in classNames) {
L.DomUtil.addClass(el, classNames[s]);
}
},
_updateClasses: function(action) {
switch (action) {
case "pegman-dragging":
this._removeClasses(this._pegman, "dropped");
this._addClasses(this._container, "dragging");
break;
case "pegman-dragged":
this._removeClasses(this._pegman, "can-drop dragged left right active dropped");
this._removeAttributes(this._pegman, ["style", "data-x", "data-y"]);
break;
case "dropzone-actived":
this._addClasses(this._map._container, "drop-active");
break;
case "dropzone-drag-entered":
this._addClasses(this._pegman, "active can-drop");
this._addClasses(this._map._container, "drop-target");
break;
case "dropzone-drag-leaved":
this._removeClasses(this._map._container, "drop-target");
this._removeClasses(this._pegman, "can-drop");
break;
case "dropzone-drop":
this._removeClasses(this._container, "dragging");
this._removeClasses(this._pegman, "active left right");
this._addClasses(this._pegman, "dropped");
this._removeClasses(this._pegman, "can-drop dragged left right active dropped");
break;
case "dropzone-deactivated":
this._removeClasses(this._pegman, "active left right");
this._removeClasses(this._map._container, "drop-active drop-target");
break;
case "mousemove-top":
this._addClasses(this._pegman, "top");
this._removeClasses(this._pegman, "bottom right left");
break;
case "mousemove-bottom":
this._addClasses(this._pegman, "bottom");
this._removeClasses(this._pegman, "top right left");
break;
case "mousemove-left":
this._addClasses(this._pegman, "left");
this._removeClasses(this._pegman, "right top bottom");
break;
case "mousemove-right":
this._addClasses(this._pegman, "right");
this._removeClasses(this._pegman, "left top bottom");
break;
case "pegman-added":
this._addClasses(this._container, "active");
break;
case "pegman-removed":
this._removeClasses(this._container, "active");
break;
case "streetview-shown":
this._addClasses(this._container, "streetview-layer-active");
break;
case "streetview-hidden":
this._removeClasses(this._container, "streetview-layer-active");
break;
default:
throw "Unhandled event:" + action;
}
this._log(action);
this.fireEvent("svpc_" + action);
},
_removeClasses: function(el, classNames) {
var classNames = classNames.split(" ");
for (var s in classNames) {
L.DomUtil.removeClass(el, classNames[s]);
}
},
/* ******************************************************* */
_removeAttributes: function(el, attrNames) {
for (var a in attrNames) {
el.removeAttribute(attrNames[a]);
}
},
onDraggableMove: function(e) {
this.mouseMoveTracking(e);
this._updateClasses("pegman-dragging");
this._translateElement(this._pegman, e.dx, e.dy);
},
_insertAfter: function(targetNode, newNode) {
targetNode.parentNode.insertBefore(newNode, targetNode.nextSibling);
},
onDraggableEnd: function(e) {
this._pegmanMarkerCoords = this._map.mouseEventToLatLng(e);
this.pegmanAdd();
this._updateClasses("pegman-dragged");
},
_translateElement: function(el, dx, dy) {
if (dx === false && dy === false) {
this._removeAttributes(this._pegman, ["style", "data-x", "data-y"]);
}
// Element's position is preserved within the data-x/data-y attributes
var x = (parseFloat(el.getAttribute('data-x')) || 0) + dx;
var y = (parseFloat(el.getAttribute('data-y')) || 0) + dy;
onDropZoneActivated: function(e) {
this._updateClasses("dropzone-actived");
},
// Translate element
el.style.webkitTransform = el.style.transform = 'translate(' + x + 'px, ' + y + 'px)';
onDropZoneDragEntered: function(e) {
this.showStreetViewLayer();
this._updateClasses("dropzone-drag-entered");
},
// Update position attributes
el.setAttribute('data-x', x);
el.setAttribute('data-y', y);
},
onDropZoneDragLeaved: function(e) {
this._updateClasses("dropzone-drag-leaved");
},
_updateClasses: function(action) {
switch (action) {
case "pegman-dragging":
this._removeClasses(this._pegman, "dropped");
this._addClasses(this._container, "dragging");
break;
case "pegman-dragged":
this._removeClasses(this._pegman, "can-drop dragged left right active dropped");
this._removeAttributes(this._pegman, ["style", "data-x", "data-y"]);
break;
case "dropzone-actived":
this._addClasses(this._map._container, "drop-active");
break;
case "dropzone-drag-entered":
this._addClasses(this._pegman, "active can-drop");
this._addClasses(this._map._container, "drop-target");
break;
case "dropzone-drag-leaved":
this._removeClasses(this._map._container, "drop-target");
this._removeClasses(this._pegman, "can-drop");
break;
case "dropzone-drop":
this._removeClasses(this._container, "dragging");
this._removeClasses(this._pegman, "active left right");
this._addClasses(this._pegman, "dropped");
this._removeClasses(this._pegman, "can-drop dragged left right active dropped");
break;
case "dropzone-deactivated":
this._removeClasses(this._pegman, "active left right");
this._removeClasses(this._map._container, "drop-active drop-target");
break;
case "mousemove-top":
this._addClasses(this._pegman, "top");
this._removeClasses(this._pegman, "bottom right left");
break;
case "mousemove-bottom":
this._addClasses(this._pegman, "bottom");
this._removeClasses(this._pegman, "top right left");
break;
case "mousemove-left":
this._addClasses(this._pegman, "left");
this._removeClasses(this._pegman, "right top bottom");
break;
case "mousemove-right":
this._addClasses(this._pegman, "right");
this._removeClasses(this._pegman, "left top bottom");
break;
case "pegman-added":
this._addClasses(this._container, "active");
break;
case "pegman-removed":
this._removeClasses(this._container, "active");
break;
case "streetview-shown":
this._addClasses(this._container, "streetview-layer-active");
break;
case "streetview-hidden":
this._removeClasses(this._container, "streetview-layer-active");
break;
default:
throw "Unhandled event:" + action;
return;
}
this._log(action);
this.fireEvent("svpc_" + action);
},
onDropZoneDropped: function(e) {
this._updateClasses("dropzone-drop");
this._translateElement(this._pegman, false, false);
},
/* ******************************************************* */
onDropZoneDeactivated: function(e) {
this._updateClasses("dropzone-deactivated");
},
onDraggableMove: function(e) {
this.mouseMoveTracking(e);
this._updateClasses("pegman-dragging");
this._translateElement(this._pegman, e.dx, e.dy);
},
onPegmanMarkerDragged: function(e) {
this._pegmanMarkerCoords = this._pegmanMarker.getLatLng();
this.findStreetViewData(this._pegmanMarkerCoords.lat, this._pegmanMarkerCoords.lng);
},
onDraggableEnd: function(e) {
this._pegmanMarkerCoords = this._map.mouseEventToLatLng(e);
this.pegmanAdd();
this._updateClasses("pegman-dragged");
},
onMapClick: function(e) {
if (this._streetViewLayerEnabled)
this.findStreetViewData(e.latlng.lat, e.latlng.lng);
},
onDropZoneActivated: function(e) {
this._updateClasses("dropzone-actived");
},
onMapLayerAdd: function(e) {
if (this._googleStreetViewLayer)
this._googleStreetViewLayer.bringToFront();
},
onDropZoneDragEntered: function(e) {
this.showStreetViewLayer();
this._updateClasses("dropzone-drag-entered");
},
onStreetViewPanoramaClose: function() {
this.clear();
},
onDropZoneDragLeaved: function(e) {
this._updateClasses("dropzone-drag-leaved");
},
/* ******************************************************* */
onDropZoneDropped: function(e) {
this._updateClasses("dropzone-drop");
this._translateElement(this._pegman, false, false);
},
clear: function() {
this.pegmanRemove();
this.hideStreetViewLayer();
this.closeStreetViewPanorama();
},
onDropZoneDeactivated: function(e) {
this._updateClasses("dropzone-deactivated");
},
toggleStreetViewLayer: function(e) {
if (this._streetViewLayerEnabled) this.clear();
else this.showStreetViewLayer();
},
onPegmanMarkerDragged: function(e) {
this._pegmanMarkerCoords = this._pegmanMarker.getLatLng();
this.findStreetViewData(this._pegmanMarkerCoords.lat, this._pegmanMarkerCoords.lng);
},
pegmanAdd: function() {
this._pegmanMarker.addTo(this._map);
this._pegmanMarker.setLatLng(this._pegmanMarkerCoords);
this.findStreetViewData(this._pegmanMarkerCoords.lat, this._pegmanMarkerCoords.lng);
this._updateClasses("pegman-added");
},
onMapClick: function(e) {
if (this._streetViewLayerEnabled)
this.findStreetViewData(e.latlng.lat, e.latlng.lng);
},
pegmanRemove: function() {
this._pegmanMarker.removeFrom(this._map);
this._updateClasses("pegman-removed");
},
onMapLayerAdd: function(e) {
this._googleStreetViewLayer.bringToFront();
},
/* ******************************************************* */
onStreetViewPanoramaClose: function() {
this.clear();
},
closeStreetViewPanorama: function() {
this._panoDiv.style.display = "none";
},
/* ******************************************************* */
openStreetViewPanorama: function() {
this._panoDiv.style.display = "block";
},
clear: function() {
this.pegmanRemove();
this.hideStreetViewLayer();
this.closeStreetViewPanorama();
},
hideStreetViewLayer: function() {
if (this._googleStreetViewLayer) {
this._googleStreetViewLayer.removeFrom(this._map);
this._streetViewLayerEnabled = false;
this._updateClasses("streetview-hidden");
}
},
toggleStreetViewLayer: function(e) {
this._streetViewLayerEnabled ? this.clear() : this.showStreetViewLayer();
},
showStreetViewLayer: function() {
if (this._googleStreetViewLayer) {
this._googleStreetViewLayer.addTo(this._map);
this._streetViewLayerEnabled = true;
this._updateClasses("streetview-shown");
}
},
pegmanAdd: function() {
this._pegmanMarker.addTo(this._map);
this._pegmanMarker.setLatLng(this._pegmanMarkerCoords);
this.findStreetViewData(this._pegmanMarkerCoords.lat, this._pegmanMarkerCoords.lng);
this._updateClasses("pegman-added");
},
findStreetViewData: function(lat, lng) {
this._streetViewCoords = new google.maps.LatLng(lat, lng);
var zoom = this._map.getZoom();
var searchRadius = 100;
pegmanRemove: function() {
this._pegmanMarker.removeFrom(this._map);
this._updateClasses("pegman-removed");
},
if (zoom < 6) searchRadius = 5000;
else if (zoom < 10) searchRadius = 500;
else if (zoom < 15) searchRadius = 250;
else if (zoom >= 17) searchRadius = 50;
else searchRadius = 100;
/* ******************************************************* */
this._streetViewService.getPanoramaByLocation(this._streetViewCoords, searchRadius, L.bind(this.processStreetViewServiceData, this));
},
closeStreetViewPanorama: function() {
this._panoDiv.style.display = "none";
},
processStreetViewServiceData: function(data, status) {
if (status == google.maps.StreetViewStatus.OK) {
this.openStreetViewPanorama();
this._panorama.setPano(data.location.pano);
this._panorama.setPov({
heading: google.maps.geometry.spherical.computeHeading(data.location.latLng, this._streetViewCoords),
pitch: 0,
zoom: 0
});
this._panorama.setVisible(true);
} else {
this._log("Street View data not found for this location.");
// this.clear(); // TODO: add a visual feedback when no SV data available
}
},
openStreetViewPanorama: function() {
this._panoDiv.style.display = "block";
},
/********************************************************/
hideStreetViewLayer: function() {
this._googleStreetViewLayer.removeFrom(this._map);
this._streetViewLayerEnabled = false;
this._updateClasses("streetview-hidden");
},
/**
* mouseMoveTracking
* @desc internal function used to style pegman while dragging
*/
mouseMoveTracking: function(e) {
var mousePos = this._mousePos;
showStreetViewLayer: function() {
this._googleStreetViewLayer.addTo(this._map);
this._streetViewLayerEnabled = true;
this._updateClasses("streetview-shown");
},
// Top <--> Bottom
if (e.pageY < mousePos.old.y) {
mousePos.direction.y = 'top';
this._updateClasses("mousemove-top");
} else if (e.pageY > mousePos.old.y) {
mousePos.direction.y = 'bottom';
this._updateClasses("mousemove-bottom");
}
// Left <--> Right
if (e.pageX < mousePos.old.x) {
mousePos.direction.x = 'left';
this._updateClasses("mousemove-left");
} else if (e.pageX > mousePos.old.x) {
mousePos.direction.x = 'right';
this._updateClasses("mousemove-right");
}
findStreetViewData: function(lat, lng) {
this._streetViewCoords = new google.maps.LatLng(lat, lng);
var zoom = this._map.getZoom();
var searchRadius = 100;
mousePos.old.x = e.pageX;
mousePos.old.y = e.pageY;
},
if (zoom < 6) searchRadius = 5000;
else if (zoom < 10) searchRadius = 500;
else if (zoom < 15) searchRadius = 250;
else if (zoom >= 17) searchRadius = 50;
else searchRadius = 100;
/**
* keyUpTracking
* @desc internal function used to track keyup events
*/
keyUpTracking: function(e) {
if (e.keyCode == 27) {
this._log('escape pressed');
this.clear();
}
},
this._streetViewService.getPanoramaByLocation(this._streetViewCoords, searchRadius, L.bind(this.processStreetViewServiceData, this));
},
/********************************************************/
processStreetViewServiceData: function(data, status) {
if (status == google.maps.StreetViewStatus.OK) {
this.openStreetViewPanorama();
this._panorama.setPano(data.location.pano);
this._panorama.setPov({
heading: google.maps.geometry.spherical.computeHeading(data.location.latLng, this._streetViewCoords),
pitch: 0,
zoom: 0
});
this._panorama.setVisible(true);
} else {
this._log("Street View data not found for this location.");
// this.clear(); // TODO: add a visual feedback when no SV data available
}
},
/**
* MouseTileTracker
* @desc internal class used to add cursor:"pointer" when hovering a semi-transparent tiled overlay
*
* TODO: code refactoring + add support for the GoogleMutant StreetView layer
*/
MouseTileTracker: function(map) {
/********************************************************/
var self = this;
/**
* mouseMoveTracking
* @desc internal function used to style pegman while dragging
*/
mouseMoveTracking: function(e) {
var mousePos = this._mousePos;
self._init = function(map) {
self.map = map;
self.mouse = {
pageX: 0,
pageY: 0
};
// Top <--> Bottom
if (e.pageY < mousePos.old.y) {
mousePos.direction.y = 'top';
this._updateClasses("mousemove-top");
} else if (e.pageY > mousePos.old.y) {
mousePos.direction.y = 'bottom';
this._updateClasses("mousemove-bottom");
}
// Left <--> Right
if (e.pageX < mousePos.old.x) {
mousePos.direction.x = 'left';
this._updateClasses("mousemove-left");
} else if (e.pageX > mousePos.old.x) {
mousePos.direction.x = 'right';
this._updateClasses("mousemove-right");
}
if (typeof(Number.prototype.toRad) === "undefined") {
Number.prototype.toRad = function() {
return this * Math.PI / 180;
};
}
mousePos.old.x = e.pageX;
mousePos.old.y = e.pageY;
},
self.defaultDraggableCursor = self.map._container.style.cursor;
/**
* keyUpTracking
* @desc internal function used to track keyup events
*/
keyUpTracking: function(e) {
if (e.keyCode == 27) {
this._log('escape pressed');
this.clear();
}
},
self.map._container.addEventListener('mousemove', self.onMapDivMouseMove);
self.map.on('mousemove', self.onMapMouseMove);
};
/********************************************************/
self.getTileURL = function(lat, lon, zoom) {
var xtile = parseInt(Math.floor((lon + 180) / 360 * (1 << zoom)));
var ytile = parseInt(Math.floor((1 - Math.log(Math.tan(lat.toRad()) + 1 / Math.cos(lat.toRad())) / Math.PI) / 2 * (1 << zoom)));
return {
x: xtile,
y: ytile,
z: zoom,
};
};
/**
* MouseTileTracker
* @desc internal class used to add cursor:"pointer" when hovering a semi-transparent tiled overlay
*
* TODO: code refactoring + add support for the GoogleMutant StreetView layer
*/
MouseTileTracker: function(map) {
self._startTracking = function(baseUrl, tileCoordinate, tileWidth, tileHeight, subdomain) {
subdomain = subdomain || null;
self.tileData = null;
self.downloadedTile = null;
self.tileCanvas = null;
self.tileSrc = "";
var self = this;
self.baseUrl = baseUrl;
self.tileCoordinate = tileCoordinate;
self.tileWidth = tileWidth;
self.tileHeight = tileHeight;
self._init = function(map) {
self.map = map;
self.mouse = {
pageX: 0,
pageY: 0
};
var protocolsRegex = /(^\w+:|^)\/\//; //eg. http://
var subdomainRegex = /.*\{s\}.*\./; //eg. mts{s}.
var cssSelectorSrc;
if (typeof(Number.prototype.toRad) === "undefined") {
Number.prototype.toRad = function() {
return this * Math.PI / 180;
}
}
self.tileSrc = self.baseUrl;
self.tileSrc = self.tileSrc.replace("{x}", self.tileCoordinate.x);
self.tileSrc = self.tileSrc.replace("{y}", self.tileCoordinate.y);
self.tileSrc = self.tileSrc.replace("{z}", self.map.getZoom());
self.defaultDraggableCursor = self.map._container.style.cursor;
cssSelectorSrc = self.tileSrc;
self.map._container.addEventListener('mousemove', self.onMapDivMouseMove);
self.map.on('mousemove', self.onMapMouseMove);
};
if (subdomain) {
self.tileSrc = self.tileSrc.replace("{s}", subdomain);
}
cssSelectorSrc = cssSelectorSrc.replace(protocolsRegex, '');
cssSelectorSrc = cssSelectorSrc.replace(subdomainRegex, '');
self.getTileURL = function(lat, lon, zoom) {
var xtile = parseInt(Math.floor((lon + 180) / 360 * (1 << zoom)));
var ytile = parseInt(Math.floor((1 - Math.log(Math.tan(lat.toRad()) + 1 / Math.cos(lat.toRad())) / Math.PI) / 2 * (1 << zoom)));
return {
x: xtile,
y: ytile,
z: zoom,
};
};
self.downloadTile(self.tileSrc);
self._startTracking = function(baseUrl, tileCoordinate, tileWidth, tileHeight, subdomain = null) {
self.tileData = null;
self.downloadedTile = null;
self.tileCanvas = null;
self.tileSrc = "";
if (!self.tileData) {
self.tileLoaded();
}
self.baseUrl = baseUrl;
self.tileCoordinate = tileCoordinate;
self.tileWidth = tileWidth;
self.tileHeight = tileHeight;
self.mapTile = document.querySelector('.leaflet-container img[src$="' + cssSelectorSrc + '"]');
var protocolsRegex = /(^\w+:|^)\/\//; //eg. http://
var subdomainRegex = /.*\{s\}.*\./; //eg. mts{s}.
var cssSelectorSrc;
if (!self.mapTile) return;
self.tileSrc = self.baseUrl;
self.tileSrc = self.tileSrc.replace("{x}", self.tileCoordinate.x);
self.tileSrc = self.tileSrc.replace("{y}", self.tileCoordinate.y);
self.tileSrc = self.tileSrc.replace("{z}", self.map.getZoom());
self.rect = self.mapTile.getBoundingClientRect();
cssSelectorSrc = self.tileSrc;
self.imgPos = {
top: (self.rect.top + window.scrollY).toFixed(0),
left: (self.rect.left + window.scrollX).toFixed(0)
};
self.mousePos = {
x: self.mouse.pageX - self.imgPos.left,
y: self.mouse.pageY - self.imgPos.top
};
if (subdomain) {
self.tileSrc = self.tileSrc.replace("{s}", subdomain);
}
cssSelectorSrc = cssSelectorSrc.replace(protocolsRegex, '');
cssSelectorSrc = cssSelectorSrc.replace(subdomainRegex, '');
self.pixelData = self.tileCanvas.getContext('2d').getImageData(self.mousePos.x, self.mousePos.y, 1, 1).data;
self.alpha = self.pixelData[3];
self.downloadTile(self.tileSrc);
self.hasTileData = (self.alpha != 0);
};
if (!self.tileData) {
self.tileLoaded();
}
self.downloadTile = function(imageSrc) {
self.downloadedTile = new Image();
self.downloadedTile.crossOrigin = "Anonymous";
self.downloadedTile.addEventListener("load", self.tileLoaded, false);
self.downloadedTile.src = imageSrc;
};
self.mapTile = document.querySelector('.leaflet-container img[src$="' + cssSelectorSrc + '"]');
self.tileLoaded = function() {
self.tileCanvas = document.createElement("canvas");
self.context = self.tileCanvas.getContext("2d");
if (!self.mapTile) return;
self.tileCanvas.width = self.tileWidth;
self.tileCanvas.height = self.tileHeight;
self.rect = self.mapTile.getBoundingClientRect();
self.context.drawImage(self.downloadedTile, 0, 0);
self.imgPos = {
top: (self.rect.top + window.scrollY).toFixed(0),
left: (self.rect.left + window.scrollX).toFixed(0)
};
self.mousePos = {
x: self.mouse.pageX - self.imgPos.left,
y: self.mouse.pageY - self.imgPos.top
};
self.tileData = self.context.getImageData(0, 0, self.tileWidth, self.tileHeight);
};
self.pixelData = self.tileCanvas.getContext('2d').getImageData(self.mousePos.x, self.mousePos.y, 1, 1).data;
self.alpha = self.pixelData[3];
self.onMapDivMouseMove = function(e) {
self.mouse.pageX = e.pageX;
self.mouse.pageY = e.pageY;
};
self.hasTileData = (self.alpha != 0);
};
self.onMapMouseMove = function(mev) {
var TILE_SIZE = 256;
var tileCoordinate = self.getTileURL(mev.latlng.lat, mev.latlng.lng, self.map.getZoom());
var toggledOverlays = self.map._layers;
var mouseTracker, hasTileData = false;
var subdomain;
self.downloadTile = function(imageSrc) {
self.downloadedTile = new Image();
self.downloadedTile.crossOrigin = "Anonymous";
self.downloadedTile.addEventListener("load", self.tileLoaded, false);
self.downloadedTile.src = imageSrc;
};
for (var i in toggledOverlays) {
var layer = toggledOverlays[i];
if (!layer._url || layer._url.indexOf("google") < 0) { //Some sort of whitelist of pointable layers
continue;
}
if (layer.options && layer.options.subdomains && layer.options.subdomains[0]) {
subdomain = layer.options.subdomains[0];
} else {
subdomain = null;
}
self._startTracking(layer._url, tileCoordinate, TILE_SIZE, TILE_SIZE, subdomain);
if (self.hasTileData) {
hasTileData = true;
}
}
self.tileLoaded = function() {
self.tileCanvas = document.createElement("canvas");
self.context = self.tileCanvas.getContext("2d");
self.map._container.style.cursor = hasTileData ? 'pointer' : self.defaultDraggableCursor;
};
self.tileCanvas.width = self.tileWidth;
self.tileCanvas.height = self.tileHeight;
self._init(map);
},
self.context.drawImage(self.downloadedTile, 0, 0);
_disableClickPropagation: function(e) {
L.DomEvent.stopPropagation(e);
L.DomEvent.preventDefault(e);
},
self.tileData = self.context.getImageData(0, 0, self.tileWidth, self.tileHeight);
};
_loadGoogleHandlers: function() {
if (typeof google !== 'object' || typeof google.maps !== 'object') return;
var attribution = 'Map data: &copy; <a href="https://www.google.com/intl/en/help/terms_maps.html">Google</a>';
var pane = "overlayPane";
if (this.options.clickableStreetViewLayer) {
// You SHOULD NOT USE UNDOCUMENTED APIs without google's express permission.
// @link https://developers.google.com/terms/api-services-user-data-policy
this._googleStreetViewLayer = L.tileLayer('https://{s}.googleapis.com/vt?lyrs=svv&style=40,18&x={x}&y={y}&z={z}', {
attribution: attribution,
pane: pane,
subdomains: ['mts1', 'mts2', 'mts3'],
});
this._mouseTileTracker = new this.MouseTileTracker(this._map);
} else {
// GoogleMutant SHOULD PROVIDE a ToS compliant way of loading Google Map's tiles into Leaflet
// @link https://gitlab.com/IvanSanchez/Leaflet.GridLayer.GoogleMutant
this._googleStreetViewLayer = L.gridLayer.googleMutant({
attribution: attribution,
pane: pane,
//type: null, // (legal?) workaround used to force a transparent background using null maptype_id
type: "roadmap",
styles: [{
"stylers": [{
"visibility": "off"
}]
}]
});
this._googleStreetViewLayer.addGoogleLayer('StreetViewCoverageLayer');
}
self.onMapDivMouseMove = function(e) {
self.mouse.pageX = e.pageX;
self.mouse.pageY = e.pageY;
};
this._panorama = new google.maps.StreetViewPanorama(this._panoDiv, {
enableCloseButton: true,
});
this._streetViewService = new google.maps.StreetViewService();
self.onMapMouseMove = function(mev) {
var TILE_SIZE = 256;
var tileCoordinate = self.getTileURL(mev.latlng.lat, mev.latlng.lng, self.map.getZoom());
var toggledOverlays = self.map._layers;
var mouseTracker, hasTileData = false;
var subdomain;
var layer;
google.maps.event.addListener(this._panorama, 'closeclick', L.bind(this.onStreetViewPanoramaClose, this));
for (var i in toggledOverlays) {
var layer = toggledOverlays[i];
if (!layer._url || layer._url.indexOf("google") < 0) { //Some sort of whitelist of pointable layers
continue;
}
if (layer.options && layer.options.subdomains && layer.options.subdomains[0]) {
subdomain = layer.options.subdomains[0];
} else {
subdomain = null;
}
self._startTracking(layer._url, tileCoordinate, TILE_SIZE, TILE_SIZE, subdomain);
if (self.hasTileData) {
hasTileData = true;
}
}
},
self.map._container.style.cursor = hasTileData ? 'pointer' : self.defaultDraggableCursor;
};
_loadInteractHandlers: function() {
if (typeof interact !== 'function') return;
// Enable Draggable Element to be Dropped into Map Container
this._draggable = interact(this._pegman).draggable(this._draggableMarkerOpts);
this._dropzone = interact(this._map._container).dropzone(this._dropzoneMapOpts);
self._init(map);
},
this._draggable.styleCursor(false);
// Toggle on/off SV Layer on Pegman's Container single clicks
interact(this._container).on("tap", L.bind(this.toggleStreetViewLayer, this));
},
_loadScripts: function(toggleStreetView) {
if (this._lazyLoaderAdded) return;
this._lazyLoaderAdded = true;
if (typeof interact !== 'function') {
var i_url = 'https://cdnjs.cloudflare.com/ajax/libs/interact.js/1.2.9/interact.min.js';
this._loadJS(i_url, function() {
this._log("interact.js loaded");
this._loadInteractHandlers();
}.bind(this));
}
if (typeof google !== 'object' || typeof google.maps !== 'object') {
var apiKey = this.options.apiKey || '';
var libraries = this.options.libraries || ''; //places,drawing,geometry
var g_url = 'https://maps.googleapis.com/maps/api/js?v=3' /*.exp*/ +
'&key=' + apiKey +
'&libraries=' + libraries +
'&callback=?';
this._loadJS(g_url, function() {
this._log("gmaps.js loaded");
this._loadGoogleHandlers();
if (toggleStreetView) {
this.toggleStreetViewLayer();
}
}.bind(this));
}
},
_loadJS: function(url, callback) {
if (url.indexOf('callback=?') !== -1) {
this._jsonp(url, callback);
} else {
var script = document.createElement('script');
script.src = url;
script.onload = script.onreadystatechange = callback;
var head = document.head || document.getElementsByTagName('head')[0] || document.documentElement;
head.insertBefore(script, head.firstChild);
}
},
_jsonp: function(url, callback, params) {
var query = url.indexOf('?') === -1 ? '?' : '&';
params = params || {};
for (var key in params) {
if (params.hasOwnProperty(key)) {
query += encodeURIComponent(key) + '=' + encodeURIComponent(params[key]) + '&';
}
}
var timestamp = new Date().getUTCMilliseconds();
var jsonp = "json_call_" + timestamp; // uniqueId('json_call');
window[jsonp] = function(data) {
callback(data);
window[jsonp] = undefined;
};
var script = document.createElement('script');
if (url.indexOf('callback=?') !== -1) {
script.src = url.replace('callback=?', 'callback=' + jsonp) + query.slice(0, -1);
} else {
script.src = url + query + 'callback=' + jsonp;
}
script.async = true;
script.onload = script.onreadystatechange = function() {
if (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete') {
script.onload = script.onreadystatechange = null;
if (script && script.parentNode) {
script.parentNode.removeChild(script);
}
}
};
var head = document.head || document.getElementsByTagName('head')[0] || document.documentElement;
// Use insertBefore instead of appendChild to circumvent an IE6 bug.
// This arises when a base node is used.
head.insertBefore(script, head.firstChild);
},
});
L.control.pegman = function(options) {
return new L.Control.Pegman(options);
return new L.Control.Pegman(options);
};
{
"name": "leaflet-pegman",
"version": "0.0.6",
"version": "0.0.7",
"description": "A Leaflet plugin that allows easy integration with the Google StreetView Service API",

@@ -5,0 +5,0 @@ "main": "leaflet-pegman.js",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc