EModeration - SVG-Funktionalität

Aus THM-Wiki
Wechseln zu: Navigation, Suche

Im Fokus dieser Arbeit steht die Erstellung eines Freihand-zeichnen-Werkzeugs für den Moderator einer "eModeration".

Design

Das Screendesign

Informationen zum Screendesign

Der Moderator hat ein Werkzeug "Stift" in seiner Werkzeugleiste. Wählt er dieses, so öffnet sich ein frei verschiebbares Optionsfenster mit den folgenden Einstellmöglichkeiten:

  • Farbe wählen
  • Linienstärke einstellen

Der Mauszeiger nimmt dabei die Form eines Stifts an (mögliche Erweiterung: Stiftfarbe wird im Cursor sichtbar). Der Moderator kann nun auf der gesamten Pinnwand frei zeichnen. Lässt er den Mauszeiger los, so synchronisiert sich die Ansicht mit denen der Teilnehmer. Einmal gezeichnete Linien können nachträglich bearbeitet werden:

  • Verschieben mit der Maus
  • Ändern von Farbe und Linienstärke (Optionsfenster öffnet sich)
  • Löschen der Linie

Die Umrandung der Freihandzeichnung wird erst bei einem "MouseOver" sichtbar.

Anm.: Den grammatikalischen Fauxpas in der Titelkarte bittet der Autor zu entschuldigen ;)

Unterbrechung der Synchronität

Da es beim Freihandzeichen schnell passieren kann, dass man sich vermalt, wäre eine Unterbrechungsmöglichkeit der Synchronität mit den Clienten sinnvoll. Dies könnte durch einen Schalter in der Werkzeugleiste des Moderators umgesetzt werden. So kann der Moderator frei gestalten (z.B. auch Karten anbringen) ohne dass dies die Teilnehmer mitbekommen.

Entwicklung

Das Frontend

Das Freihand-Zeichnen-Werkzeug steht abgekoppelt von der eModeration zur Verfügung. Zur Einbindung der Funktionalität schickt folgender Aufruf:

var canvas = $('pinnwand');
new SVG_MarkerTool( canvas );

canvas kann dabei ein beliebiges HTML-Element sein, welches die Zeichenfläche darstellen soll.

  • SVG-Stift testen
    Nicht sehr performant, da GlobalMouseOver aktiviert (siehe unten). Nach Deaktivierung des Stifts können die Zeichnungen verschoben, bearbeitet und gelöscht werden.
  • Dokumentation der Klassen

SVG mouse cursor

Die Erstellung eines eigenen MouseCursors, dessen Farben sich dynamisch verändern lassen, ist leicht möglich. Folgende Anforderungen stellen sich dabei an den Cursor:

  • es muss eine SVG sein
  • die SVG muss Elemente bereit halten, welche die fill-Eigenschaft verstehen. Dies sind Formen und Text-Elemente.
  • Die fill-Elemente brauchen eine eindeutige ID

Die IDs können dann einfach bei der Erstellung der Klasse übergeben werden:

var stift = new SVG_MouseCursor( "pinnwand", "mein_stift.svg", {
    shapes: [ "fill_1", "fill_2", "fill_3"  ]
});
stift.setColor( "00FF00" );

Alle fill-Elemente werden im obigen Beispiel grün gefärbt.

Globales MouseOver

Da das Freihand-Tool unter anderem auch dazu eingesetzt wird, mehrere Karten komplett einzurahmen, ergibt sich folgendes Problem: Die SVG-Zeichnung wird stets in ein DIV-Element geladen, welches dann die Ausmaße der Zeichnung erhält. Dadurch, dass dieses DIV-Element nun die darunter liegenden Karten komplett verdeckt, sind sie über die Maus nicht mehr direkt erreichbar. Schön wäre es, wenn die Anordnung der Karten auf der Z-Achse keine Rolle spielen würde und man stets an jede Karte auf der Pinnwand, ob nun überdeckt oder nicht, ohne Verschieben heran käme. Das "mouseover"-Ereignis der HTML-ELemente wird leider nur für Elemente der vordersten Ebene ausgelöst. Da also keine nativen Möglichkeiten zur Verfügung stehen, wurde im Rahmen der Arbeit das Globale MouseOver umgesetzt.

