9/25/2017

SVG 3D Tag Cloud jQuery Plugin V2

Nach diversen Anfragen gibt es nun ein Update für das SVG 3D Tag Cloud jQuery Plugin.
In der Version 2 gibt es nun die Möglichkeit anstelle von Texten Bilder zu laden. Und, was auch schon häufiger angefragt worden ist, ihr könnt euch zu jedem Bild/Text auch einen Tooltip anzeigen lassen.
Die alte und die neue Version sind soweit kompatibel, weshalb ihr mit der neuen JS-Datei einfach die alte überschreiben könnt. Und das ohne die Funktionalität zu zerstören.
Hier ein Beispiel mit Bildern und Tooltips:




So setzt man nach wie vor Tags mit Text:

var entries = [ 

    { label: 'Dev Blog', url: 'http://niklasknaack.blogspot.de/', target: '_top' },
    { label: 'Flashforum', url: 'http://www.flashforum.de/', target: '_top' },
    { label: 'Javascript-Forum', url: 'http://forum.jswelt.de/', target: '_top' },
    { label: 'CodePen', url: 'http://codepen.io/', target: '_top' },
    { label: 'three.js', url: 'http://threejs.org/', target: '_top' },
    { label: 'WebGLStudio.js', url: 'http://webglstudio.org/', target: '_top' },
    { label: 'JS Compress', url: 'http://jscompress.com/', target: '_top' },
    { label: 'TinyPNG', url: 'https://tinypng.com/', target: '_top' },
    { label: 'Can I Use', url: 'http://caniuse.com/', target: '_top' },
    { label: 'URL shortener', url: 'https://goo.gl/', target: '_top' }

];


Wollt ihr nun Bilder anstelle von Text anzeigen, dann sieht das wie folgt aus:

var entries = [ 

    { image: './img/Basket.png', width: '50', height: '50', url: 'http://jquery-plugins.net/', target: '_top' },
    { image: './img/Briefcase.png', width: '50', height: '50', url: 'http://jquery-plugins.net/', target: '_top' },
    { image: './img/Brush.png', width: '50', height: '50', url: 'http://jquery-plugins.net/', target: '_top' },
    { image: './img/Calendar.png', width: '50', height: '50', url: 'http://jquery-plugins.net/', target: '_top' },
    { image: './img/Camera.png', width: '50', height: '50', url: 'http://jquery-plugins.net/', target: '_top' },
    { image: './img/Cassette.png', width: '50', height: '50', url: 'http://jquery-plugins.net/', target: '_top' },
    { image: './img/Clock.png', width: '50', height: '50', url: 'http://jquery-plugins.net/', target: '_top' },
    { image: './img/Cloud_Download.png', width: '50', height: '50', url: 'http://jquery-plugins.net/', target: '_top' },
    { image: './img/Cloud_Upload.png', width: '50', height: '50', url: 'http://jquery-plugins.net/', target: '_top' },
    { image: './img/Coffee.png', width: '50', height: '50', url: 'http://jquery-plugins.net/', target: '_top' },
    { image: './img/Comments.png', width: '50', height: '50', url: 'http://jquery-plugins.net/', target: '_top' },
    { image: './img/Credit_Card.png', width: '50', height: '50', url: 'http://jquery-plugins.net/', target: '_top' }

];


Ihr ersetzt einfach nur den Paramter label mit dem Parameter image. Bei image gebt ihr den Pfad und den Dateinamen zu der gewünschten Grafik ein. Neben dem neuen Parameter image gibt es noch die neuen Parameter width und height, mit denen ihr die anzuzeigende Größe von eurer Grafik mit angeben müsst.

Und wenn ihr jetzt noch Tooltips dazu haben wollt schaut euch das Beispiel hier an:


var entries = [ 

    { image: './img/Basket.png', width: '50', height: '50', url: 'http://jquery-plugins.net/', target: '_top', tooltip: 'Lorem ipsum' },
    { image: './img/Briefcase.png', width: '50', height: '50', url: 'http://jquery-plugins.net/', target: '_top', tooltip: 'Dolor sit amet' },
    { image: './img/Brush.png', width: '50', height: '50', url: 'http://jquery-plugins.net/', target: '_top', tooltip: 'Consetetur sadipscing' },
    { image: './img/Calendar.png', width: '50', height: '50', url: 'http://jquery-plugins.net/', target: '_top', tooltip: 'Sed diam' },
    { image: './img/Camera.png', width: '50', height: '50', url: 'http://jquery-plugins.net/', target: '_top', tooltip: 'At vero' },
    { image: './img/Cassette.png', width: '50', height: '50', url: 'http://jquery-plugins.net/', target: '_top', tooltip: 'Nonumy eirmod' },
    { image: './img/Clock.png', width: '50', height: '50', url: 'http://jquery-plugins.net/', target: '_top', tooltip: 'Stet clita' },
    { image: './img/Cloud_Download.png', width: '50', height: '50', url: 'http://jquery-plugins.net/', target: '_top', tooltip: 'Justo duo' },
    { image: './img/Cloud_Upload.png', width: '50', height: '50', url: 'http://jquery-plugins.net/', target: '_top', tooltip: 'Ut wisi enim' },
    { image: './img/Coffee.png', width: '50', height: '50', url: 'http://jquery-plugins.net/', target: '_top', tooltip: 'Minim veniam' },
    { image: './img/Comments.png', width: '50', height: '50', url: 'http://jquery-plugins.net/', target: '_top', tooltip: 'Quis nostrud' },
    { image: './img/Credit_Card.png', width: '50', height: '50', url: 'http://jquery-plugins.net/', target: '_top', tooltip: 'Exerci tation' },

 ];


Ihr könnt ganz einfach den Parameter tooltip hinzufügen mit einem String der dann als Tooltip angezeigt werden soll.

Natürlich könnt ihr auch Text-Tags mit Tooltips kombinieren:


var entries = [ 
                
    { label: 'Dev Blog', url: 'http://niklasknaack.blogspot.de/', target: '_top', tooltip: 'Lorem ipsum' },
    { label: 'Flashforum', url: 'http://www.flashforum.de/', target: '_top', tooltip: 'Dolor sit amet' },
    { label: 'jQueryScript.net', url: 'http://www.jqueryscript.net/', target: '_top', tooltip: 'Consetetur sadipscing' },
    { label: 'Javascript-Forum', url: 'http://forum.jswelt.de/', target: '_top', tooltip: 'Sed diam' },
    { label: 'JSFiddle', url: 'https://jsfiddle.net/user/NiklasKnaack/fiddles/', target: '_top' },
    { label: 'CodePen', url: 'http://codepen.io/', target: '_top', tooltip: 'At vero' },
    { label: 'three.js', url: 'http://threejs.org/', target: '_top', tooltip: 'Nonumy eirmod' },
    { label: 'WebGLStudio.js', url: 'http://webglstudio.org/', target: '_top', tooltip: 'Stet clita' },
    { label: 'JS Compress', url: 'http://jscompress.com/', target: '_top', tooltip: 'Justo duo' },
    { label: 'TinyPNG', url: 'https://tinypng.com/', target: '_top', tooltip: 'Ut wisi enim' }

 ];


Wie schon in der alten Version müsst ihr das erzeugte entries Objekt mit an das settings Objekt übergeben. Beim settings Objekt sind ein paar optionale Parameter hinzugekommen. Hier eine Auflistung aller möglichen Parameter inklusive dem entries Objekt:

var settings = {

    entries: entries,
    width: 480,
    height: 480,
    radius: '65%',
    radiusMin: 75,
    bgDraw: true,
    bgColor: '#111',
    opacityOver: 1.00,
    opacityOut: 0.05,
    opacitySpeed: 6,
    fov: 800,
    speed: 2,
    fontFamily: 'Oswald, Arial, sans-serif',
    fontSize: '15',
    fontColor: '#fff',
    fontWeight: 'normal',
    fontStyle: 'normal',
    fontStretch: 'normal',
    fontToUpperCase: true,
    tooltipFontFamily: 'Oswald, Arial, sans-serif',
    tooltipFontSize: '11',
    tooltipFontColor: '#fff',
    tooltipFontWeight: 'normal',
    tooltipFontStyle: 'normal',
    tooltipFontStretch: 'normal',
    tooltipFontToUpperCase: false,
    tooltipTextAnchor: 'middle',//left, right
    tooltipDiffX: 0,
    tooltipDiffY: 20

};


Die frisch hinzugekommenen tooltipFont Parameter sind selbsterklärend. Mit tooltipTextAnchor gebt ihr an wie sich euer Tooltipp im Verhältnis zum Tag ausrichten soll. Bei Grafik-Tags empfiehlt sich 'left' und bei Text-Tags 'middle'. Mit tooltipDiffX und tooltipDiffY könnt ihr den Abstand zum Tag bestimmen.

