mirror of
https://github.com/webbukkit/dynmap.git
synced 2024-12-25 18:17:37 +01:00
Added client-side portrait generation.
Replaced MarkerWithLabel with CustomMarker. Reworked map.js for easier portrait generation and use of CustomMarker.
This commit is contained in:
parent
588e107dc8
commit
e761cff2b8
76
web/custommarker.js
Normal file
76
web/custommarker.js
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
function CustomMarker(latlng, map, oncreated, args) {
|
||||||
|
google.maps.OverlayView.call(this);
|
||||||
|
|
||||||
|
this.latlng_ = latlng;
|
||||||
|
|
||||||
|
// Once the LatLng and text are set, add the overlay to the map. This will
|
||||||
|
// trigger a call to panes_changed which should in turn call draw.
|
||||||
|
this.setMap(map);
|
||||||
|
|
||||||
|
this.oncreated = oncreated;
|
||||||
|
this.oncreatedargs = args;
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomMarker.prototype = new google.maps.OverlayView();
|
||||||
|
|
||||||
|
CustomMarker.prototype.draw = function() {
|
||||||
|
var me = this;
|
||||||
|
|
||||||
|
// Check if the div has been created.
|
||||||
|
var div = this.div_;
|
||||||
|
if (!div) {
|
||||||
|
// Create a overlay text DIV
|
||||||
|
div = this.div_ = document.createElement('DIV');
|
||||||
|
// Create the DIV representing our CustomMarker
|
||||||
|
div.style.position = "absolute";
|
||||||
|
|
||||||
|
google.maps.event.addDomListener(div, "click", function(event) {
|
||||||
|
google.maps.event.trigger(me, "click");
|
||||||
|
});
|
||||||
|
|
||||||
|
this.oncreated(div, this.oncreatedargs);
|
||||||
|
|
||||||
|
// Then add the overlay to the DOM
|
||||||
|
var panes = this.getPanes();
|
||||||
|
panes.overlayLayer.appendChild(div);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Position the overlay
|
||||||
|
var point = this.getProjection().fromLatLngToDivPixel(this.latlng_);
|
||||||
|
if (point) {
|
||||||
|
div.style.left = point.x + 'px';
|
||||||
|
div.style.top = point.y + 'px';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
CustomMarker.prototype.setPosition = function(p) {
|
||||||
|
this.latlng_ = p;
|
||||||
|
var projection = this.getProjection();
|
||||||
|
if (projection) {
|
||||||
|
var point = projection.fromLatLngToDivPixel(this.latlng_);
|
||||||
|
this.div_.style.left = point.x + 'px';
|
||||||
|
this.div_.style.top = point.y + 'px';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
CustomMarker.prototype.hide = function() {
|
||||||
|
if (this.div_ && !this.isHidden) {
|
||||||
|
this.div_.style.display = 'none';
|
||||||
|
this.isHidden = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomMarker.prototype.show = function() {
|
||||||
|
if (this.div_ && this.isHidden) {
|
||||||
|
this.div_.style.display = 'block';
|
||||||
|
this.isHidden = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomMarker.prototype.remove = function() {
|
||||||
|
// Check if the overlay was on the map and needs to be removed.
|
||||||
|
if (this.div_) {
|
||||||
|
this.div_.parentNode.removeChild(this.div_);
|
||||||
|
this.div_ = null;
|
||||||
|
}
|
||||||
|
};
|
@ -13,14 +13,19 @@
|
|||||||
<link rel="stylesheet" type="text/css" href="style.css" media="screen" />
|
<link rel="stylesheet" type="text/css" href="style.css" media="screen" />
|
||||||
<script type="text/javascript" src="config.js"></script>
|
<script type="text/javascript" src="config.js"></script>
|
||||||
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
|
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
|
||||||
|
<script type="text/javascript" src="custommarker.js"></script>
|
||||||
|
<script type="text/javascript" src="minecraft.js"></script>
|
||||||
<script type="text/javascript" src="map.js"></script>
|
<script type="text/javascript" src="map.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="mcmap"></div>
|
<div id="mcmap"></div>
|
||||||
<div id="plist" style="display:none;">
|
<div id="plist">
|
||||||
<img id="plistbtn" alt="on" src="list_on.png" onclick="plistopen()" title="Toggle Player List" />
|
<img id="plistbtn" alt="on" src="list_on.png" onclick="plistopen()" title="Toggle Player List" />
|
||||||
<img id="cavebtn" src="cave_off.png" title="Toggle X-Ray" onclick="caveSwitch()">
|
<img id="cavebtn" src="cave_off.png" title="Toggle X-Ray" onclick="caveSwitch()">
|
||||||
<div id="lst">[Connecting]</div>
|
<div id="lst">
|
||||||
|
<div id="playerlst"></div>
|
||||||
|
<div id="clock"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="controls" style="display:none;">
|
<div id="controls" style="display:none;">
|
||||||
<form action="#" method="get">
|
<form action="#" method="get">
|
||||||
|
540
web/map.js
540
web/map.js
@ -1,387 +1,3 @@
|
|||||||
/**
|
|
||||||
* This constructor creates a label and associates it with a marker.
|
|
||||||
* It is for the private use of the MarkerWithLabel class.
|
|
||||||
* @constructor
|
|
||||||
* @param {Marker} marker The marker with which the label is to be associated.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
function MarkerLabel_(marker) {
|
|
||||||
this.marker_ = marker;
|
|
||||||
|
|
||||||
this.labelDiv_ = document.createElement("div");
|
|
||||||
this.labelDiv_.style.cssText = "position: absolute; overflow: hidden;";
|
|
||||||
|
|
||||||
// Set up the DIV for handling mouse events in the label. This DIV forms a transparent veil
|
|
||||||
// in the "overlayMouseTarget" pane, a veil that covers just the label. This is done so that
|
|
||||||
// events can be captured even if the label is in the shadow of a google.maps.InfoWindow.
|
|
||||||
// Code is included here to ensure the veil is always exactly the same size as the label.
|
|
||||||
this.eventDiv_ = document.createElement("div");
|
|
||||||
this.eventDiv_.style.cssText = this.labelDiv_.style.cssText;
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarkerLabel_ inherits from OverlayView:
|
|
||||||
MarkerLabel_.prototype = new google.maps.OverlayView();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds the DIV representing the label to the DOM. This method is called
|
|
||||||
* automatically when the marker's <code>setMap</code> method is called.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
MarkerLabel_.prototype.onAdd = function () {
|
|
||||||
var me = this;
|
|
||||||
var cMouseIsDown = false;
|
|
||||||
var cDraggingInProgress = false;
|
|
||||||
var cSavedPosition;
|
|
||||||
var cSavedZIndex;
|
|
||||||
var cLatOffset, cLngOffset;
|
|
||||||
var cIgnoreClick;
|
|
||||||
|
|
||||||
// Stops all processing of an event.
|
|
||||||
//
|
|
||||||
var cAbortEvent = function (e) {
|
|
||||||
if (e.preventDefault) {
|
|
||||||
e.preventDefault();
|
|
||||||
}
|
|
||||||
e.cancelBubble = true;
|
|
||||||
if (e.stopPropagation) {
|
|
||||||
e.stopPropagation();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.getPanes().overlayImage.appendChild(this.labelDiv_);
|
|
||||||
this.getPanes().overlayMouseTarget.appendChild(this.eventDiv_);
|
|
||||||
|
|
||||||
this.listeners_ = [
|
|
||||||
google.maps.event.addDomListener(document, "mouseup", function (mEvent) {
|
|
||||||
if (cDraggingInProgress) {
|
|
||||||
mEvent.latLng = cSavedPosition;
|
|
||||||
cIgnoreClick = true; // Set flag to ignore the click event reported after a label drag
|
|
||||||
google.maps.event.trigger(me.marker_, "dragend", mEvent);
|
|
||||||
}
|
|
||||||
cMouseIsDown = false;
|
|
||||||
google.maps.event.trigger(me.marker_, "mouseup", mEvent);
|
|
||||||
}),
|
|
||||||
google.maps.event.addListener(me.marker_.getMap(), "mousemove", function (mEvent) {
|
|
||||||
if (cMouseIsDown && me.marker_.getDraggable()) {
|
|
||||||
// Change the reported location from the mouse position to the marker position:
|
|
||||||
mEvent.latLng = new google.maps.LatLng(mEvent.latLng.lat() - cLatOffset, mEvent.latLng.lng() - cLngOffset);
|
|
||||||
cSavedPosition = mEvent.latLng;
|
|
||||||
if (cDraggingInProgress) {
|
|
||||||
google.maps.event.trigger(me.marker_, "drag", mEvent);
|
|
||||||
} else {
|
|
||||||
// Calculate offsets from the click point to the marker position:
|
|
||||||
cLatOffset = mEvent.latLng.lat() - me.marker_.getPosition().lat();
|
|
||||||
cLngOffset = mEvent.latLng.lng() - me.marker_.getPosition().lng();
|
|
||||||
google.maps.event.trigger(me.marker_, "dragstart", mEvent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
google.maps.event.addDomListener(this.eventDiv_, "mouseover", function (e) {
|
|
||||||
//me.eventDiv_.style.cursor = "pointer";
|
|
||||||
google.maps.event.trigger(me.marker_, "mouseover", e);
|
|
||||||
}),
|
|
||||||
google.maps.event.addDomListener(this.eventDiv_, "mouseout", function (e) {
|
|
||||||
//me.eventDiv_.style.cursor = me.marker_.getCursor();
|
|
||||||
google.maps.event.trigger(me.marker_, "mouseout", e);
|
|
||||||
}),
|
|
||||||
google.maps.event.addDomListener(this.eventDiv_, "click", function (e) {
|
|
||||||
if (cIgnoreClick) { // Ignore the click reported when a label drag ends
|
|
||||||
cIgnoreClick = false;
|
|
||||||
} else {
|
|
||||||
cAbortEvent(e); // Prevent click from being passed on to map
|
|
||||||
google.maps.event.trigger(me.marker_, "click", e);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
google.maps.event.addDomListener(this.eventDiv_, "dblclick", function (e) {
|
|
||||||
cAbortEvent(e); // Prevent map zoom when double-clicking on a label
|
|
||||||
google.maps.event.trigger(me.marker_, "dblclick", e);
|
|
||||||
}),
|
|
||||||
google.maps.event.addDomListener(this.eventDiv_, "mousedown", function (e) {
|
|
||||||
cMouseIsDown = true;
|
|
||||||
cDraggingInProgress = false;
|
|
||||||
cLatOffset = 0;
|
|
||||||
cLngOffset = 0;
|
|
||||||
cAbortEvent(e); // Prevent map pan when starting a drag on a label
|
|
||||||
google.maps.event.trigger(me.marker_, "mousedown", e);
|
|
||||||
}),
|
|
||||||
google.maps.event.addListener(this.marker_, "dragstart", function (mEvent) {
|
|
||||||
cDraggingInProgress = true;
|
|
||||||
cSavedZIndex = me.marker_.getZIndex();
|
|
||||||
}),
|
|
||||||
google.maps.event.addListener(this.marker_, "drag", function (mEvent) {
|
|
||||||
me.marker_.setPosition(mEvent.latLng);
|
|
||||||
me.marker_.setZIndex(1000000); // Moves the marker to the foreground during a drag
|
|
||||||
}),
|
|
||||||
google.maps.event.addListener(this.marker_, "dragend", function (mEvent) {
|
|
||||||
cDraggingInProgress = false;
|
|
||||||
me.marker_.setZIndex(cSavedZIndex);
|
|
||||||
}),
|
|
||||||
google.maps.event.addListener(this.marker_, "position_changed", function () {
|
|
||||||
me.setPosition();
|
|
||||||
}),
|
|
||||||
google.maps.event.addListener(this.marker_, "zindex_changed", function () {
|
|
||||||
me.setZIndex();
|
|
||||||
}),
|
|
||||||
google.maps.event.addListener(this.marker_, "visible_changed", function () {
|
|
||||||
me.setVisible();
|
|
||||||
}),
|
|
||||||
google.maps.event.addListener(this.marker_, "labelvisible_changed", function () {
|
|
||||||
me.setVisible();
|
|
||||||
}),
|
|
||||||
google.maps.event.addListener(this.marker_, "title_changed", function () {
|
|
||||||
me.setTitle();
|
|
||||||
}),
|
|
||||||
google.maps.event.addListener(this.marker_, "labelcontent_changed", function () {
|
|
||||||
me.setContent();
|
|
||||||
}),
|
|
||||||
google.maps.event.addListener(this.marker_, "labelanchor_changed", function () {
|
|
||||||
me.setAnchor();
|
|
||||||
}),
|
|
||||||
google.maps.event.addListener(this.marker_, "labelclass_changed", function () {
|
|
||||||
me.setStyles();
|
|
||||||
}),
|
|
||||||
google.maps.event.addListener(this.marker_, "labelstyle_changed", function () {
|
|
||||||
me.setStyles();
|
|
||||||
})
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes the DIV for the label from the DOM. It also removes all event handlers.
|
|
||||||
* This method is called automatically when the marker's <code>setMap(null)</code>
|
|
||||||
* method is called.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
MarkerLabel_.prototype.onRemove = function () {
|
|
||||||
var i;
|
|
||||||
this.labelDiv_.parentNode.removeChild(this.labelDiv_);
|
|
||||||
this.eventDiv_.parentNode.removeChild(this.eventDiv_);
|
|
||||||
|
|
||||||
// Remove event listeners:
|
|
||||||
for (i = 0; i < this.listeners_.length; i++) {
|
|
||||||
google.maps.event.removeListener(this.listeners_[i]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Draws the label on the map.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
MarkerLabel_.prototype.draw = function () {
|
|
||||||
this.setContent();
|
|
||||||
this.setTitle();
|
|
||||||
this.setStyles();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the content of the label.
|
|
||||||
* The content can be plain text or an HTML DOM node.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
MarkerLabel_.prototype.setContent = function () {
|
|
||||||
var content = this.marker_.get("labelContent");
|
|
||||||
if (typeof content.nodeType === "undefined") {
|
|
||||||
this.labelDiv_.innerHTML = content;
|
|
||||||
this.eventDiv_.innerHTML = this.labelDiv_.innerHTML;
|
|
||||||
} else {
|
|
||||||
this.labelDiv_.appendChild(content);
|
|
||||||
content = content.cloneNode(true);
|
|
||||||
this.eventDiv_.appendChild(content);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the content of the tool tip for the label. It is
|
|
||||||
* always set to be the same as for the marker itself.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
MarkerLabel_.prototype.setTitle = function () {
|
|
||||||
this.eventDiv_.title = this.marker_.getTitle() || "";
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the style of the label by setting the style sheet and applying
|
|
||||||
* other specific styles requested.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
MarkerLabel_.prototype.setStyles = function () {
|
|
||||||
var i, labelStyle;
|
|
||||||
|
|
||||||
// Apply style values from the style sheet defined in the labelClass parameter:
|
|
||||||
this.labelDiv_.className = this.marker_.get("labelClass");
|
|
||||||
this.eventDiv_.className = this.labelDiv_.className;
|
|
||||||
|
|
||||||
// Clear existing inline style values:
|
|
||||||
this.labelDiv_.style.cssText = "";
|
|
||||||
this.eventDiv_.style.cssText = "";
|
|
||||||
// Apply style values defined in the labelStyle parameter:
|
|
||||||
labelStyle = this.marker_.get("labelStyle");
|
|
||||||
for (i in labelStyle) {
|
|
||||||
if (labelStyle.hasOwnProperty(i)) {
|
|
||||||
this.labelDiv_.style[i] = labelStyle[i];
|
|
||||||
this.eventDiv_.style[i] = labelStyle[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.setMandatoryStyles();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the mandatory styles to the DIV representing the label as well as to the
|
|
||||||
* associated event DIV. This includes setting the DIV position, zIndex, and visibility.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
MarkerLabel_.prototype.setMandatoryStyles = function () {
|
|
||||||
this.labelDiv_.style.position = "absolute";
|
|
||||||
this.labelDiv_.style.overflow = "hidden";
|
|
||||||
// Make sure the opacity setting causes the desired effect on MSIE:
|
|
||||||
if (typeof this.labelDiv_.style.opacity !== "undefined") {
|
|
||||||
this.labelDiv_.style.filter = "alpha(opacity=" + (this.labelDiv_.style.opacity * 100) + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
this.eventDiv_.style.position = this.labelDiv_.style.position;
|
|
||||||
this.eventDiv_.style.overflow = this.labelDiv_.style.overflow;
|
|
||||||
this.eventDiv_.style.opacity = 0.01; // Don't use 0; DIV won't be clickable on MSIE
|
|
||||||
this.eventDiv_.style.filter = "alpha(opacity=1)"; // For MSIE
|
|
||||||
|
|
||||||
this.setAnchor();
|
|
||||||
this.setPosition(); // This also updates zIndex, if necessary.
|
|
||||||
this.setVisible();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the anchor point of the label.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
MarkerLabel_.prototype.setAnchor = function () {
|
|
||||||
var anchor = this.marker_.get("labelAnchor");
|
|
||||||
this.labelDiv_.style.marginLeft = -anchor.x + "px";
|
|
||||||
this.labelDiv_.style.marginTop = -anchor.y + "px";
|
|
||||||
this.eventDiv_.style.marginLeft = -anchor.x + "px";
|
|
||||||
this.eventDiv_.style.marginTop = -anchor.y + "px";
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the position of the label. The zIndex is also updated, if necessary.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
MarkerLabel_.prototype.setPosition = function () {
|
|
||||||
var position = this.getProjection().fromLatLngToDivPixel(this.marker_.getPosition());
|
|
||||||
|
|
||||||
this.labelDiv_.style.left = position.x + "px";
|
|
||||||
this.labelDiv_.style.top = position.y + "px";
|
|
||||||
this.eventDiv_.style.left = this.labelDiv_.style.left;
|
|
||||||
this.eventDiv_.style.top = this.labelDiv_.style.top;
|
|
||||||
|
|
||||||
this.setZIndex();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the zIndex of the label. If the marker's zIndex property has not been defined, the zIndex
|
|
||||||
* of the label is set to the vertical coordinate of the label. This is in keeping with the default
|
|
||||||
* stacking order for Google Maps: markers to the south are in front of markers to the north.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
MarkerLabel_.prototype.setZIndex = function () {
|
|
||||||
var zAdjust = (this.marker_.get("labelInBackground") ? -1 : +1);
|
|
||||||
if (typeof this.marker_.getZIndex() === "undefined") {
|
|
||||||
this.labelDiv_.style.zIndex = parseInt(this.labelDiv_.style.top, 10) + zAdjust;
|
|
||||||
this.eventDiv_.style.zIndex = this.labelDiv_.style.zIndex;
|
|
||||||
} else {
|
|
||||||
this.labelDiv_.style.zIndex = this.marker_.getZIndex() + zAdjust;
|
|
||||||
this.eventDiv_.style.zIndex = this.labelDiv_.style.zIndex;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the visibility of the label. The label is visible only if the marker itself is
|
|
||||||
* visible (i.e., its visible property is true) and the labelVisible property is true.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
MarkerLabel_.prototype.setVisible = function () {
|
|
||||||
if (this.marker_.get("labelVisible")) {
|
|
||||||
this.labelDiv_.style.display = this.marker_.getVisible() ? "block" : "none";
|
|
||||||
} else {
|
|
||||||
this.labelDiv_.style.display = "none";
|
|
||||||
}
|
|
||||||
this.eventDiv_.style.display = this.labelDiv_.style.display;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @name MarkerWithLabelOptions
|
|
||||||
* @class This class represents the optional parameter passed to the {@link MarkerWithLabel} constructor.
|
|
||||||
* The properties available are the same as for <code>google.maps.Marker</code> with the addition
|
|
||||||
* of the properties listed below. To change any of these additional properties after the labeled
|
|
||||||
* marker has been created, call <code>google.maps.Marker.set(propertyName, propertyValue)</code>.
|
|
||||||
* <p>
|
|
||||||
* When any of these properties changes, a property changed event is fired. The names of these
|
|
||||||
* events are derived from the name of the property and are of the form <code>propertyname_changed</code>.
|
|
||||||
* For example, if the content of the label changes, a <code>labelcontent_changed</code> event
|
|
||||||
* is fired.
|
|
||||||
* <p>
|
|
||||||
* @property {string|Node} [labelContent] The content of the label (plain text or an HTML DOM node).
|
|
||||||
* @property {Point} [labelAnchor] By default, a label is drawn with its anchor point at (0,0) so
|
|
||||||
* that its top left corner is positioned at the anchor point of the associated marker. Use this
|
|
||||||
* property to change the anchor point of the label. For example, to center a 50px-wide label
|
|
||||||
* beneath a marker, specify a <code>labelAnchor</code> of <code>google.maps.Point(25, 0)</code>.
|
|
||||||
* (Note: x-values increase to the right and y-values increase to the bottom.)
|
|
||||||
* @property {string} [labelClass] The name of the CSS class defining the styles for the label.
|
|
||||||
* Note that style values for <code>position</code>, <code>overflow</code>, <code>top</code>,
|
|
||||||
* <code>left</code>, <code>zIndex</code>, <code>display</code>, <code>marginLeft</code>, and
|
|
||||||
* <code>marginTop</code> are ignored; these styles are for internal use only.
|
|
||||||
* @property {Object} [labelStyle] An object literal whose properties define specific CSS
|
|
||||||
* style values to be applied to the label. Style values defined here override those that may
|
|
||||||
* be defined in the <code>labelClass</code> style sheet. If this property is changed after the
|
|
||||||
* label has been created, all previously set styles (except those defined in the style sheet)
|
|
||||||
* are removed from the label before the new style values are applied.
|
|
||||||
* Note that style values for <code>position</code>, <code>overflow</code>, <code>top</code>,
|
|
||||||
* <code>left</code>, <code>zIndex</code>, <code>display</code>, <code>marginLeft</code>, and
|
|
||||||
* <code>marginTop</code> are ignored; these styles are for internal use only.
|
|
||||||
* @property {boolean} [labelInBackground] A flag indicating whether a label that overlaps its
|
|
||||||
* associated marker should appear in the background (i.e., in a plane below the marker).
|
|
||||||
* The default is <code>false</code>, which causes the label to appear in the foreground.
|
|
||||||
* @property {boolean} [labelVisible] A flag indicating whether the label is to be visible.
|
|
||||||
* The default is <code>true</code>. Note that even if <code>labelVisible</code> is
|
|
||||||
* <code>true</code>, the label will <i>not</i> be visible unless the associated marker is also
|
|
||||||
* visible (i.e., unless the marker's <code>visible</code> property is <code>true</code>).
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* Creates a MarkerWithLabel with the options specified in {@link MarkerWithLabelOptions}.
|
|
||||||
* @constructor
|
|
||||||
* @param {MarkerWithLabelOptions} [opt_options] The optional parameters.
|
|
||||||
*/
|
|
||||||
function MarkerWithLabel(opt_options) {
|
|
||||||
opt_options = opt_options || {};
|
|
||||||
opt_options.labelContent = opt_options.labelContent || "";
|
|
||||||
opt_options.labelAnchor = opt_options.labelAnchor || new google.maps.Point(0, 0);
|
|
||||||
opt_options.labelClass = opt_options.labelClass || "markerLabels";
|
|
||||||
opt_options.labelStyle = opt_options.labelStyle || {};
|
|
||||||
opt_options.labelInBackground = opt_options.labelInBackground || false;
|
|
||||||
if (typeof opt_options.labelVisible === "undefined") {
|
|
||||||
opt_options.labelVisible = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.label = new MarkerLabel_(this); // Bind the label to the marker
|
|
||||||
|
|
||||||
// Call the parent constructor. It calls Marker.setValues to initialize, so all
|
|
||||||
// the new parameters are conveniently saved and can be accessed with get/set.
|
|
||||||
// Marker.set triggers a property changed event (called "propertyname_changed")
|
|
||||||
// that the marker label listens for in order to react to state changes.
|
|
||||||
google.maps.Marker.apply(this, arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarkerWithLabel inherits from <code>Marker</code>:
|
|
||||||
MarkerWithLabel.prototype = new google.maps.Marker();
|
|
||||||
|
|
||||||
MarkerWithLabel.prototype.setMap = function (theMap) {
|
|
||||||
// Call the inherited function...
|
|
||||||
google.maps.Marker.prototype.setMap.apply(this, arguments);
|
|
||||||
|
|
||||||
// ... then deal with the label:
|
|
||||||
this.label.setMap(theMap);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* generic function for making an XMLHttpRequest
|
/* generic function for making an XMLHttpRequest
|
||||||
* url: request URL
|
* url: request URL
|
||||||
* func: callback function for success
|
* func: callback function for success
|
||||||
@ -584,7 +200,6 @@ function makeRequest(url, func, type, fail, post, contenttype)
|
|||||||
var lasttimestamp = firstRow[0];
|
var lasttimestamp = firstRow[0];
|
||||||
servertime = firstRow[1];
|
servertime = firstRow[1];
|
||||||
delete rows[0];
|
delete rows[0];
|
||||||
var playerlst = '';
|
|
||||||
var numwarps = 0;
|
var numwarps = 0;
|
||||||
var numsigns = 0;
|
var numsigns = 0;
|
||||||
var numhomes = 0;
|
var numhomes = 0;
|
||||||
@ -594,74 +209,91 @@ function makeRequest(url, func, type, fail, post, contenttype)
|
|||||||
for(var line in rows) {
|
for(var line in rows) {
|
||||||
var p = rows[line].split(' ');
|
var p = rows[line].split(' ');
|
||||||
|
|
||||||
if(p[0] == '') continue;
|
if (p[0] == '') continue;
|
||||||
|
|
||||||
// Hack to keep duplicate markers from conflicting with eachother
|
|
||||||
if (p[1] != 'player' && p.length == 5) {
|
|
||||||
p[0] = p[0] + '<span style="display:none;">' + p[1] + '</span>';
|
|
||||||
}
|
|
||||||
loggedin[p[0]] = 1;
|
|
||||||
|
|
||||||
if(p.length == 5) {
|
if(p.length == 5) {
|
||||||
var image = p[1] + '.png';
|
var mi = {
|
||||||
|
id: p[0] + '_' + p[1],
|
||||||
|
text: p[0],
|
||||||
|
type: p[1],
|
||||||
|
position: fromWorldToLatLng(p[2], p[3], p[4])
|
||||||
|
};
|
||||||
|
|
||||||
if (p[1] == 'player') {
|
loggedin[mi.id] = 1;
|
||||||
if(playerlst != '') playerlst += '<br />';
|
|
||||||
playerlst += '<img id="icon_' + p[0] + '" title="Follow" class="plicon" src="' + (p[0] == followPlayer ? 'follow_on.png' : 'follow_off.png') + '" onclick="plfollow(' + "'" + p[0] + "'" + ')" alt="" /><a href="#" onclick="plclick(' + "'" + p[0] + "'" + ')">' + ((setup.showPortraitsInPlayerList)?'<img class="plisthead" src="' + setup.tileUrl + p[0] + '.png" />':'') + p[0] + '</a>';
|
|
||||||
|
|
||||||
if (setup.showPortraitsOnMap) {
|
if (mi.type == 'warp') numwarps++;
|
||||||
image = setup.tileUrl + p[0] + '.png';
|
if (mi.type == 'sign') numsigns++;
|
||||||
}
|
if (mi.type == 'home') numhomes++;
|
||||||
}
|
if (mi.type == 'spawn') numspawns++;
|
||||||
|
if (mi.type == 'player') numplayers++;
|
||||||
if (p[1] == 'warp') numwarps++;
|
|
||||||
if (p[1] == 'sign') numsigns++;
|
|
||||||
if (p[1] == 'home') numhomes++;
|
|
||||||
if (p[1] == 'spawn') numspawns++;
|
|
||||||
if (p[1] == 'player') numplayers++;
|
|
||||||
|
|
||||||
var hideMarker = (
|
var hideMarker = (
|
||||||
(p[1] == 'warp' && showWarps == false) ||
|
(mi.type == 'warp' && showWarps == false) ||
|
||||||
(p[1] == 'sign' && showSigns == false) ||
|
(mi.type == 'sign' && showSigns == false) ||
|
||||||
(p[1] == 'home' && showHomes == false) ||
|
(mi.type == 'home' && showHomes == false) ||
|
||||||
(p[1] == 'spawn' && showSpawn == false)
|
(mi.type == 'spawn' && showSpawn == false)
|
||||||
);
|
);
|
||||||
|
|
||||||
if(p[0] == followPlayer) {
|
if(mi.id == followPlayer) {
|
||||||
map.panTo(fromWorldToLatLng(p[2], p[3], p[4]));
|
map.panTo(fromWorldToLatLng(p[2], p[3], p[4]));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(p[0] in markers) {
|
if(mi.id in markers) {
|
||||||
var m = markers[p[0]];
|
var m = markers[mi.id];
|
||||||
|
|
||||||
if (hideMarker) {
|
if (hideMarker) {
|
||||||
m.setMap(null);
|
m.hide();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (m.map == null) {
|
else {
|
||||||
m.setMap(map);
|
m.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
var converted = fromWorldToLatLng(p[2], p[3], p[4]);
|
var converted = mi.position;
|
||||||
m.setPosition(converted);
|
m.setPosition(mi.position);
|
||||||
} else {
|
} else {
|
||||||
if (hideMarker) {
|
var contentfun = function(div,mi) {
|
||||||
continue;
|
div.className = 'Marker ' + mi.type + 'Marker';
|
||||||
|
div.innerHTML = '<img src="' + mi.type + '.png" /> <span>' + mi.text + '</span>';
|
||||||
|
};
|
||||||
|
if (mi.type == 'player') {
|
||||||
|
contentfun = function(div, mi) {
|
||||||
|
div.className = 'Marker playerMarker';
|
||||||
|
var span = document.createElement('span');
|
||||||
|
span.className = 'playerName';
|
||||||
|
span.appendChild(document.createTextNode(mi.text));
|
||||||
|
div.appendChild(span);
|
||||||
|
getMinecraftHead(mi.text, 32, function(head) {
|
||||||
|
head.className = 'playerIcon';
|
||||||
|
div.insertBefore(head, div.firstChild);
|
||||||
|
});
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
var marker = new CustomMarker(converted, map, contentfun, mi);
|
||||||
|
//if (hideMarker)
|
||||||
|
// marker.hide();
|
||||||
|
marker.markerType = mi.type;
|
||||||
|
|
||||||
var converted = fromWorldToLatLng(p[2], p[3], p[4]);
|
markers[mi.id] = marker;
|
||||||
var marker = new MarkerWithLabel({
|
|
||||||
position: converted,
|
|
||||||
map: map,
|
|
||||||
labelContent: (p[1] == 'player' && setup.showPlayerNameOnMap == false)?'':p[0],
|
|
||||||
labelAnchor: new google.maps.Point(-14, 10),
|
|
||||||
labelClass: "labels",
|
|
||||||
clickable: false,
|
|
||||||
flat: true,
|
|
||||||
icon: new google.maps.MarkerImage(image, new google.maps.Size(28, 28), new google.maps.Point(0, 0), new google.maps.Point(14, 14))
|
|
||||||
});
|
|
||||||
|
|
||||||
markers[p[0]] = marker;
|
if (mi.type == 'player') {
|
||||||
|
var playerRow = document.createElement('div');
|
||||||
|
playerRow.id = 'playerrow_' + mi.text;
|
||||||
|
playerRow.className = 'playerrow';
|
||||||
|
getMinecraftHead(mi.text, 16, function(head) {
|
||||||
|
head.className = 'playerIcon';
|
||||||
|
playerRow.icon = head;
|
||||||
|
playerRow.insertBefore(head, playerRow.firstChild);
|
||||||
|
});
|
||||||
|
var playerText = document.createElement('a');
|
||||||
|
playerText.appendChild(document.createTextNode(' ' + mi.text));
|
||||||
|
playerText.href = '#';
|
||||||
|
playerText.onclick = function(e) { plclick(mi.id); };
|
||||||
|
playerRow.appendChild(playerText);
|
||||||
|
|
||||||
|
marker.playerRow = playerRow;
|
||||||
|
playerlst.appendChild(playerRow);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if(p.length == 3) {
|
} else if(p.length == 3) {
|
||||||
if(p[2] == 't') {
|
if(p[2] == 't') {
|
||||||
@ -684,28 +316,23 @@ function makeRequest(url, func, type, fail, post, contenttype)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (playerlst != '') playerlst += '<br>';
|
var time = {
|
||||||
playerlst += '<img class="plicon" src="clock_' + (servertime > 12000 ? 'night' : 'day') + '.png"> <span id="servertime">...</span>';
|
hours: parseInt(servertime / 1000),
|
||||||
|
minutes: parseInt(((servertime / 1000) % 1) * 60),
|
||||||
|
seconds: parseInt(((((servertime / 1000) % 1) * 60) % 1) * 60)
|
||||||
|
};
|
||||||
|
|
||||||
if(playerlst != oldplayerlst) {
|
|
||||||
oldplayerlst = playerlst;
|
|
||||||
lst.innerHTML = playerlst;
|
|
||||||
}
|
|
||||||
|
|
||||||
var timelbl = document.getElementById('servertime');
|
var clock = document.getElementById('clock');
|
||||||
var rem = 0;
|
clock.className = (servertime > 12000 ? 'night' : 'day');
|
||||||
if (servertime > 12000) {
|
clock.innerText = formatTime(time);
|
||||||
rem = (24000 - servertime) / 20;
|
|
||||||
} else {
|
|
||||||
rem = (12000 - servertime) / 20;
|
|
||||||
}
|
|
||||||
var remMin = parseInt(rem / 60);
|
|
||||||
var remSec = parseInt(rem) - remMin * 60;
|
|
||||||
timelbl.innerHTML = remMin + (remSec < 10 ? ":0" : ":") + remSec;
|
|
||||||
|
|
||||||
for(var m in markers) {
|
for(var m in markers) {
|
||||||
if(!(m in loggedin)) {
|
if(!(m in loggedin)) {
|
||||||
markers[m].setMap(null);
|
markers[m].remove(null);
|
||||||
|
if (markers[m].markerType == 'player') {
|
||||||
|
playerlst.removeChild(markers[m].playerRow);
|
||||||
|
}
|
||||||
delete markers[m];
|
delete markers[m];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -714,11 +341,24 @@ function makeRequest(url, func, type, fail, post, contenttype)
|
|||||||
document.getElementById('signsDiv').style.display = (numsigns == 0)?'none':'';
|
document.getElementById('signsDiv').style.display = (numsigns == 0)?'none':'';
|
||||||
document.getElementById('homesDiv').style.display = (numhomes == 0)?'none':'';
|
document.getElementById('homesDiv').style.display = (numhomes == 0)?'none':'';
|
||||||
document.getElementById('spawnsDiv').style.display = (numspawns == 0)?'none':'';
|
document.getElementById('spawnsDiv').style.display = (numspawns == 0)?'none':'';
|
||||||
document.getElementById('plist').style.display = (numplayers == 0)?'none':'';
|
//document.getElementById('plist').style.display = (numplayers == 0)?'none':'';
|
||||||
document.getElementById('controls').style.display = ((numwarps + numsigns + numhomes + numspawns) == 0)?'none':'';
|
document.getElementById('controls').style.display = ((numwarps + numsigns + numhomes + numspawns) == 0)?'none':'';
|
||||||
}, 'text', function() { alert('failed to get update data'); } );
|
}, 'text', function() { alert('failed to get update data'); } );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatTime(time) {
|
||||||
|
//return formatDigits(time.hours, 2) + ':' + formatDigits(time.minutes, 2) + ':' + formatDigits(time.seconds, 2);
|
||||||
|
return formatDigits(time.hours, 2) + ':' + formatDigits(time.minutes, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatDigits(n, digits) {
|
||||||
|
var s = n.toString();
|
||||||
|
while (s.length < digits) {
|
||||||
|
s = '0' + s;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
window.onload = function initialize() {
|
window.onload = function initialize() {
|
||||||
lst = document.getElementById('lst');
|
lst = document.getElementById('lst');
|
||||||
plistbtn = document.getElementById('plistbtn');
|
plistbtn = document.getElementById('plistbtn');
|
||||||
|
70
web/minecraft.js
Normal file
70
web/minecraft.js
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
var cloneCanvas = function(self) {
|
||||||
|
var c = document.createElement('canvas');
|
||||||
|
c.width = self.width;
|
||||||
|
c.height = self.height;
|
||||||
|
var cxt = c.getContext('2d');
|
||||||
|
cxt.drawImage(self,0,0);
|
||||||
|
return c;
|
||||||
|
};
|
||||||
|
|
||||||
|
CanvasRenderingContext2D.prototype.blitImage = function(image, sx ,sy, sw, sh, dx, dy, dw, dh) {
|
||||||
|
var x; var y;
|
||||||
|
for (x=0;x<dw;x++) {
|
||||||
|
for (y=0;y<dh;y++) {
|
||||||
|
this.drawImage(image,Math.floor(sx+x*(sw/dw)),Math.floor(sy+y*(sw/dw)),1,1,dx+x,dy+y,1,1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function createMinecraftHead(player,completed) {
|
||||||
|
var skinImage = new Image();
|
||||||
|
skinImage.onload = function() {
|
||||||
|
var headCanvas = document.createElement('canvas');
|
||||||
|
headCanvas.width = 8;
|
||||||
|
headCanvas.height = 8;
|
||||||
|
var headContext = headCanvas.getContext('2d');
|
||||||
|
headContext.blitImage(skinImage, 8,8,8,8, 0,0,8,8);
|
||||||
|
headContext.blitImage(skinImage, 40,8,8,8, 0,0,8,8);
|
||||||
|
completed(headCanvas);
|
||||||
|
};
|
||||||
|
skinImage.src = 'http://www.minecraft.net/skin/' + player + '.png';
|
||||||
|
}
|
||||||
|
|
||||||
|
function resizeImage(img,size) {
|
||||||
|
var canvas = document.createElement('canvas');
|
||||||
|
canvas.width = size;
|
||||||
|
canvas.height = size;
|
||||||
|
var ctx = canvas.getContext('2d');
|
||||||
|
ctx.blitImage(img, 0,0,img.width,img.height, 0,0,size,size);
|
||||||
|
return canvas;
|
||||||
|
}
|
||||||
|
|
||||||
|
var players = {};
|
||||||
|
|
||||||
|
function getMinecraftHead(player,size,completed) {
|
||||||
|
var head = players[player];
|
||||||
|
// Synchronous
|
||||||
|
if (!completed) {
|
||||||
|
return (!head || head.working) ? null : head;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Asynchronous
|
||||||
|
if (!head) {
|
||||||
|
players[player] = { working: true, hooks: [{f:completed,s:size}] };
|
||||||
|
console.log('Creating head for ',player,'...');
|
||||||
|
createMinecraftHead(player, function(head) {
|
||||||
|
console.log('Created head for ',player,': ', head);
|
||||||
|
hooks = players[player].hooks;
|
||||||
|
players[player] = head;
|
||||||
|
var i;
|
||||||
|
for(i=0;i<hooks.length;i++) {
|
||||||
|
hooks[i].f(resizeImage(head,hooks[i].s));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (head.working) {
|
||||||
|
console.log('Other process working on head of ',player,', will add myself to hooks...');
|
||||||
|
head.hooks[head.hooks.length] = {f:completed,s:size};
|
||||||
|
} else {
|
||||||
|
completed(resizeImage(head,size));
|
||||||
|
}
|
||||||
|
}
|
@ -74,6 +74,68 @@ a, a:visited {
|
|||||||
background-color:#000;
|
background-color:#000;
|
||||||
border: 0px;
|
border: 0px;
|
||||||
}
|
}
|
||||||
#servertime {
|
#clock {
|
||||||
|
padding-left: 16px;
|
||||||
color: #dede90;
|
color: #dede90;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
#clock.night { background-image: url(clock_night.png); }
|
||||||
|
#clock.day { background-image: url(clock_day.png); }
|
||||||
|
|
||||||
|
.playerIcon {
|
||||||
|
}
|
||||||
|
|
||||||
|
.playerrow {
|
||||||
|
width: 120px;
|
||||||
|
vertical-align: middle;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 1px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.playerrow:hover {
|
||||||
|
border: 1px solid #222222;
|
||||||
|
background-color: #333333;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.playerrow * {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Marker {
|
||||||
|
font-family: Tahoma;
|
||||||
|
font-size: 12px;
|
||||||
|
color: white;
|
||||||
|
width: 100px;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
margin-left: -12px;
|
||||||
|
margin-top: -12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Marker * {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Marker span {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Marker:hover span {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Marker img {
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.playerMarker {
|
||||||
|
margin-left: -16px;
|
||||||
|
margin-top: -16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.playerMarker span {
|
||||||
|
visibility: visible;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user