Aufruf der Klasse:

new GlobalMouseOver( container ); // alle Elemente innerhalb von 'container' werden berücksichtigt

Die Klasse feuert stets für das auf der Z-Achse tiefliegendste und gleichzeitig komplett verdeckte Element ein Ereignis ab, sobald der Mauszeiger es betritt, bzw. verlässt. Dieses Ereignis kann nun im Folgenden abgefangen werden, um zB das betreffende Element für die Dauer des Mausaufenthalts ganz nach vorne zu holen.

Problem der Performance: Dadurch, dass bei jeder Mausbewegung auf dem Container-Element vielfältige Positionsberechnungen angestrengt werden müssen, leidet, bei zunehmender Anzahl der Elemente, die Performance spürbar. Der Firefox-Browser ab Version 3.5 bringt hier zwar auch mit vielen Elementen schon eine akzeptable Geschwindigkeit zustande, wirklich zufriedenstellend ist diese allerdings nicht. Die Lösung ist eine Umgehung des Problems: Das GlobalMouseOver wird nur aktiviert, sobald der Nutzer die ALT-Taste gedrückt hält. So kann er bei Bedarf Verdecktes nach vorne holen, hat aber im normalen Ablauf nicht mit Performanceeinbüßen zu kämpfen.

Über das Gedrückthalten von ALT lassen sich auch verdeckte Karten/Zeichnungen erreichen

Einsatz in der eModeration

SVG Pen toolbar.png

Der Stift ist innerhalb einer eModeration über die Werkzeugleiste erreichbar. Ein erster Klick aktiviert das Werkzeug, ein zweiter deaktiviert es wieder. Das Zeichnen ist auf der gesamten Pinnwand möglich.

Synchronisation mit den Teilnehmern

Wird beim Zeichnen mit der Maus die Maustaste losgelassen, so wird die Zeichnung direkt über das Nachrichtensystem auf dem Server gespeichert und an alle anderen Teilnehmer verteilt. Wie auch schon bei den Karten, wird dem Moderator hier optisch signalisiert, dass die Zeichnung noch nicht sicher bei allen Teilnehmern angekommen ist. Im Unterschied zu vorher, wird nun das betreffende Objekt nicht mehr grau hinterlegt, sondern halbtransparent dargestellt (dies sieht einfach ansprechender aus)

SVG Pen sync.png

Das nachträgliche Ändern von Position, Farbe und Linienstärke wird ebenfalls direkt dem Nachrichtensystem mitgeteilt.

Das Backend

Datenbank

Um die momentan eingesetzte Datenbankstruktur nicht unnötig zu verkomplizieren, werden die Zeichnungen als Karte gespeichert. Hierbei wird der SVG-Code als Kartentext behandelt. Folgende Änderungen sind an der DB vorzunehmen:

ALTER TABLE `mod_objekt` ADD `type` SET( 'CARD', 'SVG' ) NOT NULL DEFAULT 'CARD';
ALTER TABLE `mod_historie` CHANGE `setRef` `setRef` INT( 11 ) NULL;

Da Zeichnungen keine Karten aus Karten-Sets referenzieren, wird das entsprechende Feld NULL gesetzt.

Ein typischer "Kartentext" einer Zeichnung sieht wie folgt aus:

<polyline xmlns="http://www.w3.org/2000/svg" matrix="1,0,0,1,0,0" invmatrix="1,0,0,1,0,0" transform="matrix(1, 0, 0, 1, -503, -22)" stroke="rgb(255,0,0)" stroke-opacity="1" stroke-width="8" fill="none" fill-opacity="0" points="507,26 519,38 534,50 552,63 610,92 645,105 676,113 685,116"/>

Bild-Export von Pinnwänden

Der Bild-Export wurde so erweitert, dass auch SVGs mit exportiert werden. Da die GDlib leider (noch) keine Möglichkeit bietet, SVGs einzuladen, bedient sich der Export des Kommandozeilenwerkzeugs rsvg. Dieses muss auf dem eingesetzten Serversystem vorhanden sein, andernfalls werden keine SVGs mit exportiert.