Programmiere dein eigenes LCARS Benutzerinterface mit Javascript und SVG

Vor einiger Zeit habe ich schon zu einem Projekt verlinkt, das ein Star-Trek LCARS GUI für die Gebäudesteuerung genutzt hat. Nachdem ich nun etwas herumgesucht habe, wie man etwas derartiges selbst umsetzen kann, bin ich auf viele verschiedene Frameworks gestossen. Manche davon sind recht alt. Diese habe ich nicht mehr im Detail angeschaut. Flash-basierte UIs sollten definitiv der Vergangenheit angehören. Andere Frameworks benutzen sehr viele Bilddateien. Auch diesen Ansatz mag ich nicht, da er recht viel Overhead erzeugt und die LCARS-Elemente eigentlich extrem einfach aufgebaut sind (jedes Element ist einfarbig).

Am meisten gefiel mir das LCARS SDK. Es nutzt Javascript und

Blöcke, um das Userinterface dynamisch zu bauen. Leider war die Dokumentation für mich nicht ganz klar und ich hatte Mühe, ein relativ einfaches Interface umzusetzen. Warum eigentlich überhaupt

Tags nutzen?

Es gibt einen noch einfacheren Weg: SVG – Scalable vector graphics. SVG ist seit mehr als 10 Jahren ein Webstandard. Man hat aber den Eindruck, es wird selten genutzt. Dabei unterstützen praktisch alle modernen Browser das Format sehr gut. Das Zeichnen von Rechtecken und Kreissegmenten ist sehr einfach. Das schöne an SVG ist, dass alle Elemente direkt im DOM mittels Javascript angesprochen werden können. So ist es ziemlich einfach, die Farbe eine Blocks zu ändern oder ihn auszublenden. Selbst das Drehen und Verschieben ist extrem einfach.

Ein weitere Vorteil an SVG ist es, dass nur sehr wenige Grafikobjekte gerendert werden müssen und dies auch auf schwachen PCs super funktioniert (oder Tablets, die gerne für die Gebäudesteuerung eingesetzt werden). Selbst auf Mobiltelefonen funktioniert ein SVG-basiertes UI perfekt.

Mit einer kleinen Bibliothek braucht ein einfaches Interface nur wenige Zeilen Code:

function home() {
    lcarsgen.container=document.getElementById("canvas");
    lcarsgen.next_x = 10
    lcarsgen.next_y = 10
    lcarsgen.knee({x:10, height2: 40})
    save_x = lcarsgen.next_x
    lcarsgen.button({x:10, text:"Light", id:"b_light"})
    lcarsgen.button({x:10, text:"Heating", id:"b_heating"})
    lcarsgen.button({x:10, text:"Blinds", id:"b_blinds"})
    lcarsgen.button({x:10, text:"Weather", id:"b_weather"})
    lcarsgen.button({x:10, text:"Movies", id:"b_movies"})
    lcarsgen.button({x:10, text:"Music", id:"b_music"})
    lcarsgen.button({x:10, text:"Config", id:"b_config"})
    lcarsgen.knee({x:10, height1: 120, height2: 40, \
                   type:"bottomleft"})
    save_y = lcarsgen.next_y - lcarsgen.spacing - 40
 
    // top bar
    lcarsgen.next_x=save_x
    lcarsgen.button({y: 10, width: 310, height: 40} )
    lcarsgen.button({y: 10, width: 310, height: 40} )

    // save for text display
    tx = lcarsgen.next_x-lcarsgen.spacing
    lcarsgen.button({y: 10, width: 55, height: 40, \
                     type:"rounded_right"} )

    // bottom bar
    lcarsgen.next_x=save_x
    lcarsgen.button({y: save_y, width: 310, height: 40} )
    lcarsgen.button({y: save_y, width: 310, height: 40} )
    lcarsgen.button({y: save_y, width: 55, height: 40, \
                     type:"rounded_right"} )

    lcarsgen.text({x:tx, y: 50, height: 40, text:"H.11 CONTROL", \
                   text_align: "right"} )
}

Das Ergebnis kann sich sehen lassen:
Screenshot 2016-05-12 12.15.52