Alles andere bleibt wie gehabt in der alten Version.
Schaut bei Fragen bitte erst in den alten Blogeintrag, da hier eine recht ausführliche Dokumentation mit enthalten ist. Ansonsten freue ich mich wie immer über Feedback und/oder Kommentare.
Zum Download gibt es wieder eine standard JS und auch eine minifizierte JS.

Bei Bedarf könnt ihr euch auch die Beispielseiten anschauen: Example 1, Example 2, Example 3 und Example 4.

Die hier in den Beispielen verwendeten Bilder/Icons sind von der Seite Smashing Magazine.

Update


GitHub
Das Projekt gibt es nun auch auf GitHub. Und hier geht´s zum GitHub Repository. Ihr findet hier immer die aktuelle Version und weitere Tutorials sowie Links.

JSFiddle

Hier ein weiteres Beispiel, das ihr direkt in JSFiddle betrachten und bearbeiten könnt.

9/18/2017

Sublime Text 3 toggle comment command doesn't work in Windows

Ein großes Ärgernis beim Arbeiten mit Sublime Text unter Windows ist das Problem, dass diverse Standard-Tastenkombinationen nicht funktionieren.
Mich hat besonders genervt, dass man Codezeilen, oder ganze Codeblöcke, nicht mit einer einfachen Tastenkombination auskommentieren kann. Schaut man in die Dokumentation, dann gibt es dafür Tastenkombinationen. Allerdings funktionieren diese nicht unter Windows.
Nach einer kleinen Recherche habe ich eine Lösung gefunden die wunderbar funktioniert und die ich an dieser Stelle mit euch teilen möchte. Wenn ihr auch mit ctrl + / bzw. mit deutscher Tastatur mit strg + / keine Codezeilen auskommentieren könnt, dann versucht auch mal folgendes.
Geht in Sublime Text im Menu auf den Punkt „Preferences“ und dort auf „Key Bindings“. Jetzt sollte sich ein neues Fenster öffnen das in etwa so aussieht wie dieses hier:


Hier findet ihr auch auf der linken Seite in dem Fenster (Default) die Standard-Tastenkombination für das togglen um Codezeilen ein-, bzw. auskommentieren zu können.


{ "keys": ["ctrl+/"], "command": "toggle_comment", "args": { "block": false } },
{ "keys": ["ctrl+shift+/"], "command": "toggle_comment", "args": { "block": true } },

Auf der rechten Seite im Fenster (User) müsst ihr nun ein paar Zeilen einfügen, und schon ist das Problem behoben. Setzt hier einfach diesen Schnipsel ein und speichert ab:


{ "keys": ["ctrl+7"], "command": "toggle_comment", "args": { "block": false } },
{ "keys": ["ctrl+shift+7"], "command": "toggle_comment", "args": { "block": true } }  

Das Ganze sollte jetzt so aussehen:


Geht zurück zu euerm Projekt und versucht erneut die Tastenkombination aus. Jetzt sollte es keine Probleme mehr geben und ihr könnt bequem per Tastenkombinationen (strg + /) togglen.

5/23/2017

Warp drive jQuery plugin

Wieder ein neues jQuery Plugin. Die Idee kam mir beim refaktorieren eines Header Experiments, das ich so auch bereits bei CodePen veröffentlicht hatte. Die Idee ist einfach. Jeder sollte die Möglichkeit bekommen so ein Sternenfeld, bzw. Warp drive in seine Seite einbinden zu können. Sei es als Seitenhintergrund oder als interaktive Animation unter einem Div.
Und so entstand dieses jQuery Plugin. Im Gegensatz zu der alten Version auf CodePen habe ich für das Plugin einige Optimierungen umgesetzt. So kann man jetzt unter anderem Farben auswählen und Geschwindigkeiten anpassen. Dazu gibt es einen autoResize-Modus und zahlreiche Parameter über die sich das Plugin individualisieren lässt.
Ich gehe an dieser Stelle nur sehr kurz auf die Technik ein.
Zum Einsatz kommen das Canvas Element und JavaScript. Dadurch sollte sichergestellt sein, dass auch ältere Browser in der Lage sind diesen Effekt darstellen zu können. Mit 4 KB im Zip-Format ist das Plugin recht schlank geworden. So entstehen keine langen Ladezeiten und euer Traffic geht nicht durch die Decke.
Wie bei meinen anderen jQuery Plugins könnt ihr diesen Effekt aber auch ohne jQuery auf eure Elemente anwenden.
Ich zeige euch erst ein paar Beispiele (Zu jedem Beispiel könnt ihr euch den Code anschauen). Danach gibt es die Download Links und die Links zum GitHub Repository, wo es zusätzlich zu den Beispielen weitere Links und Erklärungen gibt, wie ihr den Effekt einbinden und mit optionalen Parametern individualisieren könnt.


Beispiel 1:
view source

Beispiel 2:
view source

Beispiel 3:
view source

Beispiel 4:
view source

Beispiel 5:
view source

Beispiel 6:


Downloads
 

Bleibt mir nur noch euch viel Spaß zu wünschen und die Download Links anzubieten. Die jquery.warpdrive.min.js, wie hier in den Beispielen verwendet. Die jquery.warpdrive.js, falls ihr am Code interessiert seid und die jquery.warpdrive.min.js.zip als Zip.



GitHub

Und hier geht´s zum GitHub Repository. Hier findet ihr immer die aktuelle Version und weitere Tutorials sowie Links.
Wie immer gilt: Falls ihr Fragen oder Anregungen habt, dann hinterlasst einfach einen Kommentar oder schreibt mich an. 

5/19/2017

T800 Terminator Genisys particles experiment

Mit diesem Experiment will ich ein Stück weit die Grenzen des Machbaren ausreizen. Gezeichnet werden die Pixel direkt in die Canvas. Keine extra 3D Engine, bzw. Bibliothek ist hier sonst im Einsatz. Und auch kein WebGL. Somit verzichte ich hierbei ganz bewusst auf Hardwarebeschleunigung.
Auf einem Desktop-Rechner werden die knapp über 130.000 Partikel trotzdem sauber mit 60 FPS berechnet.
Als Model habe ich mich in diesem Fall für das „T800 Terminator Genisys“ Model von Machina Corp. entschieden. Der Grund dafür ist ganz einfach. Möglichst viele Details.
Ich habe das Model in Blender bearbeitet und dann als DAE exportiert. Aus dieser 16MB großen DAE habe ich dann die Werte für die Koordinaten vom Mesh kopiert und dann minifiziert in eine TXT-Datei eingefügt. Auf diese Weise konnte ich das Datenvolumen auf 2MB reduzieren.
Mit jQuery wird dann die so erzeugte TXT geladen und die Daten mit den Koordinaten von einem String in ein Array umgewandelt. Die jetzt folgenden Schritte basieren dann im Prinzip nur noch auf meinen älteren Experimenten.
Eigentlich wollte ich nur mal schauen wieviel
Partikel ich im dreidimensionalen Raum auf einmal darstellen/berechnen kann bei akzeptabler Performance. Und hier gibt’s das Ergebnis:
  Für den Fall das ihr das Experiment in einem extra Browser Tab anschauen wollt könnt ihr einfach hier klicken.

5/18/2017

SVG 3D Viewer

SVG befinden sich auf dem Vormarsch und damit verbunden viele neue und interessante Entwicklungen. 
Das auf XML basierende Format ist nicht nur für Gestalter und Kreative sehr interessant, sondern auch für Entwickler.
Da man über die XML-Struktur direkten Zugriff auf die Inhalte bekommt, kann man Elemente des SVG-DOM mit Hilfe eingebetteter Scriptsprachen wie JavaScript manipulieren. Auf diese Weise kann eine statische SVG dynamisiert werden und z.B. bestimmte Koordinaten animiert/verändert werden. So kann man unter anderem das Path-Element im SVG manipulieren, das für die Darstellung so gut wie aller
Grafikelemente in einem SVG verantwortlich sein kann. Genauso ist es möglich Farbwerte auszulesen und abzuändern. Und ebenso ist es möglich auf diese Weise online einen Editor für SVG zur Verfügung zu stellen, der nur auf JavaScript basiert.
 

