Artikel und Tutorials für HTML5-Spieleentwicklung, u.a.:
$ aptitude moo
$ aptitude -v moo
$ aptitude -v -v moo
...
Nette kleine Library zum Formatieren und Berechnen von Zeit-Daten, inkl. guter Internationalisierung.
Faszinierender Einblick in die Anfänge von HTML. Zeigt auch nett, dass sich existierende Lösungen gegenüber potentiell besseren Ideen meist durchsetzen. Ein paar interessante Stellen:
Netscape-Schöpfer Marc Andreessen, der hier noch am Vorgänger Mosaic arbeitet, schlägt den <img>-Tag vor:
I'd like to propose a new, optional HTML tag:
IMG
...
An example is:
<IMG SRC="file://foobar.com/foo/bar/blargh.xbm">
...
Browsers should be afforded flexibility as to which image formats they support. Xbm and Xpm are good ones to support, for example.
Xbm ist ein interessantes Format. Damals neben GIF eines der wenigen frei benutzbaren Bildformate — JPEG wurde erst fünf Monate vorher im September 1992 fertig und PNG drei Jahre später. Xbm besteht nicht aus einem Binärformat, sondern ist ein Byte-Array in C, damit man es leichter in eigenen Code einbinden kann. Dadurch allerdings auch recht groß.
Eine Idee von Tony Johnson:
I have something very similar in Midas 2.0
<ICON name="NoEntry" href="http://note/foo/bar/NoEntry.xbm">
...
The idea of the name parameter was to allow the browser to have a set of "built in" images. If the name matches a "built in" image it would use that instead of having to go out and fetch the image.
Im Browser eingebaute Standardbilder. Damals wohl zu aufwändig, heute gibt's Emoji.
Noch ein Vorschlag:
While we are on the subject of new tags, I have another, somewhat similar tag, which I would like to support in Midas 2.0. In principle it is:
<INCLUDE HREF="...">
The intention here would be that the second document is to be included into the first document at the place where the tag occured.
In principle the referenced document could be anything, but the main purpose was to allow images (in this case arbitrary sized) to be embedded into documents.
Zwei Jahre später taucht der <embed>-Tag im Netscape Navigator 2.0 auf. Einige bemängeln, dass eine einheitliche Lösung besser wäre statt für jeden Medientyp ein eigenes Tag zu haben. Doch das Chaos wächst, bald gibt es einen ganzen Zoo an <embed>-ähnlichen Tags. Die damals kurz sinnvollen Java-Applets werden erst mit dem <app>-, dann mit dem <applet>-Tag eingebunden und es gab sogar einen Vorläufer des HTML <video>-Tags: Das DYNSRC-Attribut, mit dem Videoclips oder gar wundervolle 3D-VRML-Welten eingebunden werden können.
1997 wurde versucht, sie alle mit dem <object>-Tag zu vereinheitlichen. <app>, <applet> und dynsrc sind verschwunden, doch der <embed>-Tag lebt immernoch. Selbst Youtube hat ihn bis vor kurzem der Kompatibilität mit alten Browsern wegen noch eingesetzt. Eingebettet in einen <object>-Tag.
Tim Berners-Lee, Erfinder des WWW schreibt:
If you allow an image, then suppose we also allow some content which includes anchors with x,y coordinates within the image. Then the document can intercept mouse clicks and allow hypergraphics
Clientseitige Image-Maps, vier Jahre später in HTML 3.2 eingeführt. Einen Monat vorher hatte laut Wikipedia bereits Kevin Hughes serverseitige Image-Maps erfunden.
Whatever happened to the enthusiasm for using the MIME typing mechanism? I made a concrete proposal a few months ago, where HREFs can point to other parts in a MIME multipart (and thereby to an "external-body"), and I've seen a similar idea recently regarding embedding media clips in a "simplemail" format.
In HTML eingebettete Medien statt externe, einzelne Dateien, genau wie Emails. Hat sich dankenswerterweise nicht durchgesetzt. Der Server müsste die Seite erst zusammenbauen, statt stur statische Dateien auszuliefern. Auch Caching einzelner Resourcen wäre so unmöglich.
Jedoch, fünf Jahre später werden Data-URIs vorgeschlagen, mit denen genau das möglich ist und die heute z.B. für Musik mit JavaScript Synths eingesetzt werden.
Wait a minute -- let's temporarily forget about MIME, if it clouds the issue. My objection was to the discussion of "how are we going to support embedded images" rather than "how are we going to support embedded objections in various media".
Otherwise, next week someone is going to suggest 'lets put in a new tag
<AUD SRC="file://foobar.com/foo/bar/blargh.snd">'
for audio.
Marc Andreessen schlägt noch eine eigene PostScript-ähnliche Grafiksprache vor, implementiert dann aber doch den schnöden <img>-Tag und schafft somit Fakten. Am Ende schaut auch noch Python-Erfinder Guido van Rossum vorbei.
Zum weiterlesen: A History of HTML über die Anfänge des WWW.
In Three Easy Steps.
Marker kann man in Google Maps zwar mit setPosition() verschieben, dies wird aber nicht animiert. Da es doch recht schön ist, wenn Marker nicht einfach rumspringen, schrieb ich die folgende Funktion. Einfach einbinden und an einem Marker aufrufen. Optional jQuery und das jQuery Easing Plugin nehmen, um mehr als nur linear zu animieren.
Demo: (auf Karte klicken)
Die Funktion:
// Animated Marker Movement. Robert Gerlach 2012-2013 https://github.com/combatwombat/marker-animate
// MIT license
//
// params:
// newPosition - the new Position as google.maps.LatLng()
// options - optional options object (optional)
// options.duration - animation duration in ms (default 1000)
// options.easing - easing function from jQuery and/or the jQuery easing plugin (default 'linear')
// options.complete - callback function. Gets called, after the animation has finished
google.maps.Marker.prototype.animateTo = function(newPosition, options) {
defaultOptions = {
duration: 1000,
easing: 'linear',
complete: null
}
options = options || {};
// complete missing options
for (key in defaultOptions) {
options[key] = options[key] || defaultOptions[key];
}
// throw exception if easing function doesn't exist
if (options.easing != 'linear') {
if (typeof jQuery == 'undefined' || !jQuery.easing[options.easing]) {
throw '"' + options.easing + '" easing function doesn\'t exist. Include jQuery and/or the jQuery easing plugin and use the right function name.';
return;
}
}
window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
window.cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame;
// save current position. prefixed to avoid name collisions. separate for lat/lng to avoid calling lat()/lng() in every frame
this.AT_startPosition_lat = this.getPosition().lat();
this.AT_startPosition_lng = this.getPosition().lng();
var newPosition_lat = newPosition.lat();
var newPosition_lng = newPosition.lng();
// crossing the 180° meridian and going the long way around the earth?
if (Math.abs(newPosition_lng - this.AT_startPosition_lng) > 180) {
if (newPosition_lng > this.AT_startPosition_lng) {
newPosition_lng -= 360;
} else {
newPosition_lng += 360;
}
}
var animateStep = function(marker, startTime) {
var ellapsedTime = (new Date()).getTime() - startTime;
var durationRatio = ellapsedTime / options.duration; // 0 - 1
var easingDurationRatio = durationRatio;
// use jQuery easing if it's not linear
if (options.easing !== 'linear') {
easingDurationRatio = jQuery.easing[options.easing](durationRatio, ellapsedTime, 0, 1, options.duration);
}
if (durationRatio < 1) {
var deltaPosition = new google.maps.LatLng( marker.AT_startPosition_lat + (newPosition_lat - marker.AT_startPosition_lat)*easingDurationRatio,
marker.AT_startPosition_lng + (newPosition_lng - marker.AT_startPosition_lng)*easingDurationRatio);
marker.setPosition(deltaPosition);
// use requestAnimationFrame if it exists on this browser. If not, use setTimeout with ~60 fps
if (window.requestAnimationFrame) {
marker.AT_animationHandler = window.requestAnimationFrame(function() {animateStep(marker, startTime)});
} else {
marker.AT_animationHandler = setTimeout(function() {animateStep(marker, startTime)}, 17);
}
} else {
marker.setPosition(newPosition);
if (typeof options.complete === 'function') {
options.complete();
}
}
}
// stop possibly running animation
if (window.cancelAnimationFrame) {
window.cancelAnimationFrame(this.AT_animationHandler);
} else {
clearTimeout(this.AT_animationHandler);
}
animateStep(this, (new Date()).getTime());
}
// move marker in 1000ms and with linear animation. marker.animateTo(newPosition);
// or with callback and options for easing and duration in milliseconds. Needs jQuery Easing Plugin. marker.animateTo(newPosition, { easing: "easeOutBounce", duration: 1000, complete: function() { alert("animation complete"); } });
<p>Das ganze auf <a href="https://github.com/combatwombat/marker-animate">github</a>.</p>