【js文件】谷歌地图 markerclusterer.js

谷歌地图,点聚合,所使用的js


function MarkerClusterer(map, opt_markers, opt_options) {this.extend(MarkerClusterer, google.maps.OverlayView);this.map_ = map;/*** @type {Array.<google.maps.Marker>}* @private*/this.markers_ = [];/***  @type {Array.<Cluster>}*/this.clusters_ = [];this.sizes = [53, 56, 66, 78, 90];/*** @private*/this.styles_ = [];/*** @type {boolean}* @private*/this.ready_ = false;var options = opt_options || {};/*** @type {number}* @private*/this.gridSize_ = options['gridSize'] || 60;/*** @private*/this.minClusterSize_ = options['minimumClusterSize'] || 2;/*** @type {?number}* @private*/this.maxZoom_ = options['maxZoom'] || null;this.styles_ = options['styles'] || [];/*** @type {string}* @private*/this.imagePath_ = options['imagePath'] ||this.MARKER_CLUSTER_IMAGE_PATH_;/*** @type {string}* @private*/this.imageExtension_ = options['imageExtension'] ||this.MARKER_CLUSTER_IMAGE_EXTENSION_;/*** @type {boolean}* @private*/this.zoomOnClick_ = true;if (options['zoomOnClick'] != undefined) {this.zoomOnClick_ = options['zoomOnClick'];}/*** @type {boolean}* @private*/this.averageCenter_ = false;if (options['averageCenter'] != undefined) {this.averageCenter_ = options['averageCenter'];}this.setupStyles_();this.setMap(map);/*** @type {number}* @private*/this.prevZoom_ = this.map_.getZoom();// Add the map event listenersvar that = this;google.maps.event.addListener(this.map_, 'zoom_changed', function() {// Determines map type and prevent illegal zoom levelsvar zoom = that.map_.getZoom();var minZoom = that.map_.minZoom || 0;var maxZoom = Math.min(that.map_.maxZoom || 100,that.map_.mapTypes[that.map_.getMapTypeId()].maxZoom);zoom = Math.min(Math.max(zoom,minZoom),maxZoom);if (that.prevZoom_ != zoom) {that.prevZoom_ = zoom;that.resetViewport();}});google.maps.event.addListener(this.map_, 'idle', function() {that.redraw();});// Finally, add the markersif (opt_markers && (opt_markers.length || Object.keys(opt_markers).length)) {this.addMarkers(opt_markers, false);}
}/*** The marker cluster image path.** @type {string}* @private*/
MarkerClusterer.prototype.MARKER_CLUSTER_IMAGE_PATH_ = '../images/m';/*** The marker cluster image path.** @type {string}* @private*/
MarkerClusterer.prototype.MARKER_CLUSTER_IMAGE_EXTENSION_ = 'png';/*** Extends a objects prototype by anothers.** @param {Object} obj1 The object to be extended.* @param {Object} obj2 The object to extend with.* @return {Object} The new extended object.* @ignore*/
MarkerClusterer.prototype.extend = function(obj1, obj2) {return (function(object) {for (var property in object.prototype) {this.prototype[property] = object.prototype[property];}return this;}).apply(obj1, [obj2]);
};/*** Implementaion of the interface method.* @ignore*/
MarkerClusterer.prototype.onAdd = function() {this.setReady_(true);
};/*** Implementaion of the interface method.* @ignore*/
MarkerClusterer.prototype.draw = function() {};/*** Sets up the styles object.** @private*/
MarkerClusterer.prototype.setupStyles_ = function() {if (this.styles_.length) {return;}for (var i = 0, size; size = this.sizes[i]; i++) {this.styles_.push({url: this.imagePath_ + (i + 1) + '.' + this.imageExtension_,height: size,width: size});}
};/***  Fit the map to the bounds of the markers in the clusterer.*/
MarkerClusterer.prototype.fitMapToMarkers = function() {var markers = this.getMarkers();var bounds = new google.maps.LatLngBounds();for (var i = 0, marker; marker = markers[i]; i++) {bounds.extend(marker.getPosition());}this.map_.fitBounds(bounds);
};/***  Sets the styles.**  @param {Object} styles The style to set.*/
MarkerClusterer.prototype.setStyles = function(styles) {this.styles_ = styles;
};/***  Gets the styles.**  @return {Object} The styles object.*/
MarkerClusterer.prototype.getStyles = function() {return this.styles_;
};/*** Whether zoom on click is set.** @return {boolean} True if zoomOnClick_ is set.*/
MarkerClusterer.prototype.isZoomOnClick = function() {return this.zoomOnClick_;
};/*** Whether average center is set.** @return {boolean} True if averageCenter_ is set.*/
MarkerClusterer.prototype.isAverageCenter = function() {return this.averageCenter_;
};/***  Returns the array of markers in the clusterer.**  @return {Array.<google.maps.Marker>} The markers.*/
MarkerClusterer.prototype.getMarkers = function() {return this.markers_;
};/***  Returns the number of markers in the clusterer**  @return {Number} The number of markers.*/
MarkerClusterer.prototype.getTotalMarkers = function() {return this.markers_.length;
};/***  Sets the max zoom for the clusterer.**  @param {number} maxZoom The max zoom level.*/
MarkerClusterer.prototype.setMaxZoom = function(maxZoom) {this.maxZoom_ = maxZoom;
};/***  Gets the max zoom for the clusterer.**  @return {number} The max zoom level.*/
MarkerClusterer.prototype.getMaxZoom = function() {return this.maxZoom_;
};/***  The function for calculating the cluster icon image.**  @param {Array.<google.maps.Marker>} markers The markers in the clusterer.*  @param {number} numStyles The number of styles available.*  @return {Object} A object properties: 'text' (string) and 'index' (number).*  @private*/
MarkerClusterer.prototype.calculator_ = function(markers, numStyles) {var index = 0;var count = markers.length;var dv = count;while (dv !== 0) {dv = parseInt(dv / 10, 10);index++;}index = Math.min(index, numStyles);return {text: count,index: index};
};/*** Set the calculator function.** @param {function(Array, number)} calculator The function to set as the*     calculator. The function should return a object properties:*     'text' (string) and 'index' (number).**/
MarkerClusterer.prototype.setCalculator = function(calculator) {this.calculator_ = calculator;
};/*** Get the calculator function.** @return {function(Array, number)} the calculator function.*/
MarkerClusterer.prototype.getCalculator = function() {return this.calculator_;
};/*** Add an array of markers to the clusterer.** @param {Array.<google.maps.Marker>} markers The markers to add.* @param {boolean=} opt_nodraw Whether to redraw the clusters.*/
MarkerClusterer.prototype.addMarkers = function(markers, opt_nodraw) {if (markers.length) {for (var i = 0, marker; marker = markers[i]; i++) {this.pushMarkerTo_(marker);}} else if (Object.keys(markers).length) {for (var marker in markers) {this.pushMarkerTo_(markers[marker]);}}if (!opt_nodraw) {this.redraw();}
};/*** Pushes a marker to the clusterer.** @param {google.maps.Marker} marker The marker to add.* @private*/
MarkerClusterer.prototype.pushMarkerTo_ = function(marker) {marker.isAdded = false;if (marker['draggable']) {// If the marker is draggable add a listener so we update the clusters on// the drag end.var that = this;google.maps.event.addListener(marker, 'dragend', function() {marker.isAdded = false;that.repaint();});}this.markers_.push(marker);
};/*** Adds a marker to the clusterer and redraws if needed.** @param {google.maps.Marker} marker The marker to add.* @param {boolean=} opt_nodraw Whether to redraw the clusters.*/
MarkerClusterer.prototype.addMarker = function(marker, opt_nodraw) {this.pushMarkerTo_(marker);if (!opt_nodraw) {this.redraw();}
};/*** Removes a marker and returns true if removed, false if not** @param {google.maps.Marker} marker The marker to remove* @return {boolean} Whether the marker was removed or not* @private*/
MarkerClusterer.prototype.removeMarker_ = function(marker) {var index = -1;if (this.markers_.indexOf) {index = this.markers_.indexOf(marker);} else {for (var i = 0, m; m = this.markers_[i]; i++) {if (m == marker) {index = i;break;}}}if (index == -1) {// Marker is not in our list of markers.return false;}marker.setMap(null);this.markers_.splice(index, 1);return true;
};/*** Remove a marker from the cluster.** @param {google.maps.Marker} marker The marker to remove.* @param {boolean=} opt_nodraw Optional boolean to force no redraw.* @return {boolean} True if the marker was removed.*/
MarkerClusterer.prototype.removeMarker = function(marker, opt_nodraw) {var removed = this.removeMarker_(marker);if (!opt_nodraw && removed) {this.resetViewport();this.redraw();return true;} else {return false;}
};/*** Removes an array of markers from the cluster.** @param {Array.<google.maps.Marker>} markers The markers to remove.* @param {boolean=} opt_nodraw Optional boolean to force no redraw.*/
MarkerClusterer.prototype.removeMarkers = function(markers, opt_nodraw) {var removed = false;for (var i = 0, marker; marker = markers[i]; i++) {var r = this.removeMarker_(marker);removed = removed || r;}if (!opt_nodraw && removed) {this.resetViewport();this.redraw();return true;}
};/*** Sets the clusterer's ready state.** @param {boolean} ready The state.* @private*/
MarkerClusterer.prototype.setReady_ = function(ready) {if (!this.ready_) {this.ready_ = ready;this.createClusters_();}
};/*** Returns the number of clusters in the clusterer.** @return {number} The number of clusters.*/
MarkerClusterer.prototype.getTotalClusters = function() {return this.clusters_.length;
};/*** Returns the google map that the clusterer is associated with.** @return {google.maps.Map} The map.*/
MarkerClusterer.prototype.getMap = function() {return this.map_;
};/*** Sets the google map that the clusterer is associated with.** @param {google.maps.Map} map The map.*/
MarkerClusterer.prototype.setMap = function(map) {this.map_ = map;
};/*** Returns the size of the grid.** @return {number} The grid size.*/
MarkerClusterer.prototype.getGridSize = function() {return this.gridSize_;
};/*** Sets the size of the grid.** @param {number} size The grid size.*/
MarkerClusterer.prototype.setGridSize = function(size) {this.gridSize_ = size;
};/*** Returns the min cluster size.** @return {number} The grid size.*/
MarkerClusterer.prototype.getMinClusterSize = function() {return this.minClusterSize_;
};/*** Sets the min cluster size.** @param {number} size The grid size.*/
MarkerClusterer.prototype.setMinClusterSize = function(size) {this.minClusterSize_ = size;
};/*** Extends a bounds object by the grid size.** @param {google.maps.LatLngBounds} bounds The bounds to extend.* @return {google.maps.LatLngBounds} The extended bounds.*/
MarkerClusterer.prototype.getExtendedBounds = function(bounds) {var projection = this.getProjection();// Turn the bounds into latlng.var tr = new google.maps.LatLng(bounds.getNorthEast().lat(),bounds.getNorthEast().lng());var bl = new google.maps.LatLng(bounds.getSouthWest().lat(),bounds.getSouthWest().lng());// Convert the points to pixels and the extend out by the grid size.var trPix = projection.fromLatLngToDivPixel(tr);trPix.x += this.gridSize_;trPix.y -= this.gridSize_;var blPix = projection.fromLatLngToDivPixel(bl);blPix.x -= this.gridSize_;blPix.y += this.gridSize_;// Convert the pixel points back to LatLngvar ne = projection.fromDivPixelToLatLng(trPix);var sw = projection.fromDivPixelToLatLng(blPix);// Extend the bounds to contain the new bounds.bounds.extend(ne);bounds.extend(sw);return bounds;
};/*** Determins if a marker is contained in a bounds.** @param {google.maps.Marker} marker The marker to check.* @param {google.maps.LatLngBounds} bounds The bounds to check against.* @return {boolean} True if the marker is in the bounds.* @private*/
MarkerClusterer.prototype.isMarkerInBounds_ = function(marker, bounds) {return bounds.contains(marker.getPosition());
};/*** Clears all clusters and markers from the clusterer.*/
MarkerClusterer.prototype.clearMarkers = function() {this.resetViewport(true);// Set the markers a empty array.this.markers_ = [];
};/*** Clears all existing clusters and recreates them.* @param {boolean} opt_hide To also hide the marker.*/
MarkerClusterer.prototype.resetViewport = function(opt_hide) {// Remove all the clustersfor (var i = 0, cluster; cluster = this.clusters_[i]; i++) {cluster.remove();}// Reset the markers to not be added and to be invisible.for (var i = 0, marker; marker = this.markers_[i]; i++) {marker.isAdded = false;if (opt_hide) {marker.setMap(null);}}this.clusters_ = [];
};/****/
MarkerClusterer.prototype.repaint = function() {var oldClusters = this.clusters_.slice();this.clusters_.length = 0;this.resetViewport();this.redraw();// Remove the old clusters.// Do it in a timeout so the other clusters have been drawn first.window.setTimeout(function() {for (var i = 0, cluster; cluster = oldClusters[i]; i++) {cluster.remove();}}, 0);
};/*** Redraws the clusters.*/
MarkerClusterer.prototype.redraw = function() {this.createClusters_();
};/*** Calculates the distance between two latlng locations in km.* @see http://www.movable-type.co.uk/scripts/latlong.html** @param {google.maps.LatLng} p1 The first lat lng point.* @param {google.maps.LatLng} p2 The second lat lng point.* @return {number} The distance between the two points in km.* @private
*/
MarkerClusterer.prototype.distanceBetweenPoints_ = function(p1, p2) {if (!p1 || !p2) {return 0;}var R = 6371; // Radius of the Earth in kmvar dLat = (p2.lat() - p1.lat()) * Math.PI / 180;var dLon = (p2.lng() - p1.lng()) * Math.PI / 180;var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +Math.cos(p1.lat() * Math.PI / 180) * Math.cos(p2.lat() * Math.PI / 180) *Math.sin(dLon / 2) * Math.sin(dLon / 2);var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));var d = R * c;return d;
};/*** Add a marker to a cluster, or creates a new cluster.** @param {google.maps.Marker} marker The marker to add.* @private*/
MarkerClusterer.prototype.addToClosestCluster_ = function(marker) {var distance = 40000; // Some large numbervar clusterToAddTo = null;var pos = marker.getPosition();for (var i = 0, cluster; cluster = this.clusters_[i]; i++) {var center = cluster.getCenter();if (center) {var d = this.distanceBetweenPoints_(center, marker.getPosition());if (d < distance) {distance = d;clusterToAddTo = cluster;}}}if (clusterToAddTo && clusterToAddTo.isMarkerInClusterBounds(marker)) {clusterToAddTo.addMarker(marker);} else {var cluster = new Cluster(this);cluster.addMarker(marker);this.clusters_.push(cluster);}
};/*** Creates the clusters.** @private*/
MarkerClusterer.prototype.createClusters_ = function() {if (!this.ready_) {return;}// Get our current map view bounds.// Create a new bounds object so we don't affect the map.var mapBounds = new google.maps.LatLngBounds(this.map_.getBounds().getSouthWest(),this.map_.getBounds().getNorthEast());var bounds = this.getExtendedBounds(mapBounds);for (var i = 0, marker; marker = this.markers_[i]; i++) {if (!marker.isAdded && this.isMarkerInBounds_(marker, bounds)) {this.addToClosestCluster_(marker);}}
};/*** A cluster that contains markers.** @param {MarkerClusterer} markerClusterer The markerclusterer that this*     cluster is associated with.* @constructor* @ignore*/
function Cluster(markerClusterer) {this.markerClusterer_ = markerClusterer;this.map_ = markerClusterer.getMap();this.gridSize_ = markerClusterer.getGridSize();this.minClusterSize_ = markerClusterer.getMinClusterSize();this.averageCenter_ = markerClusterer.isAverageCenter();this.center_ = null;this.markers_ = [];this.bounds_ = null;this.clusterIcon_ = new ClusterIcon(this, markerClusterer.getStyles(),markerClusterer.getGridSize());
}/*** Determins if a marker is already added to the cluster.** @param {google.maps.Marker} marker The marker to check.* @return {boolean} True if the marker is already added.*/
Cluster.prototype.isMarkerAlreadyAdded = function(marker) {if (this.markers_.indexOf) {return this.markers_.indexOf(marker) != -1;} else {for (var i = 0, m; m = this.markers_[i]; i++) {if (m == marker) {return true;}}}return false;
};/*** Add a marker the cluster.** @param {google.maps.Marker} marker The marker to add.* @return {boolean} True if the marker was added.*/
Cluster.prototype.addMarker = function(marker) {if (this.isMarkerAlreadyAdded(marker)) {return false;}if (!this.center_) {this.center_ = marker.getPosition();this.calculateBounds_();} else {if (this.averageCenter_) {var l = this.markers_.length + 1;var lat = (this.center_.lat() * (l-1) + marker.getPosition().lat()) / l;var lng = (this.center_.lng() * (l-1) + marker.getPosition().lng()) / l;this.center_ = new google.maps.LatLng(lat, lng);this.calculateBounds_();}}marker.isAdded = true;this.markers_.push(marker);var len = this.markers_.length;if (len < this.minClusterSize_ && marker.getMap() != this.map_) {// Min cluster size not reached so show the marker.marker.setMap(this.map_);}if (len == this.minClusterSize_) {// Hide the markers that were showing.for (var i = 0; i < len; i++) {this.markers_[i].setMap(null);}}if (len >= this.minClusterSize_) {marker.setMap(null);}this.updateIcon();return true;
};/*** Returns the marker clusterer that the cluster is associated with.** @return {MarkerClusterer} The associated marker clusterer.*/
Cluster.prototype.getMarkerClusterer = function() {return this.markerClusterer_;
};/*** Returns the bounds of the cluster.** @return {google.maps.LatLngBounds} the cluster bounds.*/
Cluster.prototype.getBounds = function() {var bounds = new google.maps.LatLngBounds(this.center_, this.center_);var markers = this.getMarkers();for (var i = 0, marker; marker = markers[i]; i++) {bounds.extend(marker.getPosition());}return bounds;
};/*** Removes the cluster*/
Cluster.prototype.remove = function() {this.clusterIcon_.remove();this.markers_.length = 0;delete this.markers_;
};/*** Returns the center of the cluster.** @return {number} The cluster center.*/
Cluster.prototype.getSize = function() {return this.markers_.length;
};/*** Returns the center of the cluster.** @return {Array.<google.maps.Marker>} The cluster center.*/
Cluster.prototype.getMarkers = function() {return this.markers_;
};/*** Returns the center of the cluster.** @return {google.maps.LatLng} The cluster center.*/
Cluster.prototype.getCenter = function() {return this.center_;
};/*** Calculated the extended bounds of the cluster with the grid.** @private*/
Cluster.prototype.calculateBounds_ = function() {var bounds = new google.maps.LatLngBounds(this.center_, this.center_);this.bounds_ = this.markerClusterer_.getExtendedBounds(bounds);
};/*** Determines if a marker lies in the clusters bounds.** @param {google.maps.Marker} marker The marker to check.* @return {boolean} True if the marker lies in the bounds.*/
Cluster.prototype.isMarkerInClusterBounds = function(marker) {return this.bounds_.contains(marker.getPosition());
};/*** Returns the map that the cluster is associated with.** @return {google.maps.Map} The map.*/
Cluster.prototype.getMap = function() {return this.map_;
};/*** Updates the cluster icon*/
Cluster.prototype.updateIcon = function() {var zoom = this.map_.getZoom();var mz = this.markerClusterer_.getMaxZoom();if (mz && zoom > mz) {// The zoom is greater than our max zoom so show all the markers in cluster.for (var i = 0, marker; marker = this.markers_[i]; i++) {marker.setMap(this.map_);}return;}if (this.markers_.length < this.minClusterSize_) {// Min cluster size not yet reached.this.clusterIcon_.hide();return;}var numStyles = this.markerClusterer_.getStyles().length;var sums = this.markerClusterer_.getCalculator()(this.markers_, numStyles);this.clusterIcon_.setCenter(this.center_);this.clusterIcon_.setSums(sums);this.clusterIcon_.show();
};/*** A cluster icon** @param {Cluster} cluster The cluster to be associated with.* @param {Object} styles An object that has style properties:*     'url': (string) The image url.*     'height': (number) The image height.*     'width': (number) The image width.*     'anchor': (Array) The anchor position of the label text.*     'textColor': (string) The text color.*     'textSize': (number) The text size.*     'backgroundPosition: (string) The background postition x, y.* @param {number=} opt_padding Optional padding to apply to the cluster icon.* @constructor* @extends google.maps.OverlayView* @ignore*/
function ClusterIcon(cluster, styles, opt_padding) {cluster.getMarkerClusterer().extend(ClusterIcon, google.maps.OverlayView);this.styles_ = styles;this.padding_ = opt_padding || 0;this.cluster_ = cluster;this.center_ = null;this.map_ = cluster.getMap();this.div_ = null;this.sums_ = null;this.visible_ = false;this.setMap(this.map_);
}/*** Triggers the clusterclick event and zoom's if the option is set.*/
ClusterIcon.prototype.triggerClusterClick = function() {var markerClusterer = this.cluster_.getMarkerClusterer();// Trigger the clusterclick event.google.maps.event.trigger(markerClusterer, 'clusterclick', this.cluster_);if (markerClusterer.isZoomOnClick()) {// Zoom into the cluster.this.map_.fitBounds(this.cluster_.getBounds());}
};/*** Adding the cluster icon to the dom.* @ignore*/
ClusterIcon.prototype.onAdd = function() {this.div_ = document.createElement('DIV');if (this.visible_) {var pos = this.getPosFromLatLng_(this.center_);this.div_.style.cssText = this.createCss(pos);this.div_.innerHTML = this.sums_.text;}var panes = this.getPanes();panes.overlayMouseTarget.appendChild(this.div_);var that = this;google.maps.event.addDomListener(this.div_, 'click', function() {that.triggerClusterClick();});
};/*** Returns the position to place the div dending on the latlng.** @param {google.maps.LatLng} latlng The position in latlng.* @return {google.maps.Point} The position in pixels.* @private*/
ClusterIcon.prototype.getPosFromLatLng_ = function(latlng) {var pos = this.getProjection().fromLatLngToDivPixel(latlng);pos.x -= parseInt(this.width_ / 2, 10);pos.y -= parseInt(this.height_ / 2, 10);return pos;
};/*** Draw the icon.* @ignore*/
ClusterIcon.prototype.draw = function() {if (this.visible_) {var pos = this.getPosFromLatLng_(this.center_);this.div_.style.top = pos.y + 'px';this.div_.style.left = pos.x + 'px';}
};/*** Hide the icon.*/
ClusterIcon.prototype.hide = function() {if (this.div_) {this.div_.style.display = 'none';}this.visible_ = false;
};/*** Position and show the icon.*/
ClusterIcon.prototype.show = function() {if (this.div_) {var pos = this.getPosFromLatLng_(this.center_);this.div_.style.cssText = this.createCss(pos);this.div_.style.display = '';}this.visible_ = true;
};/*** Remove the icon from the map*/
ClusterIcon.prototype.remove = function() {this.setMap(null);
};/*** Implementation of the onRemove interface.* @ignore*/
ClusterIcon.prototype.onRemove = function() {if (this.div_ && this.div_.parentNode) {this.hide();this.div_.parentNode.removeChild(this.div_);this.div_ = null;}
};/*** Set the sums of the icon.** @param {Object} sums The sums containing:*   'text': (string) The text to display in the icon.*   'index': (number) The style index of the icon.*/
ClusterIcon.prototype.setSums = function(sums) {this.sums_ = sums;this.text_ = sums.text;this.index_ = sums.index;if (this.div_) {this.div_.innerHTML = sums.text;}this.useStyle();
};/*** Sets the icon to the the styles.*/
ClusterIcon.prototype.useStyle = function() {var index = Math.max(0, this.sums_.index - 1);index = Math.min(this.styles_.length - 1, index);var style = this.styles_[index];this.url_ = style['url'];this.height_ = style['height'];// 新增了lineHeight_this.lineHeight_ = style['lineHeight']; this.width_ = style['width'];this.textColor_ = style['textColor'];this.anchor_ = style['anchor'];this.textSize_ = style['textSize'];this.backgroundPosition_ = style['backgroundPosition'];
};/*** Sets the center of the icon.** @param {google.maps.LatLng} center The latlng to set as the center.*/
ClusterIcon.prototype.setCenter = function(center) {this.center_ = center;
};/*** Create the css text based on the position of the icon.** @param {google.maps.Point} pos The position.* @return {string} The css style text.*/
ClusterIcon.prototype.createCss = function(pos) {var style = [];style.push('background-image:url(' + this.url_ + ');');var backgroundPosition = this.backgroundPosition_ ? this.backgroundPosition_ : '0 0';style.push('background-position:' + backgroundPosition + ';');if (typeof this.anchor_ === 'object') {if (typeof this.anchor_[0] === 'number' && this.anchor_[0] > 0 &&this.anchor_[0] < this.height_) {style.push('height:' + (this.height_ - this.anchor_[0]) +'px; padding-top:' + this.anchor_[0] + 'px;');} else {style.push('height:' + this.height_ + 'px; line-height:' + this.lineHeight_ +'px;');}if (typeof this.anchor_[1] === 'number' && this.anchor_[1] > 0 &&this.anchor_[1] < this.width_) {style.push('width:' + (this.width_ - this.anchor_[1]) +'px; padding-left:' + this.anchor_[1] + 'px;');} else {style.push('width:' + this.width_ + 'px; text-align:center;');}} else {style.push('height:' + this.height_ + 'px; line-height:' +this.lineHeight_ + 'px; width:' + this.width_ + 'px; text-align:center;');}var txtColor = this.textColor_ ? this.textColor_ : 'black';var txtSize = this.textSize_ ? this.textSize_ : 11;style.push('cursor:pointer; top:' + pos.y + 'px; left:' +pos.x + 'px; color:' + txtColor + '; position:absolute; font-size:' +txtSize + 'px; font-family:Arial,sans-serif; font-weight:bold');return style.join('');
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/233469.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(自适应手机版)全屏滚动装修装潢公司网站模板

(自适应手机版)全屏滚动装修装潢公司网站模板 PbootCMS内核开发的网站模板&#xff0c;该模板适用于装修公司网站、装潢公司网站类等企业&#xff0c;当然其他行业也可以做&#xff0c;只需要把文字图片换成其他行业的即可&#xff1b; 自适应手机版&#xff0c;同一个后台&a…

SQL Server 安装教程

安装数据库 1、启动SQL Server2014安装程序&#xff0c;运行setup.exe文件&#xff0c;打开”SQL Server安装中心“对话框&#xff0c;单击左侧 的导航区域中的”安装“选项卡。 2、选择”全新SQL Server独立安装或向现有安装添加功能“&#xff0c;启动SQL Server2014安装向导…

自动驾驶技术入门平台分享:百度Apollo开放平台9.0全方位升级

目录 平台全方位的升级 全新的架构 工具服务 应用软件&#xff08;场景应用&#xff09; 软件核心 硬件设备 更强的算法能力 9.0版本算法升级总结 更易用的工程框架 Apollo开放平台9.0版本的技术升级为开发者提供了许多显著的好处&#xff0c;特别是对于深度开发需求…

.gitignore和git lfs学习

The ninth day——12.18 1. .gitignore 忽略规则优先级 从命令行中读取可用的忽略规则当前目录定义的规则父级目录定义的规则&#xff0c;依次递推$GIT_DIR/info/exclude 文件中定义的规则core.excludesfile中定义的全局规则 忽略规则匹配语法 空格不匹配任意文件&#xff…

LVS+Keepalived 高可用集群

一.Keepalived工具介绍 1.支持故障自动切换(Failover) 2.支持节点健康状态检查(Health Checking) 3.基于vrrp协议完成地址流动 4.为vip地址所在的节点生成ipvs规则(在配置文件中预先定义) 5.为ipvs集群的各RS做健康状态检测 6.基于脚本调用接口完成脚本中定义的功能&…

MyBatis ${}和#{}区别

sql防注入底层jdbc类型转换当简单类型参数$不防止Statment不转换value#防止preparedStatement转换任意 除模糊匹配外&#xff0c;杜绝使用${} MyBatis教程&#xff0c;大家可以借鉴 MyBatis 教程_w3cschoolMyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。…

RPC(5):AJAX跨域请求处理

接上一篇RPC&#xff08;4&#xff09;&#xff1a;HttpClient实现RPC之POST请求进行修改。 1 修改客户端项目 1.1 修改maven文件 修改后配置文件如下&#xff1a; <dependencyManagement><dependencies><dependency><groupId>org.springframework.b…

数据智慧:如何利用可视化提升效率

数据可视化是一项强大的工具&#xff0c;能够显著提高工作效率和决策的准确性。下面我就以可视化从业者的角度&#xff0c;简单谈谈数据可视化是如何助力效率提升的。 直观理解复杂数据 数据可视化将抽象的数据转化为图表、图形或仪表盘&#xff0c;使数据更易于理解。这种直观…

openstack-keystone服务

文章目录 keystone服务安装和配置先决条件安装并配置组件运行以下命令来安装包。编辑文件 /etc/keystone/keystone.conf 并完成如下动作&#xff1a;初始化身份认证服务的数据库&#xff1a;初始化Fernet keys&#xff1a;Bootstrap the Identity service: 配置 Apache HTTP 服…

【算法题】1. 两数之和

目录 题目 题解 题目 给定一个整数数组nums和一个整数目标值target&#xff0c;请你在该数组中找出和为目标值target的那两个整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现。 你可以…

Linux系统之部署Linux管理面板1Panel

一、介绍 1.1简介 1Panel 是一个现代化、开源的 Linux 服务器运维管理面板。 1.2特点 快速建站&#xff1a;深度集成 Wordpress 和 Halo&#xff0c;域名绑定、SSL 证书配置等一键搞定&#xff1b; 高效管理&#xff1a;通过 Web 端轻松管理 Linux 服务器&#xff0c;包括应用管…

AWS S3相关配置笔记

关闭 阻止所有公开访问 存储桶策略(开放外部访问) {"Version": "2012-10-17","Id": "S3PolicyId1","Statement": [{"Sid": "statement1","Effect": "Allow","Principal"…

[最后一个月征稿、ACM独立出版】第三届密码学、网络安全和通信技术国际会议(CNSCT 2024)

第三届密码学、网络安全和通信技术国际会议&#xff08;CNSCT 2024&#xff09; 2024 3rd International Conference on Cryptography, Network Security and Communication Technology 一、大会简介 随着互联网和网络应用的不断发展&#xff0c;网络安全在计算机科学中的地…

【线性代数】两个向量组等价,其中一个向量组线性无关,另一个向量组也是线性无关吗?

一、问题 两个向量组等价,其中一个向量组线性无关,另一个向量组也是线性无关吗? 二、答案 不一定,当两个向量组中的向量个数也相同时,结论才成立.若向量个数不相同,结论不成立. 例如&#xff1a; 向量组一&#xff1a;(1,0),(0,1) 向量组二&#xff1a;(1,0),(0,1),(1,1) 两…

MSVC编译 openssl windows 库

开发需要在windows下集成 openssl 库&#xff0c;参考官方指导完成了编译&#xff1a;openssl/NOTES-WINDOWS.md at master openssl/openssl 不过&#xff0c;最后还是走了直接下载的捷径。 1. 安装 ActivePerl 需要在 ActiveState 注册账户&#xff0c;之后彼会提供具体的…

CentOS安装Nginx

1、yum安装nginx yum install -y nginx 2、nginx启动、关闭 // 查看状态 systemctl status nginx// 运行 systemctl start nginx// 停止 systemctl stop nginx 若使用systemctl start nginx启动时报80端口被占用&#xff1b;&#xff08;原因可能是 你直接使用 nginx命令启…

Redis反序列化异常处理方法

文章目录 问题背景问题分析解决方案 问题背景 通过String类型存储&#xff0c;只不过Value是一个自定义对象。暂且叫这个类型为UserBo吧。 当我们通过redisTemplate.opsForValue().set(userId, userBo, 24, TimeUnit.HOURS)存入时并没有什么问题。 可是如果我们通过UserBo use…

webpack知识点总结(基础应用篇)

一、为什么需要webpack 1.为什么使用webpack ①传统的书写方式&#xff0c;加载太多脚本会导致网络瓶颈&#xff0c;如不小心改变JavaScript文件加载顺序&#xff0c;项目会崩溃&#xff0c;还会导致作用域问题、js文件太大无法做到按需加载、可读性和可维护性太低的问题。 ②…

Vue+ElementUI前端添加展开收起搜索框按钮

1、搜索框添加判断 v-if"advanced" <el-form-item label"创建日期" v-if"advanced"><el-date-pickerv-model"daterangeLedat"size"small"style"width: 240px"value-format"yyyy-MM-dd"type&q…

深入了解常见的应用层网络协议

目录 1. HTTP协议 1.1. 工作原理 1.2. 应用场景 1.3. 安全性考虑 2. SMTP协议 2.1. 工作原理 2.2. 应用场景 2.3. 安全性考虑 3. FTP协议 3.1. 工作原理 3.2. 应用场景 3.3. 安全性考虑 4. DNS协议 4.1. 工作原理 4.2. 应用场景 4.3. 安全性考虑 5. 安全性考虑…