Und genau hier greift meine Idee die Koordinaten der Pfade einer SVG auszulesen, bzw. zu parsen, diese in pseudo 3D umzurechnen, die der User dann in Echtzeit manipulieren kann und dann im Anschluss wieder in 2D zurückumgewandelt als SVG ausgeben zu lassen.
Klingt etwas sperrig, aber im Prinzip ist es ganz einfach. Der User kann eine SVG laden und diese dann im dreidimensionalen Raum rotieren und skalieren. Zusätzlich hat der User noch Einfluss auf die im SVG verwendeten Farben. Als Gimmick kann das so vom User manipulierte SVG abgespeichert (Bei den Einstellungen unter „Open Controls
zu finden) und dann problemlos für andere Zwecke weiterverwendet werden.

(Original SVG File)

Der SVG 3D Viewer ist noch im absoluten Experimentierstadium. So werden aktuell keine Farbverläufe unterstützt. Ebenso kommt es zu Problemen, wenn die Maße der SVG größer sind als die Fläche (480x480px) des Viewers selbst. Besonders detailreiche SVG bringen den Viewer noch an seine Grenzen und lassen die Performance einbrechen.

Im folgenden Screenshot der Browser-Konsole sieht man die neu berechneten Koordinaten im Path-Element einer dynamisch geladenen SVG: 




Das Parsen der SVG ist mit dem SVG Path Parser von Jake Rosoman realisiert.
Die hier gezeigten SVG-Logos sind bis auf 2 Ausnahmen Eigenproduktionen. Das Logo zu Beginn ist das Firmenlogo von anyMOTION GRAPHICS. Das zweite Logo das nicht von mir stammt ist das offizielle Logo von Fortuna Düsseldorf.

5/08/2017

Pure JavaScript planetoid particles with light source and bumpmapping

Die Idee für dieses Experiment kam mir als ich bei Oleg Pashkovsky die „Animation with code #12“ sah und mich an ein älteres meiner Experimente erinnerte.
Das Ziel war nun eine Art Kombination beider Experimente. Ich wollte es ermöglichen einen ähnlichen Look zu erhalten wie bei Oleg und gleichzeitig verschiedene Planetoiden im dreidimensionalen Raum zu visualisieren.
Mit meinen vergangenen 3D Partikelexperimenten war bereits der Grundstein gelegt. Es blieb nur ein großes Problem. Für die Szene brauchte ich eine Lichtquelle. Und genau eine solche Lichtquelle hatte ich bisher noch nicht in meine Experimente mit implementiert. Da ich bei den Canvas Experimenten auf 3D Frameworks wie z.B. Three.js verzichte, musste ich eine Lösung finden das Ganze von Grund auf neu zu schreiben. Mein Glück, ich hatte noch das Buch „Foundation HTML5 Animation with JavaScript“
(Affiliatelink) von Keith Peters im Bücherregal stehen. Hier fand ich einen simplen Ansatz für eine rudimentäre Umsetzung einer Lichtquelle die nicht zu viel Rechenleistung beansprucht. 
var dotProd = particle.vx * light.x + particle.vy * light.y + particle.vz * light.z;

var normMag = Math.sqrt( particle.vx * particle.vx + particle.vy * particle.vy + particle.vz * particle.vz );

var lightMag = Math.sqrt( light.x * light.x + light.y * light.y + light.z * light.z );

var lightFactor = ( Math.acos( dotProd / ( normMag * lightMag ) ) / Math.PI ) * light.brightness;
Darüber hinaus sind in diesem Experiment weitere Neuerungen zu sehen die ich so bisher noch nicht umgesetzt hatte. Wenn man sich den Erdball aus meinem alten Experiment anschaut, dann sieht man die wenig schöne Verteilung der Partikel zur Abbildung des Planetoiden. Die jetzige Verteilung der Partikel ist da deutlich homogener. Aber auch hierbei gab es ein Problem. Die Platzierung der Partikel war Abhängig von den Koordinaten der Textur. Die damals eingesetzte Methode um Pixel-Koordinaten in Latitude und Longitude umzurechnen und dann auf eine Sphere zu mappen war also hinfällig. Die Lösung war der umgekehrte Weg. Ich erstelle die Sphere für den Planetoiden und hole mir dann erst die nötigen Pixel-Koordinaten zum Auslesen der Farbwerte aus der Textur. Die Lösung hierfür sind UV-Koordinaten. Mit erstaunlich wenig Mathe kommt man auf diesem Weg an 2D Koordinaten aus einer 3D-Sphere. 
p = p.normalize();

var u = Math.atan2( p.x, p.z ) / ( 2 * Math.PI ) + 0.5; 
var v = Math.asin( p.y ) / Math.PI + 0.5;

var x = u * texture.width;
var y = v * texture.height;
Und zu guter Letzt wollte ich dann noch Bumpmapping implementieren, damit die Oberfläche der Planetoiden plastischer und detailreicher erscheint. Normalerweise geschieht das über eine Bumpmap, oder auch height map genannt. Ich bin für dieses Experiment aber einen ganz anderen Weg gegangen. Ich berechne für jedes Partikel einen Wert, der auf der Basis der Farbe des Partikels basiert. Daraus ergibt sich ein Prozentwert. Eine Art Schwellenwertverfahren. Weiß ist also 100% und schwarz ist 0%. Mit einer simplen Formel multipliziere ich jetzt diesen Prozentwert in Kombination mit einer Variablen für die Stärke des Effekts zu den Koordinaten der Partikel. Auf diese Weise bekommen hellere Partikel einen größeren Radius als dunkle Partikel. Ein z.B. ein dunkles Tal auf dem Planetoiden ist somit also tatsächlich tiefer als ein heller Berg. Im Gegensatz zum klassischen Bumpmapping nehme ich in diesem Experiment also sehr wohl Einfluss auf die Geometriekomplexität. Da ich aber keinen Namen für diesen von mir eingesetzten Weg habe wird hier einfach, und vielleicht fälschlicher Weise, von Bumpmapping gesprochen.
var threshold = ( particle.color.r + particle.color.g + particle.color.b ) / 3;

var percent = threshold / 255;

var distance = ( percent / bumpScale ) + 1;

particle.x *= distance;
particle.y *= distance;
particle.z *= distance;

Genug erzählt. Komment wir endlich zum Experiment. Ich empfehle wie immer das Experiment in einem neuen Browser Tab zu öffnen. Ihr könnt es euch aber auch gleich hier unterhalb auf dieser Seite anschauen. Über den Button „Open Controls“ könnt ihr diverse Einstellungen vornehmen und verschiedene Texturen laden.




Die kleine Sphere in diesem Experiment symbolisiert die Lichtquelle. Verschwindet diese Lichtquelle hinter dem Planetoiden wird sie durch ein kleines rotes Kreuz visualisiert.
Ihr könnt mit Hilfe der Einstellungen die Anzahl der Partikel auf bis zu 125000 steigern. Auf diese Weise lässt dich der Detailgrad erhöhen, aber dafür kann die Performance leiden. Falls euer Rechner schon etwas älter ist könnte es also auch sinnvoll sein die Anzahl zu verringern. Ansonsten könnt ihr, wie bei meinen anderen Experimenten auch, die Szene abhängig von eurer Mausposition drehen. Für User mit mobilen Geräten und Touchscreen sind Touch-Events implementiert mit denen ihr die Szene ebenfalls steuern könnt. 

Die Texuren für den Planetoiden kommen von Planet Texture Maps und von Robert Stein III. Die Texturen habe ich lediglich in der Größe angepasst. Ansonsten entsprechen sie den Originalgrafiken.
Verlinkungen zu Amazon in diesem Blogpost sind so genannte Affiliate Links.

4/05/2017

Wobble window jQuery plugin

Es gibt unzählige Tutorials und Code Snippets mit denen man HTML-Elemente „wobblen“ lassen kann. In den meisten Fällen geht es aber eher darum Elemente zu schütteln, bzw. einen shake-Effekt anzuwenden.
Ich wollte allerdings einen wobble-Effekt schreiben, der sich auf die Form von einem DIV bezieht.  Genauer gesagt, ein Effekt der die Form von einem DIV beeinflusst. Das Ganze abhängig von der Mausposition. So entstand das „Wobble window jQuery Plugin“. Über diverse optionale Parameter könnt ihr mit Hilfe vom „Wobble window jQuery Plugin“ einen Hintergrund für ein beliebiges DIV erzeugen, welcher seine Form abhängig von der Mausposition verändert. Der Hintergrund wobblet/wabert und so entsteht ein interessanter Effekt der an eine Flüssigkeit erinnert.
Zuerst gesehen hatte ich diesen Effekt bei Paul Neave. Damals, genauer gesagt 2006, hatte ich den Effekt in Flash nachgebaut. Und jetzt war es endlich mal an der Zeit den Effekt in HTML5 zu überführen und dabei auch für andere Entwickler nutzbar zu machen. Daher die Idee mit dem jQuery Plugin.
Zum Einsatz kommen das Canvas Element und JavaScript. Dadurch sollte sichergestellt sein, dass auch ältere Browser in der Lage sind diesen Effekt darstellen zu können. Mit 3 KB im Zip-Format ist das Plugin recht schlank geworden. So entstehen keine langen Ladezeiten und euer Traffic geht nicht durch die Decke.
Wie bei meinen anderen jQuery Plugins auch könnt ihr diesen Effekt aber auch ohne jQuery auf eure Elemente anwenden.
Ich zeige euch erst ein paar Beispiele (Zu jedem Beispiel könnt ihr euch den Code anschauen). Danach gehe ich noch etwas konkreter auf den Code ein, damit ihr das „Wobble window jQuery Plugin“ direkt nutzen könnt.


Beispiel 1:
view source

Beispiel 2:
view source

Beispiel 3:
view source

Beispiel 4:
view source

Beispiel 5:
view source

Beispiel 6:
view source

Und hier nun ein paar Beispiele wie ihr das in eurer Webseite einbinden könnt. Zunächst einmal müsst ihr die JS Dateien in eure Seite einbinden:



Danach könnt ihr direkt starten. Mit jQuery sieht das wie folgt aus:
$( '#window' ).wobbleWindow();

Und so ohne jQuery:
var wobbleWindow = new WobbleWindow( document.getElementById( 'window' ) );

Natürlich könnt ihr noch diverse Parameter an das Plugin übergeben um den Effekt zu individualisieren. Ein solches Objekt zu erstellen ist optional, aber hier der Vollständigkeit wegen das Objekt mit allen möglichen Parametern:
var settings = {

    name: 'my_window',//name
    depth: 1,//depth for zIndex
    offsetX: 0,//+ or - value the size of the div
    offsetY: 0,//+ or - value the size of the div
    moveTypeIn: 'move',//method points follow the mouse
    moveTypeOut: 'wobble',//method points go back to init position
    wobbleFactor: 0.9,//control the wobble effect
    wobbleSpeed: 0.1,//control the wobble speed
    moveSpeed: 3,//control the move speed
    lineWidth: 1,//lineWidth
    lineColor: '',//no value = no line. Use hex/rgba values
    bodyColor: '#FFF',//no value = no body color. Use hex/rgba values
    numberOfXPoints: 7,//quantity of points horizontal. must be an odd int
    numberOfYPoints: 5,//quantity of points vertical. must be an odd int
    movementLeft: true,//enable/disable movement directions
    movementRight: true,//enable/disable movement directions
    movementTop: true,//enable/disable movement directions
    movementBottom: true,//enable/disable movement directions
    autoResize: true,//if true size will be automatically adjusted
    autoResize: true,//enable/disable automatic size adjustement
    debug: false//enable/disable debug mode

};

Wollt ihr das Plugin mit Parametern starten, dann sieht der Aufruf mit jQuery wie folgt aus
$( '#window' ).wobbleWindow( settings );

Und so ohne jQuery:
var wobbleWindow = new WobbleWindow( document.getElementById( 'window' ), settings );

Downloads

Das wars schon. Bleibt mir nur noch euch viel Spaß zu wünschen und die Download Links anzubieten. Die jquery.wobblewindow.min.js, wie hier in den Beispielen verwendet. Die jquery.wobblewindow.js, falls ihr am Code interessiert seid und die jquery.wobblewindow.min.js.zip als Zip.




GitHub

Und hier geht´s zum
GitHub Repository. Hier findet ihr immer die aktuelle Version und weitere Tutorials sowie Links.

Wie immer gilt: Falls ihr Fragen oder Anregungen habt, dann hinterlasst einfach einen Kommentar oder schreibt mich an.

3/24/2017

Water ripple effect jQuery plugin

Ich war von dem „water ripple effect“ schon immer fasziniert und so wurde es mal Zeit sich mit damit zu beschäftigen. Rausgekommen ist dabei ein kleines jQuery Plugin, welches ihr komfortabel in euren Projekten mit einbinden könnt. Wie bei meinen letzten jQuery Plugins auch, könnt ihr den „water ripple effect“ mit, oder ohne jQuery benutzen. Als Zip und minifiert ist dieses Plugin nur knapp 2KB groß.
Ursprünglich für Java von Neil Wallis geschrieben und später von Sergey Chikuyonok für JavaScript adaptiert, musste ich das Rad nicht neu erfinden. Ich habe lediglich versucht den Code noch an ein paar Stellen weiter zu optimieren.
Zum Einsatz kommen die Canvas und gutes altes JavaScript. Dadurch ist sichergestellt, dass eine maximale Abwärtskompatibilität erreicht wird. So sollten auch ältere Browser in der Lage sein den Effekt darzustellen. Trotz Optimierungen kostet der Effekt allerdings noch immer gut Rechenpower. Ihr solltet also darauf achten nicht zu große Bilder zu verwenden.

Hier könnt ihr euch eine Demo anschauen:



Folgend ein paar Beispiele wie ihr den Effekt in euer Projekt einbinden könnt. Zunächst mit jQuery, bzw. als jQuery Plugin.




Zuerst einmal müsst ihr jQuery und danach dann das Plugin in eure Seite einbinden.
var settings = {

    image: './img/SwimmingPool.jpg',//image path
    rippleRadius: 3,//radius of the ripple
    width: 480,//width
    height: 480,//height
    delay: 1,//if auto param === true. 1 === 1 second delay for animation
    auto: true//if auto param === true, animation starts on it´s own

};

Als nächstes erstellt ihr ein Objekt. Mit diesem könnt ihr diverse Parameter übergeben. Unverzichtlich ist der Parameter image, mit dem ihr angeben müsst wo das Bild liegt das ihr für den Effekt verwenden wollt. Mit rippleRadius bestimmt ihr den Radius der Wellen. Die Parameter width und height geben an wie groß euer Bild ist. Der Parameter delay kommt ins Spiel wenn ihr den Parameter auto auf true stellt. Steht auto auf true läuft die Animation automatisch ab und mit dem delay könnt ihr bestimmen wie schnell
$( '#holder' ).waterRippleEffect( settings );

Hiermit startet, bzw. initiiert ihr den Effekt. holder ist ein einfaches Div. Wie ihr seht wird an dieser Stelle das eben erstellte Objekt settings mit übergeben.
Soweit so gut. False ihr bei den settings auto auf true gestellt habt dann seid ihr im Prinzip schon fertig.
Wollt ihr das Ganze mit der Maus beeinflussen, dann könnt ihr z.B. folgendes schreiben:

$( '#holder' ).click( function( e ) {

    var mouseX = e.pageX - $( this ).offset().left;
    var mouseY = e.pageY - $( this ).offset().top;

    $( '#holder' ).waterRippleEffect( "disturb", mouseX, mouseY );

} );

So erscheinen die Wellen per Klick an der aktuellen Mausposition.
$( '#holder' ).mousemove( function( e ) {

    var mouseX = e.pageX - $( this ).offset().left;
    var mouseY = e.pageY - $( this ).offset().top;

    $( '#holder' ).waterRippleEffect( "disturb", mouseX, mouseY );

} );

Und so per Mousefollow.

Ihr benutzt kein jQuery? Kein Problem. Dann macht es einfach wie folgt ohne jQuery:



Ihr bindet nur die jquery.waterrippleeffect.min.js in eure Seite mit ein.
Der part mit dem settings Objekt ist 1zu1 gleich wie oben für die jQuery Variante beschrieben, weshalb ich das an dieser Stelle nicht noch einmal wiederhole. Ihr könnt diesen Part einfach so von oben übernehmen.
So startet ihr den Effekt:

var waterRippleEffect = new WaterRippleEffect( document.getElementById( 'holder' ), settings );

holder ist hier wieder ein Div und auch hier wird das settings Objekt mit den Parametern für den Effekt übergeben.
Wollt ihr das Ganze per Mausklick steuern ergänzt folgendes:

document.getElementById( 'holder' ).addEventListener( 'click', function( e ) {

    var mouseX = e.layerX;
    var mouseY = e.layerY;

    waterRippleEffect.disturb( mouseX, mouseY );

} );

Für einen Mouse-Follow schreibt ihr einfach:
document.getElementById( 'holder' ).addEventListener( 'mousemove', function( e ) {

    var mouseX = e.layerX;
    var mouseY = e.layerY;

    waterRippleEffect.disturb( mouseX, mouseY );

} );

Das wars. Mehr ist nicht nötig. Ihr könnt euch auch die Demo oben direkt anschauen und den Code aus dem HTML File entnehmen. Dazu einfach hier klicken.

Zum Download stelle ich euch drei Varianten zur freien Verfügung. Die jquery.waterrippleeffect.min.js wie hier in den Beispielen verwendet. Die jquery.waterrippleeffect.js, falls ihr mal hinter die Kulissen schauen wollt und die jquery.waterrippleeffect.min.js.zip als Zip.

Viel Spaß mit diesem jquery Plugin. Falls ihr Fragen oder Anregungen habt würde ich mich über ein paar Kommentare freuen.

 

3/17/2017

Tornado Simulation

Die Tornado Simulation ist ein Experiment das ich schon seit langem starten wollte. Und mit meiner 3D Particle-Engine, die jetzt schon in so zahlreichen anderen Experimenten zum Einsatz kam, und etwas Zeit ließ sich diese Simulation jetzt endlich mal umsetzen.
Für die Simulation selbst kommen keine weiteren Frameworks wie z.B. Three.js zum Einsatz. Einfach pures JavaScript. Dadurch konnte ich auch in diesem Experiment die Dateigröße mit 13KB recht klein halten.
Zum Rendern nutze ich das Canvas-Element und das ImageData Interface um Zugriff auf die Pixel zu bekommen.
Wer sich für dieses Thema interessiert, ich hatte dazu mal ein Tutorial geschrieben.
Aber zurück zum Tornado. Ziel war es im weitesten Sinn eine möglichst realistische Simulation eines Tornados mit den zur Verfügung stehenden Mitteln zu realisieren.
Die Höhe des Tornados ergibt sich aus der Anzahl der „Radial Segments“. Diese sind in einer sich drehenden Spirale angeordnet, die nach oben hin exponentiell größer wird. Auf die Animation der Verschiebung der Spirale könnt ihr mit „Spiral Disp.“ Einfluss nehmen. Um jedes der „Radial Segments“ kreisen die „Tubular Segments“. Deren Anzahl kann nur auf ein Maximum festgelegt werden, da hier der Zufall mitbestimmt wie viele „Tubular Segments“ pro „Radial Segment“ generiert werden. Jedes einzelne „Tubular Segment“, also Partikel, erhält einen per Zufall generierten Graustufen-Wert und kann eine Spur hinter sich herziehen, deren maximale Länge ihr in den Einstellungen per „Max Trail Length“ beeinflussen könnt. Auch auf die Geschwindigkeit und Drehrichtung der Partikel könnt ihr mit „Max Speed“ Einfluss nehmen. Mit „Min Radius“ könnt ihr zudem noch festlegen wie groß/klein der Radius des Tornados unten am Boden ist.
Geht einfach mal in die Einstellungen mit „Open Controls“ und spielt mit den Werten. Aber bitte etwas vorsichtig. Langsame Rechner könnten hierbei schnell an ihre Grenzen gebracht werden!
Ihr könnt die Anwendung direkt hier unterhalb starten (einfach mit der Maus über das untenstehende Fenster fahren), oder ihr öffnet die Simulation in einem neuen Browserfenster. Vor allem User mit mobilen Endgeräten und älteren Rechnern sollten sich die Simulation in einem extra Fenster anschauen.
Viel Spaß und haltet eure Hüte fest.

 

3/09/2017

Lissajous Curve

Die Lissajous-Figur ist aus mathematischer Sicht das parametrische Schaubild einer Funktion erfunden vom französischen Physiker Jules Antoine Lissajous.
Hier umgesetzt mit JavaScript ohne weitere Frameworks und dadurch unter 15KB klein.
Spielt einfach mal mit den Parametern. Damit lassen sich interessante Ergebnisse erzielen. Um ein harmonisches Ergebnis zu erziehlen, sollten die Werte der drei Parameter W1, W2 und W3 nah beieinander liegen. Wie z.B. in den Voreinstellungen sichtbar.

Ihr könnt die Anwendung direkt hier unterhalb anschauen, oder, besonders für mobile Endgeräte empfehlenswert, in einem neuen Browserfenster.

3/06/2017

Dwitter!

Dwitter? Du meinst bestimmt Twitter! Nein, Dwitter.
Was ist Dwitter? „A social network for short JavaScript demos“.
Dwitter ähnelt Twitter sehr. Nur mit dem Unterschied, dass man mit den 140 Zeichen (bytes) keine Textnachrichten verfasst, sondern kleine JavaScript Demos programmiert.
Die große Herausforderung, und gleichzeitig auch der Reiz, besteht darin, sein Vorhaben in 140 Zeichen Code zu verpacken. Dabei muss man seinen Code brutal optimieren und lernt immer wieder neue Kniffe und Tricks um hier und da ein paar Zeichen einzusparen. Natürlich gibt es Tools wie z.B. das sehr empfehlenswerte „JavaScript Compression Tool“ und andere, aber deren Einsatz allein reicht in den meisten Fällen nicht aus, oder kann nur unterstützend eingesetzt werden.
Am besten schaut man sich andere Beispiele auf Dwitter an und versucht deren Code zu verstehen. So kann man ziemlich schnell viele Tricks zum optimieren seines Codes sammeln.
Hier mal meine ersten Gehversuche auf Dwitter:
https://www.dwitter.net/u/Niklas 

Und hier eine kleine Auswahl meiner Favoriten Dweets:
https://www.dwitter.net/d/701
https://www.dwitter.net/d/1494
https://www.dwitter.net/d/1231
https://www.dwitter.net/d/855
https://www.dwitter.net/d/433
https://www.dwitter.net/d/1829
https://www.dwitter.net/d/915
https://www.dwitter.net/d/1232

2/21/2017

Tentacle Creature

Und wieder ein three.js Experiment.
Warum Tentakeln? Weil ich mit dem Ergebnis in dem Experiment zuvor nicht zufrieden bin. Bei „Procedurally generated trees in JavaScript“ sehen die Baumstämme und Äste einfach viel zu wenig natürlich aus. So gerade und abgehakt wachsen keine Pflanzen und auch die Verbindungen der Äste untereinander wird man so nicht in der Natur vorfinden.
Auf der Suche nach einer Lösung bin ich über die TubeGeometry gestolpert. Mit dieser lässt sich die Form einer Röhre abbilden. Und, für mich besonders wichtig, man kann ihr einen Pfad mit Koordinaten mitgeben und die TubeGeometry richtet sich danach aus. Und das allerbeste, die TubeGeometry akzeptiert als Pfad auch eine CatmullRomCurve3. Eine Kurve, bzw. etwas genauer gesagt ein Spline, die eine gegebene Anzahl an Kontrollpunkten sehr soft miteinander verbindet. Stichwort: Kubisch Hermitescher Spline, oder auch Centripetal Catmull–Rom spline.
Das einzige Problem das jetzt noch bestand war, dass die TubeGeometry nur einen Radius als Parameter akzeptiert. Gibt man ihr einen Radius von 3, dann hat sie an ihrem Anfangspunkt den selben Radius 3 wie am Endpunkt. Mein Ziel aber was es einen Start, und einen End-Radius definieren zu können. So soll es z.B. möglich sein, dass sich die Röhre zum Ende hin konisch verjüngt. Um das zu erreichen musste ich die TubeGeometry umschreiben. Herausgekommen ist dabei die TentacleGeometry.js. Und weil mich beim Entwickeln die ersten Formen so stark an Tentakeln erinnerten ist dieses Experiment hier entstanden. Das Ganze ist also eher nur ein Zwischenschritt für ein neues „Procedurally generated trees“-Experiment.
Ihr könnt das Experiment direkt hier starten, oder ihr öffnet die Anwendung in einem neuen Browser-Fenster.


2/07/2017

Procedurally generated trees in JavaScript


Das Thema ist nicht ganz neu für mich. Bereits 2006 und 2007 hatte ich damals noch mit Flash erste Gehversuche gestartet. Allerdings noch in 2D und aus heutiger Sicht wenig schön anzusehen.
Jetzt bin ich nicht nur einen anderen Weg gegangen, sondern auch einen Schritt weiter.
Bei dem neuen Experiment ist eine Dimension hinzugekommen und umgesetzt ist das Ganze nun mit JavaScript. Als 3D Bibliothek kommt wie zuletzt auch wieder three.js zum Einsatz.
Mit Hilfe einer rekursiven Funktion und vielen per Zufall generierten Werten erzeuge ich hier Bäume, oder zumindest baumähnliche Gebilde. Wie immer, wenn der Zufall im Spiel ist, kann es auch mal Überraschungen geben. Damit die Performance auch auf älteren Rechnern stimmt, habe ich es mit den Wachstumszyklen nicht übertrieben. Aber schaut einfach selbst.
Ihr könnt direkt hier starten, oder ihr öffnet die Anwendung in einem neuen Browser-Fenster.


 

10/14/2016

Raspberry Pi als DLNA-Medienserver mit ReadyMedia einrichten

In diesem Tutorial möchte ich euch beschreiben, wie ihr mit eurem Raspberry Pi einen kostenlosen DLNA-Medienserver für euer Heimnetzwerk einrichten könnt und die Daten von euren USB Devices (Festplatten & Sticks) anderen Geräten in eurem Heimnetzwerk per WLAN zur Verfügung stellt.

An wen richtet sich dieses Tutorial: Noobs, Anfänger und Fortgeschrittene.

Im Netz gibt es zum Thema DLNA schon einige Tutorials, aber keines davon führte mich zum Ziel. Daher die Idee mit diesem Tutorial, das euch hoffentlich hilft und die Zeit für die Einrichtung verkürzt.

Kurz vorweg, ich bin kein Linux Experte und besitze meinen Raspberry Pi 3 Model B erst seit ein paar Tagen. Ich bin eigentlich ein Windows User und habe diverse USB Festplatten und fand es immer schon lästig, wenn man z.B. die Fotos, Filme und Musik von den USB Devices auf anderen Geräten im Haushalt wiedergeben wollte. 


Das Ziel dieses Tutorials ist es also, dass ihr, wenn ihr ein oder mehrere USB Devices habt, diese an euer Raspberry Pi (direkt oder per USB-Hub) anschließen könnt und dann mit euren DLNA-fähigen Geräten per WLAN auf die Medien, die auf diesen Geräten gespeichert sind, zugreifen könnt. Wir fangen bei Null an mit einem jungfräulichen Raspberry Pi und am Ende habt ihr ein komplett konfiguriertes System.


 

Setup

 

Mein PC Setup:
- Windows 8 PC mit Putty SSH Client installiert
- SD-Karten Lesegerät (bei vielen schon mit eingebaut)
- Diverse externe USB Festplatten


Mein Raspberry Pi Setup:
- Raspberry Pi 3 Model B
- Raspberry Pi 3 Gehäuse von KuGi
- Rydges SpeedPower High-Quality PC Netzteil
- EasyAcc Superspeed USB 3.0 7 Port Hub
- SanDisk Extreme 32GB Class 10 microSDH
- AmazonBasics Hochgeschwindigkeits-HDMI-Kabel

Die hier aufgezählten Produkte sind Affiliate-Links

Hinweis: Falls ihr euren Pi bereits angeschlossen und aufgesetzt habt, könnt ihr die folgenden Abschnitte überspringen und direkt mit zum Punkt DLNA-Medienserver einrichten weitergehen. Für alle anderen gibt es hier eine ausführliche Anleitung mit ersten Schritten wie ihr euren Pi einrichten könnt.

 

Raspberry Pi anschließen und installieren


Nachdem ihr den Raspberry Pi angeschlossen habt kann es eigentlich schon direkt losgehen.
Ich habe hier einen Monitor stehen mit zwei HDMI Eingängen. Am einem hängt der PC und an dem anderen der Raspberry Pi. Ich kann also immer zwischen beiden Geräten hin und her switchen. Falls ihr mehrere Monitore habt, dann ist das natürlich noch bequemer. Natürlich solltet ihr noch, zumindest für den Anfang, eine Maus und eine Tastatur an euren Raspberry Pi klemmen. Zur Not könnt ihr aber auch diese Geräte switchen und für PC & Pi nutzen. Ist dann etwas lästig mit den Kabeln, aber ich habe in diesem Tutorial versucht darauf zu achten, dass ihr den Pi nur einmal zu Beginn mit Maus und Tastatur ansteuern müsst. Wenn ihr mit den ersten Schritten durch seid, dann steuert ihr den Pi komplett von eurem PC aus.

 

Los geht’s


Installiert euch zuerst einmal PuTTY auf eurem PC, damit ihr später per SSH auf euren Pi zugreifen könnt. Später mehr dazu.

Jetzt zur SD-Karte, um genau zu sein zur microSD-Karte, denn der Pi schluckt nur die kleinen Karten. Bei der von mir verlinkten Karte ist ein SD-Karten Adapter dabei, damit ihr die Daten auch mit eurem PC auf die Karte bekommt. Jetzt spielt ihr das Betriebssystem auf die Karte. Dazu könnt ihr einfach auf die offizielle Raspberry Pi Webseite gehen und klickt dort auf den Menüpunkt DOWNLOADS. Dort ladet ihr euch dann NOOBS runter. Ich habe einfach die ZIP heruntergeladen.



Wenn der Download abgeschlossen ist entpackt ihr die ZIP einfach und kopiert den Inhalt auf eure SD-Karte. Danach entnehmt ihr die microSD-Karte aus dem Adapter und steckt sie in den Pi. Jetzt klemmt ihr das Stromkabel an den Pi. Soweit so gut. Der Pi startet nun. Ihr folgt einfach den Installationsanweisungen und installiert NOOBS, bzw. Raspbian. Mit wenigen Mausklicks und ein paar Minuten Geduld läuft euer System. 

Stellt nun die Verbindung zu eurem WLAN her. 



Danach öffnet ihr die Konsole. 



Bevor ihr weitermacht, empfiehlt es sich euer System auf den neuesten Stand zu bringen.
Gebt dazu folgendes ein um eure package list zu updaten:


sudo apt-get update


Und jetzt gebt ihr noch folgendes ein um eure packages zu upgraden:


sudo apt-get upgrade


Nach ein paar Minuten ist auch dieser Prozess abgeschlossen und es kann weiter gehen.

 


SSH Zugriff unter Raspbian einrichten




Damit ihr gleich den Pi von eurem PC aus steuern könnt sind noch ein paar Schritte notwendig.
Solltet ihr eine ältere (bei der aktuell verlinkten Version ist das nicht nötig) oder eine andere Distribution haben, dann müsst ihr den SSH-Server manuell installieren.
Gebt dazu folgendes ein wenn nötig:


sudo apt-get install ssh


Jetzt könnt ihr den SSH-Server starten. Dieser Schritt ist in jedem Fall nötig:


sudo /etc/init.d/ssh start


Damit der SSH-Server automatisch bei jedem Neustart vom Pi startet, empfehle ich noch folgendes einzugeben:


sudo update-rc.d ssh defaults

Nun müsst ihr noch die IP-Adresse von eurem Pi herausfinden.
Gebt dazu folgendes in die Konsole ein:


ifconfig


Jetzt schaut ihr bei wlan0 nach der inet Adresse.
In meinem Fall lautet die IP-Adresse: 192.168.0.21
Notiert euch die IP-Adresse bevor ihr weiter macht.





Wechselt nun zu eurem PC und startet PuTTY. Dort gebt ihr in das Feld Host Name (or IP address) eure eben ermittelte IP-Adresse ein. Damit ihr das nicht immer wieder machen müsst empfiehlt es sich eine Session zu speichern. Klickt nun auf Open.



 

Es sollte sich eine Konsole öffnen, die euch fragt mit welchen Zugangsdaten ihr euch beim Pi anmelden wollt.



Die Default Zugangsdaten sind immer:
User: pi
Password: raspberry

 
Gebt nun also zuerst pi ein und bestätigt mit Enter.





Jetzt das Passwort raspberry eingeben und wie immer mit Enter bestätigen. 

Nicht wundern: Bei der Eingabe des Passworts erscheinen keine Symbole in der Konsole.
Solltet ihr die Zugangsdaten korrekt eingegeben haben, dann erscheint der folgende Screen und ihr seid startklar um den DLNA-Server einzurichten. 




 

DLNA-Medienserver einrichten


Da der Pi nur über wenige USB-Anschlüsse verfügt, empfiehlt es sich einen USB-Hub zu verwenden. Ich habe oben den USB-Hub verlinkt den ich benutze.
Wichtig, wenn eure USB Devices nicht über eine eigene Stromversorgung verfügen ist ein USB-Hub mit Stromversorgung Pflicht. Der Pi schafft es ansonsten häufig nicht die angeschlossenen Geräte alle mit ausreichend Strom zu versorgen. Es kann auch zu Abstürzen kommen. Erspart euch das also am besten und benutzt z.B. den von mir verlinkten USB-Hub oder einen eurer Wahl.
Schließt eure Festplatten usw. jetzt am Pi, bzw. am Hub an und startet diese, falls die Geräte einen eigenen An- / Ausschalter haben. Wartet ggf. ein paar Sekunden bis die Geräte alle laufen.

In meinem Fall habe ich drei externe Festplatten mit den Namen Volume, TREKSTOR und G-Drive angeschlossen. Ich erkläre das ganze Prozedere daher von diesem Setup ausgehend.

Als DLNA-Server verwenden wir ReadyMedia. Besser bekannt unter dem früheren Namen MiniDLNA.
Bevor wir weitermachen: Ich verwende in diesem Tutorial immer den Namen MiniDLNA. Bitte nicht davon irritieren lassen. Da der DLNA-Server in der Konsole auch über den Namen minidlna angesteuert wird macht das aus meiner Sicht Sinn.

Wir installieren jetzt aber noch nicht den DLNA-Server, sondern kümmern uns erst einmal um die Datenträger(Festplatten und/oder USB-Sticks). Die wollen wir mounten. Um das machen zu können benötigen wir die UUID und den TYPE der Geräte.
Um an diese Daten zu kommen geben wir in der Konsole ein:


sudo blkid


Ihr erhaltet eine Liste in der ihr nach euren Datenträgern suchen müsst. In dem folgenden Screenshot seht ihr wie das in meinem Fall aussieht. Zu sehen sind die UUID´s und die TYPEn der einzelnen Geräte. Notiert euch diese Daten und haltet euch bereit diese im übernächsten Schritt einzugeben.





Nun müssen wir Verzeichnisse erstellen in die wir die Datenträger mounten. Für jeden Datenträger ein Verzeichnis. In meinem Fall sind das nach Adam Riese 3 Verzeichnisse. Ich war bei der Benennung nicht besonders kreativ und habe als Namen HDD1 (für Volume), HDD2 (für TREKSTOR) und HDD3 (für G-Drive) gewählt. Natürlich könnt ihr hier nach Belieben auch andere Namen wählen. Zusätzlich zum Erstellen der Verzeichnisse müssen wir uns auch noch um deren Rechte kümmern, damit verschiedene User Zugriff haben.
Am Beispiel für HDD1. So wird das Verzeichnis erstellt:


sudo mkdir -p /media/HDD1


Und so vergeben wir die Rechte für HDD1:


sudo chmod 755 /media/HDD1


Dieses Prozedere wiederholen wir jetzt noch für die anderen Datenträger/Verzeichnisse:


sudo mkdir -p /media/HDD2
sudo chmod 755 /media/HDD2


Und:

sudo mkdir -p /media/HDD3
sudo chmod 755 /media/HDD3


Wer mehr über chmod, Dateirechte und 755, 777, etc. erfahren will der findet hier eine sehr gute Erklärung.

Jetzt sind die Verzeichnisse erstellt und die Rechte vergeben. Ihr könnt euch das nun z.B. direkt in Raspbian mit dem Dateimanager anschauen.
Auf der linken Seite vom Dateimanager seht ihr im Verzeichnisbaum meine drei Laufwerke und rechts daneben meine Medienverzeichnisse von HDD1 (für Volume)





Um die Datenträger zu mounten müssen wir nun die Datei fstab editieren:

sudo nano /etc/fstab


Ihr habt nun mit dem Editor Nano die Datei fstab geöffnet. 





 

Jetzt navigiert ihr mit den Pfeiltasten den Cursor nach unten bis zur ersten freien Zeile und tragt hier die UUID´s, TYPEn und die Pfade zu den eben angelegten Verzeichnissen ein. Zuerst kommt die UUID, dann der Verzeichnis-Pfad und danach der TYPE. Dahinter folgt noch jeweils defaults und zweimal 0. Das alles immer jeweils pro Gerät/Verzeichnis in eine Zeile schreiben. So wie in dem folgenden Screenshot zu sehen:




 

Wenn ihr fertig seid schließt ihr die Datei mit CTRL + X. Danach die y-Taste drücken und mit Enter bestätigen, um die Änderungen zu speichern.
Tippt nun in der Konsole folgendes ein um euren Pi neu zu booten:


sudo reboot


PuTTY verliert nach der Eingabe die Verbindung. Wartet bis euer Pi neu gestartet ist und verbindet euch, wie oben beschrieben, neu mit eurem Pi.

Jetzt sind wir soweit und können MiniDLNA installieren.
Gebt dazu in die Konsole folgendes ein:


sudo apt-get install minidlna


Nachdem MiniDLNA installiert ist müssen wir den DLNA-Server natürlich noch konfigurieren. Gebt dazu folgendes in die Konsole ein, um die Datei minidlna.conf mit Nano zu editieren:


sudo nano /etc/minidlna.conf


Jetzt wird es etwas unübersichtlich.
Zunächst müssen wir die Verzeichnisse festlegen die wir im WLAN zur Verfügung haben wollen, oder wie es in der Beschreibung heißt: Path to the directory you want scanned for media files.
Scrollt mit den Pfeiltasten zu dieser Zeile hier:

media_dir=/var/lib/minidlna


Diese Zeile müsst ihr auskommentieren oder entfernen:

#media_dir=/var/lib/minidlna


Ich habe auf meiner Festplatte mit dem Namen Volume, also dem vorhin erstellten Verzeichnis HDD1 folgende Ordner die ich von MiniDLNA gescannt haben möchte: moviesHD, movies3D, neu, series und images. Dafür habe ich folgende Einträge in die minidlna.conf geschrieben:



media_dir=V,/media/HDD1/moviesHD
media_dir=V,/media/HDD1/movies3D
media_dir=V,/media/HDD1/neu
media_dir=V,/media/HDD1/series
media_dir=P,/media/HDD1/images


Das V steht hierbei für Video und das P für Pictures. Als weiteren Typ gibt es auch noch A für Audio.
Mit den Typen könnt ihr festlegen welche spezifischen Inhalte/Medientypen die Verzeichnisse beinhalten.
Hätte ich jetzt auf der Festplatte z.B. eine andere Verzeichnisstruktur, dann würde das natürlich anders aussehen.

Nur als Beispiel: Hätte ich auf der Festplatte Volume einen Ordner mit dem Namen Media, dort drin einen Ordner mp3 und dort drin einen weiteren Ordner audiobooks, den ich gescannt haben möchte, dann würde der Eintrag dafür so aussehen:


media_dir=A,/media/HDD1/Media/mp3/audiobooks


Achtet auch hier unbedingt auf Groß- und Kleinschreibung.
Für meine drei Festplatten/Verzeichnisse sieht das wie folgt aus:





 

Sucht nun nach dieser Zeile:

#log_dir=/var/log


Und entfernt die Raute um die Zeile zu „aktivieren“:

log_dir=/var/log


Falls später etwas schief laufen sollte, habt ihr nun die Chance im log file nachzuschauen, was MiniDLNA dort für Fehler/Warnungen reingeschrieben hat.

Jetzt sucht ihr nach der folgenden Zeile:


#friendly_name=


Hier vergebt ihr den Namen für euren DLNA-Server. Seid kreativer als ich. Der von mir gewählte Name lautet: WORLD. Die Zeile sieht in meinem Falls also so aus:

friendly_name=WORLD


Wenn ihr jetzt noch wollt, dass später neu hinzugefügte Mediendateien ohne einen Neustart des DLNA-Servers erfasst werden, dann müsst ihr nach dieser Zeile hier suchen:

#inotify=yes


Und die Raute entfernen:

inotify=yes


Fertig. Schließt jetzt die Datei mit CTRL + X. Danach die y-Taste drücken und mit Enter bestätigen, um die Änderungen zu speichern.

Optional, aber sehr empfehlenswert, wenn ihr wollt, dass der DLNA-Server automatisch immer gestartet wird wenn ihr euren Pi neu startet:

sudo update-rc.d minidlna defaults


Nun müsst ihr euren DLNA-Server starten:

sudo service minidlna start


Und/oder:

sudo service minidlna restart


Nun gebt ihr noch folgendes ein:

sudo service minidlna force-reload


MiniDLNA beginnt nun die Dateien zu indizieren. Je nach Anzahl kann das eine ganze Weile dauern. Bis dieser Prozess nicht abgeschlossen ist sind nur die bereits indizierten Dateien zu sehen.

Für den Fall das ihr später noch Änderungen an den Konfigurationsfiles vornehmen wollt, müsst ihr minidlna neu starten und neu laden. Das macht ihr mit den folgenden beiden Befehlen:

sudo service minidlna restart


Und:

sudo service minidlna force-reload


Glückwunsch! Ihr habt nun euren DLNA-Medienserver erfolgreich eingerichtet. Nun könnt ihr mit euren DLNA-fähigen Geräten, die sich im gleichen WLAN befinden, auf die Mediendateien zugreifen.

 

Testen


Ihr könnt das Ganze auch direkt am PC testen. Gebt dazu die IP-Adresse von eurem Pi in eurem Browser ein mit dem Port 8200. In meinem Fall sieht das so aus:


192.168.0.21:8200




 

Ihr solltet nun ein kleines Webfrontend zu sehen bekommen, das euch Auskunft darüber gibt, welche und wieviel Dateien indiziert worden sind. 



Wenn ihr diesen Test direkt nach den eben aufgezeigten Schritten durchführt, dann kann es sein, dass der Prozess der Indizierung noch nicht abgeschlossen ist und somit nicht alle relevanten Dateien aufgezählt worden sind. In diesem Fall solltet ihr das Webfrontend einfach aktualisieren. Die Anzahl der Dateien sollte dann bei jedem Klick auf den Reload-Button vom Browser steigen. Ihr könnt so quasi live zuschauen wie die Indizierung voranschreitet.

Auf meinem Android Smartphone habe ich die App BubbleUpPnP installiert, mit der ich auf den DLNA-Server WORLD zugreifen kann. Nachfolgend ein paar Screenshots davon.
Hinweis: Ich hatte zu Beginn einmal kurz Schwierigkeiten mit meinem Smartphone auf WORLD zuzugreifen, nachdem ich den Pi nochmal komplett neu aufsetzen musste. Der DLNA-Server wollte einfach nicht mehr in der Liste der Medienserver bei BubbleUpPnP erscheinen. Nachdem ich das Smartphone einmal neugestartet hatte gab es dann aber keine Probleme mehr.




Das Ganze läuft auch problemlos auf meinem Samsung Smart TV. Ein etwas älteres Gerät von Philips funktioniert ebenfalls recht gut. Hier ist die Software vom TV nur nicht immer in der Lage alle Medienformate korrekt abzuspielen. Das ist dann aber der TV schuld und nicht der DLNA-Server!
Mit entsprechenden Apps habe ich das auch auf iPhone und iPad getestet. Alles kein Problem. Ich konnte für die Apple Geräte allerdings keine kostenlose App finden die mich überzeugt hat.
Noch nicht getestet habe ich das persönlich alles mit Playstation und Xbox, aber theoretisch sollte das auch problemlos funktionieren. Jedenfalls gibt es im Netz dazu sehr viele positive Berichte.

Wenn es bei euch nicht klappt oder zu Problemen kommt, dann werft am besten mal einen Blick ins log file um nach Fehlern zu suchen. Gebt dazu in die Konsole folgendes ein:


sudo nano /var/log/minidlna.log



Zusätzlich


Wenn ihr das automatische starten von minidlna beim Neustart vom Pi wieder entfernen wollt, dann gebt das hier in die Konsole ein:


sudo update-rc.d -f minidlna remove


Den DLNA-Server stoppen:


sudo service minidlna stop


Falls sich der Service nicht stoppen lässt, dann könnt ihr den Service auch killen:

sudo killall minidlna


Und wenn ihr MiniDLNA wieder komplett deinstallieren wollt, dann macht ihr das mit:

sudo atp-get remove --purge minidlna

 

Ende


Ich hoffe ihr hattet Erfolg. Natürlich gebe ich keine Gewährleistung für dieses Tutorial. Falls ihr Fragen habt, oder Anregungen/Verbesserungen, dann postet diese sehr gerne in den Kommentaren.

 

Quellen


https://www.raspberrypi.org/downloads/noobs/
https://www.raspberrypi.org/forums/viewtopic.php?f=35&t=16352
https://raspberry.tips/raspi-media-center/raspberry-pi-als-media-server-mit-minidlna-einrichten/
http://www.forum-raspberrypi.de/Thread-tutorial-minidlna
https://kofler.info/der-raspberry-pi-als-dlna-server/
https://www.youtube.com/watch?v=5FCGMljivIg
https://wiki.ubuntuusers.de/ReadyMedia/
http://www.putty.org/
http://www.shellbefehle.de/befehle/
https://willy-tech.de/sd-karte-mit-diskpart-formatieren/

http://support.ecs-webhosting.de/FragenundAntworten/Linux-Dateirechte-und-755-777-etc-verstehen


Update


Zeit für ein kleines Update. Ich habe den DLNA-Medienserver nun schon einige Zeit im Einsatz und war zu Beginn auch sehr angetan von der Performance. Inzwischen aber habe ich an meinem Setup ein paar Änderungen vorgenommen.
Die wichtigste Änderung ist die Verbindung vom Pi mit meinem Netzwerk. Damit auch Videoinhalte in FullHD (1080p mit DTS Sound) flüssig und ohne buffern auf die Endgeräte gestreamt werden können habe ich den Pi nun per LAN Kabel direkt mit meinem Modem verbunden. Jetzt ist der Pi zwar nicht mehr drahtlos im Netz, aber so ist sichergestellt, dass auch Videoinhalte mit mehr als 720p sauber gestreamt werden können. Ich bin kein Fan von Kabeln, aber die Geschwindigkeit vom WLAN hat so einfach nicht ausgereicht. Und die Endgeräte auf die gestreamt werden soll sind ja nach wie vor drahtlos im Netzwerk, weshalb ich die Lösung mit dem LAN Kabel zwischen Pi und Modem nicht so schlimm finde.
Wenn also euer Pi nicht allzu weit weg steht vom Modem, dann empfehle ich eine Verbindung per LAN Kabel. Zum Glück sind hierzu nur wenige Schritte nötig die nur im Detail vom Tutorial abweichen.

Schließt euren Pi einfach per Kabel ans Modem an und deaktiviert WLAN über das entsprechende Symbol in der Taskleiste von Raspbian. Falls die Verbindung per Kabel erfolgreich war erscheint neben dem deaktivierten WLAN-Symbol nun ein neues Symbol mit zwei Pfeilen das eine erfolgreiche Verbindung symbolisiert. So weit, so gut. Wollt ihr euren Pi auch weiterhin über SSH mit PuTTY steuern, dann müsst ihr erneut die IP-Adresse vom Pi ermitteln. Wie im Tutorial beschrieben gebt ihr dazu wieder ifconfig in die Konsole ein. Dieses Mal schaut ihr aber nicht bei wlan0 nach der inet Adresse, sondern bei eth0. In der Regel sollte sich die IP-Adresse nur minimal verändert haben. Im WLAN hatte mein Pi die IP-Adresse 192.168.0.21 und jetzt 192.168.0.20
Mit der neuen IP-Adresse könnt ihr euch nun wie schon gewohnt über PuTTY mit eurem Pi konnektieren. Und auch beim Testen ob euer Medienserver gestartet worden ist und die Inhalte korrekt indexiert worden sind gebt ihr nun einfach statt der alten die neue IP-Adresse mit ein. In meinem Fall: 192.168.0.21:8200
Alles andere funktioniert nach wie vor wie im Tutorial beschrieben und auch die Endgeräte sollten wie schon gewohnt euren Medienserver finden. Nur das jetzt Videoinhalte in FullHD ohne lästiges buffern laufen sollten.
Hier noch ein sehr schöner Artikel zum Thema: Ist WLAN für Media Streaming geeignet?

Ein anderer Punkt der mich am DLNA-Medienserver stört ist der Indexierungsprozess. Ich habe für dieses Problem leider noch keine saubere Lösung gefunden. Vielleicht habt ihr ja eine Idee.
Folgende Situation. Ihr spielt auf einen eurer Datenträger neue Files drauf und wollt diese nun ins heimische Netzwerk streamen. Euer Medienserver aber zeigt nur die alten Files an. Ganz klar, ihr müsst erst die Files neu indizieren. Das kann je nach Anzahl bis zu mehrere Stunden dauern. Klar, das nervt, aber was richtig nervt ist die Tatsache das der Befehl sudo service minidlna force-reload nicht immer ausgeführt wird. Man gibt den Befehl ein und nichts passiert. Da hilft auch kein stop und kein reload des Medienservers. Erst wenn ich sudo nano /etc/minidlna.conf in die Konsole eingebe, dort ein paar Dinge verändere und dann das Dokument abgespeichert habe, kann ich mit force-reload den Medienserver dazu zwingen alles neu zu indizieren.
Falls also einer von euch eine Idee hat wieso force-reload nicht jedes Mal dazu führt das meine Files neu indiziert werden bitte in die Comments schreiben.

Auf meinen Android und iOS Geräten habe ich jetzt zum Abspielen von Videos und Audiodateien VLC installiert. BubbleUPnP, wie im Tutorial beschrieben, ist nach wie vor auch eine super App um auf euren DLNA-Medienserver zuzugreifen und Medien wiederzugeben, aber mit VLC gibt es eine super bequeme, ebenfalls kostenlose und sehr schlanke Alternative. Und, VLC gibt es auch für iOS.

-Android: VLC for Android
-iOS: VLC for Mobile