Die Jquery Komponente für Steve Rowland ist für Fotos schon sehr gut, aber da ich mehr und mehr Videos zu produzieren habe, mußte das Steve Rowland Photography Frontend noch um die Möglichkeit erweitert werden, Videos abzuspielen. Da ich ein Frontend haben möchte das auf jedem Endgerät läuft, habe ich den
Player als HTML5-Mediaelement Jquery-Erweiterung,
in das bestehende Jquery-Frontend integriert. Wie das geht und wie man das Ganze mit Gallery2, als Assetmanagement adminstriertbar macht, ist Thema dieses Posts. Das Video veranschaulicht, wie das Handling des Frontends arbeiten muß: 1. Video wird ausgewählt. 2. Das <img> wird durch einen <video> Element ersetzt. 3. Das Video wird abgespielt, sobald der Ladezustand soweit fortgeschritten ist, das der Film ohne Pause durchlaufen kann 4. Ein anderes Video wird ausgewählt. 5. Die <source> Elemente des <Video> Elements, werden durch die neuen <source> Elemente ersetzt und neu geladen. 6. wie 3. 7. Wird ein Thumbnail ausgewählt, das ein Foto referenziert, wird das <video> Element wieder durch das <img> Element ersetzt.
Wer das ganze mit seiner eigenen Gallery durchexerzieren möchten, muss natürlich die URL: http://www.steverowland.net/gallery2, durch seine eigene Gallery2 Installations-URL ersetzen. Wer keine Gallery2 als Assetmanagement verwenden möchte, kann das Frontend auch in einer Standalone-Version, ganz am Ende des Posts herunterladen, und ohne Gallery2 verwenden. Der Post beschreibt aber die Variante, wie ich sie auf der Steverowland.net installiert habe, also mit Gallery2 Assetmanagement.
1. Gallery2
Die letzte stabile Version 2.3.1, am Besten gleich die Developer Version(mit Alles), von Gallery2, hier herunterladen. und auf dem Server instalieren. Es gibt auch Gallery3, was aber keine neue Version von Gallery2, sondern eine andere Bildergallerie, die mit einer anderen Programmarchitektur programmiert wurde darstellt, die eher geeignet ist, wenn man schnell eine Bildergallery ins Netz stellen will. Wir benötigen die wesentlich umfangreichere API von Gallery2, um das als Admininterface für das Jquery umstricken zu können. Die installation ist eigentlich selbsterklärend, wer Schwierigkeiten hat, hier gibts die ausgezeichnete Dokumentation für Gallery2. Welches Thema man wählt ist eigentlich egal, denn der User wird die Gallery ohnehin nicht betreten, man sollte also ein Thema wählen, mit dem man selbst eine gute Übersicht behält. Im Gegensatz dazu, werden ALLE verfügbaren Plugins(Module), incl. URL-Rewrite installiert (sind unter der gleichen URL gelistet, wie die Core, aber alle Bestandteil der Developer Version) und richtig konfiguriert. Um Gallery2 wirklich perfekt zum laufen zu kriegen, wären folgende Server Applications zu empfehlen: GD-Library(stellt Bildbearbeitung funktionen zur Verfügung), ImageMagick(Ist sozusagen die "Platin-Edition" zu GD), Jpegtran (Kann Jpegs verlustfrei umrechnen). Da auch die Adminstration von Filmen vorgesehen ist, wäre auch die ffmpeg-Extension zu empfehlen, dafür sollte zusätzlich 'ffmpeg' auf dem Server installiert sein. Alle Pfade zu den Binaries der gelisteten Server-Apps, müssen als Ressource-Pfade, PHP zur Verfügung stehen.(Wird in der php_ini gesetzt), Wer keine Root Zugang zum Server hat, muss seinen Serveradmin entsprechend instruieren. Gallery2 würde auch ohne das Alles grunsätzlich funktionieren und Standarts bieten, aber mit diesen Tools, ist es ein echtes 'Bildbearbeitungs-Brett', von herrausragender Qualität und Performance, das auch für hochprofessionelles Assetmanagement, keine Wünsche offen lässt.
2. Simpleviewer Source Extension
Es gibt eine Gallery2 Extension, die eigntlich zu einem Flash Imageslider gehört, die SimpleviewerSource. Diese ist nicht Bestandteil der Offiziellen Repository und müsste man sich aus den Community-Extensions besorgen. Allerdings ist eine größeres PHP-Workaround notwendig, wenn man die Original-Erweiterung verwendet, deshalb kann man sich meine, bereits umgenbaute Version herunterladen und diese installieren. Diese kann allerdings nicht im "normalen" Plugin installationsprozess von Gallery2 installiert werden, sondern wird Gallery2, wie folgt zugeführt.
Instalation: 1. zip Datei hier herunterladen 2.zip auspacken und Ordner in das Verzeichnis [Gallery installationspfad]/modules auspacken, oder zip hochladen und im Verzeichnis auspacken. 3. In der Site-administration, Module auswählen. Jetzt ist die Erweiterung SimpleviewerSource unter 'Exportieren', verfügbar und kann aktiviert werden.
VORSICHT!!! Die Nummer funktioniert nur, weil Simpleviewer Source eine "offizielle Extension" ist, der wir ein Kuckuks-Ei unterschieben, in der GalleryFactory wird Simpleviewer Source als ordentlich Extension in Gallery2 registriert, man kann also nicht einfach irgendeinen Ordner anlegen, der dann von Gallery2 als Extension wahrgenommen wird. Wahlweise, kann man natürlich auch die Extension übers Backend installieren und anschliessend die Moduldateien, per ftp-Upload mit den modifizierten überschreiben.
Man kann auch ein eigenes Modul für Gallery2 schreiben, aber SimpleviewerSource, hat bereits fast alles was wir brauchen, Was, Wie, Warum genau diese Extension bietet, würde hier den Rahmen sprengen und eher Thema für einen eigenen Post, aber SimpleviewerSource erstellt eine XML-struckturierte Ausgabe, der kompletten Gallery, die eigentlich als URL für den HTTP-Request dier Flash Datei gedacht ist und genau DIESE, bietet auch das perfekte Datenmodel für den View, den wir dem Modul hinzufügen. Man muss keinen der SimpleviewerSource Konfigurationsparameter ausfüllen oder setzen, da diese von der überarbeiteten Version schlicht übergangen werden!
3. Die Views
Gallery2 ist in MVC Architektur programmiert. Das Model sowie Controller, sind schon im Modul vorhanden, wir müssen dem Modul nur einen View hinzufügen, analog zum XMLOut View hab ich ihn HTMLOut genannt und er erweitert die GalleryView Class, die Datei die ihn beinhaltet, heisst dann nach Gallery2-API HTMLOut.inc. Der einzige Parameter der an den Controller übergeben wird, ist die Id, des Album Elements für den wir den View haben mölchten. Im Gegensatz zur XMLOut, die ein Album und deren Fotoelemente darstellt, habe ich den HTMLView um eine Hirarchie erweitert, es wird also eine Album mit dessen Unteralben und die Bilder in den Unteralben ausgelesen werden, um das Datenmodel, wie es für die JQuery-Ausgabe benötigt wird, zu erhalten. Eine Möglichkeit das neu Frontend anzuzeigen besteht nun darin, den View direkt mit der ItenId des Portfolios (in diesem Fall ist das die 1051) aufzurufen. Die Gallery2-API setzt noch Prefix davor, also g2_view und g2_itemId, wodurch der komplette Aufruf so aussieht:
Ausserdem brauchen wir, für die Thumbnailnavigation einen View, der die Thumbnails der Bilder in den Subalben zeigt, z.B. so:
dieser wird in das jeweilige img.src attribut eingetragen.
Beim Click auf das Thumbnail, soll das Hintergrund Bild geladen werden, das Jquery verwendet dazu den Wert im img.alt Attribut des jeweiligen Thumbnails. Wir brauchen also noch einen weiteren View, nämlich den, der das große Bild zeigt. Bestandteil der SimpleviewerSource, wäre der View, downloadMax View, wobei dieser dem DownloadItem View der Core, um die beiden Parameter g2_maxImageHeight und g2_maxImageWidth erweitert entspricht. Da diesen hier keine Bedeutung zukommt, da die Bildgröße nicht von Gallery2, sondern durch das Jquery an die jeweilige Screengröße angepasst wird, kann man genausogut den View der Core verwenden.
Da der Aufruf innerhalb des Gallery Root Pfades erfolgt, würden auch die relative Pfade genügen, hier aus dem Blog müssen wir natürlich absolut verlinken. Auch ganz ohne Views, wäre es theoretisch möglich, auf die Items zuzugreifen, ein paar Beispiele:
Dieser Code etwa: <a href="http://www.steverowland.net/gallery2/v/show/crist/1967_ORDER03.jpg.html" ><img src="http://www.steverowland.net/gallery2/d/4314-2/1967_ORDER03.jpg" alt="1967_ORDER03" /></a>, das kleine v steht für view, show/ ist das oberste Album, crist/ ist das subalbum, 1967_ORDER03.jpg ist der Bildname und .html, zeigt, das nicht das Bild sondern die Fotoseite des Bildes angezeigt wird. Im src attribut des angezeigten Bildes steht das d/ für "download", was immer ein Bild zeigt, wärend v/ den g2_view des Bildes zeigt. In HTML ausgeführt, wird hier ein clickbares Thumbnail gezeigt, das auf die Photoseite des Items verlinkt und sieht so aus:

Oder dieser Code: <a href="http://www.steverowland.net/gallery2/d/4313-1/1967_ORDER03.jpg"><img src="http://www.steverowland.net/gallery2/d/4316-2/1967_ORDER03.jpg" alt="1967_ORDER03" /></a>. Sowohl das href als auch das src zeigen ein Bild(d/). In diesem Fall, die erste Zwischengrösse, clickbar, mit Verweis zur Originaldatei. was in HTML so aussieht:

Dieser Code würde hier in HTML, den Blog sprengen: <img src="http://www.steverowland.net/gallery2/d/4313-1/1967_ORDER03.jpg" alt="1967_ORDER03" /> er würde direkt die Originaldatei hier anzeigen, wie am href Attribut des vorherigen Beispiels deutlich zu sehen ist. Wer's nicht glaubt, kann ja den Wert der src, direkt ins Browser Adressfenster kopieren. Die URL-Rewrite Regeln für Gallery2, lassen sich in der Siteadministration derselben auch umdefinieren.
Damit haben wir die URLs, die wir im HTML Code der jquery extension in das src und das alt atribut des jeweilegen Thumbs eintragen müssen. Ein Listenelement könnte also, in etwa so aussehen, wobei ich aus Übersichtsgründen, die cufon-wraps weggelassen habe und hier der simpleviewerSource View eingetragen ist, was wie gesagt, in diesem Fall das gleiche Resultat liefert:
<li class="album">
<span class="st_link">Cover-shooting, D&W Katalog 2002, Milano <span class="st_arrow_down"></span></span>
<div style="overflow: hidden;" class="st_wrapper st_thumbs_wrapper">
<div style="width: 1098px;" class="st_thumbs">
<img src="http://www.steverowland.net/gallery2/main.php?g2_view=simpleviewersource.DownloadThumb&g2_itemId=4791" alt="main.php?g2_view=simpleviewersource.DownloadMax&g2_maxImageHeight=&g2_maxImageWidth=&g2_itemId=4791" title="http://www.steverowland.net/gallery2/v/show/D_W01_Titel/D+W01_Titel.jpg.html">
<img src="http://www.steverowland.net/gallery2/main.php?g2_view=simpleviewersource.DownloadThumb&g2_itemId=4796" alt="main.php?g2_view=simpleviewersource.DownloadMax&g2_maxImageHeight=&g2_maxImageWidth=&g2_itemId=4796" title="http://www.steverowland.net/gallery2/v/show/D_W01_Titel/D+W01_Titel.jpg.html">
<img src="http://www.steverowland.net/gallery2/main.php?g2_view=simpleviewersource.DownloadThumb&g2_itemId=4800" alt="main.php?g2_view=simpleviewersource.DownloadMax&g2_maxImageHeight=&g2_maxImageWidth=&g2_itemId=4800" title="http://www.steverowland.net/gallery2/v/show/D_W01_Titel/D+W01_Titel.jpg.html">
<img src="http://www.steverowland.net/gallery2/main.php?g2_view=simpleviewersource.DownloadThumb&g2_itemId=4804" alt="main.php?g2_view=simpleviewersource.DownloadMax&g2_maxImageHeight=&g2_maxImageWidth=&g2_itemId=4804" title="http://www.steverowland.net/gallery2/v/show/D_W01_Titel/D+W01_Titel.jpg.html">
<img src="http://www.steverowland.net/gallery2/main.php?g2_view=simpleviewersource.DownloadThumb&g2_itemId=4812" alt="main.php?g2_view=simpleviewersource.DownloadMax&g2_maxImageHeight=&g2_maxImageWidth=&g2_itemId=4812" title="http://www.steverowland.net/gallery2/v/show/D_W01_Titel/D+W01_Titel.jpg.html">
<img src="http://www.steverowland.net/gallery2/main.php?g2_view=simpleviewersource.DownloadThumb&g2_itemId=4816" alt="main.php?g2_view=simpleviewersource.DownloadMax&g2_maxImageHeight=&g2_maxImageWidth=&g2_itemId=4816" title="http://www.steverowland.net/gallery2/v/show/D_W01_Titel/D+W01_Titel.jpg.html">
</div>
</div>
</li>
Jetzt sollte auch deutlich werden, warum diese Gallery äusserst Suchmaschinen optimal ist, den auf diese Weise, sind tatsächlich alle relevanten Bild und Albumparameter, bereits in dieser einen Datei vorhanden und direkt vom Googlebot Indizierbar, ohne weitere Aktion oder einer Substitution der Calls durch Snapshots für den Googlebot, wie das für Flash notwendig wäre.
Damit sieht, der View ja schonmal aus, wie die gewünschte Ausgabe und ist es ja auch, aber…
… sie soll ja eigentlich mit der folgenden URL aufgerufen werden:
Die URL sieht nicht nur besser aus, sondern hat auch den Vorteil, das es auch ausserhalb des Gallery2-Instalationspfades funktionieren würde, was mit dem View nicht geht. Aber dazu fehlt noch die Datei "portfolio.php", eine sog. Wrapper-Datei.
4. Die Wrapper Datei
Ruft man Gallery2 auf, erfolgt normalerweise ein Aufruf der Datei 'main.php'. View und Item werden als URL Parameter, an diese übergeben. Aber Gallery2 kann auch eingebettet, in einer anderen Anwendung, oder mit einer anderen Anwendung über ein event-based loose coupling verbunden, aufgerufen werden. In diesem Fall, wird Gallery2 nicht über die 'main.php', sondern über die 'embed.php' aufgerufen. Damit wird die 'bootstrap.inc' nicht zuerst eingebunden und die Gallery2 Ausgabe kann in ein andere Datei, oder eine andere Anwendung, umgeleitet werden. Diese kann in einem anderen Verzeichnis, muß aber auf der selben Domain liegen (auch keine Subdomain). Wird Gallery2 in eine andere Anwendung geleitet, läuft Gallery2 'eingebettet". Wird Gallery2 über ein coupling verbunden findet die Ausgabe von Gallery2 und die der verbundenen Anwenndung, in einer weiteren Datei statt. Diese Datei nennt man Wrapper Datei.
Die Datei muss folgendes enthalten:
<?php
// der relative Pfad zum Gallery-Root Verzeichnis (in diesem Fall befinden sich die wrapper-Datei im Gallery-Root Verzeichnis)
$g2_Config['path'] = dirname(__FILE__) . '/';
// Den Rootpath der Gallery2 installation, allso von der Domain-Root zum Gallery-Root Verzeichnis.
$g2_Config['g2Uri'] = '/gallery2/';
// und den embed Pfad, also von der Domain-root zur wrapper Datei, damit lassen sich alle anderen Relation herstellen.
$g2_Config['embedUri'] = '/gallery2/portfolio.php';
// Dann wird die embed.php eingebunden.
require_once( $g2_Config['path'] . 'embed.php');
// Wir schicken einen HTML Header
if (!headers_sent()) {
header('Content-Type: text/html; charset=UTF-8');
}
// Durch die init, wird ein Status in der Gallery erzeugt, der aufrufe verarbeiten kann und
$ret = GalleryEmbed::init(array('fullInit' => true));
check($ret);
GalleryCapabilities::set('login',true);
// Eine Instanz der Gallerie laden und autifizieren.
/* Grab the authToken */
global $gallery;
$session =& $gallery->getSession();
$authToken = $session->getAuthToken();
// die Request Varialblen direkt an den entsprechenden view übergeben.
GalleryUtilities::putRequestVariable('view', 'simpleviewersource.HTMLOut');
GalleryUtilities::putRequestVariable('itemId', '1051');
// Und die Anfragen von den definierten Controllern bearbeiten lassen
$data = GalleryEmbed::handleRequest();
// Die $data, enthält jetzt die Daten unserer Ausgabegallerie, bis auf das Thema. Da hier MVC, konsequent durchgezogen wurde, besteht eine 100% Trennung, zwischen Form und Inhalt. Wobei $data['headHtml'] die Headerdaten und $data['bodyHtml'] die Bodydaten enthält.
// Da wir wegen einer möglichen Video Ausgabe eine HTML5 Ausgabe möchten, Gallerie aber ein HTML4 Ausgabe schicken würde, haben wir das komplette HTML im View integriert und geben diesen auch wieder komplett als HTML aus.
function check($ret) {
if ($ret) die($ret->getAsHtml());
}
?>
5. Das Javascript
Auch diese Datei ist Bestandteil, der umgebauten SimpleviewerSource-Erweiterung und zwar hier: js/HTML5JqueryMediaelement.1.1.js. Die Datei enthält bereits Teile, für die Version 2, die hier noch garnicht zum Einsatz kommen, wie z.B. die Verwendung von Canvas zum zeichnen von Standbildern aus dem Video. Diese hab ich hier weggelassen.
$(function() {
// einzige konfigurierbare Variable. Wo liegen die Filmdateien?
var $videoPath = 'http://addit-media.net/new/uploads/stevemovies/';
// Variablen, die sich auf die verwendete Index Datei beziehen
// the loading image
var $loader = $('#st_loading');
// the ul element
var $list = $('#st_nav');
// the current image being shown
var $currImage = $('#st_main').children('img:first');
var windowWidth = $(window).width(),
windowHeight = $(window).height();
// Aktuellen Bild….
// und die Navigation mit den Thumbs laden
$('<img>').load(function(){
$loader.hide();
$currImage.fadeIn(3000);
setTimeout(function(){
$list.animate({'left':'0px'},500);
},
1000);
}).attr('src',$currImage.attr('src'));
// Breite des div elements, für die Thumbnailnavi berechnen
// um festzustellen, wo die einzelnen thumbs agezeigt werden müssen
buildThumbs();
function buildThumbs() {
$list.children('li.album').each(function(){
var $elem = $(this);
var $thumbs_wrapper = $elem.find('.st_thumbs_wrapper');
var $thumbs = $thumbs_wrapper.children(':first');
//180px pro thumb + 3 für margin
var finalW = $thumbs.find('img').length * 183;
$thumbs.css('width',finalW + 'px');
//element scrollbar machen, funktion siehe ganz am ende des skripts
makeScrollable($thumbs_wrapper,$thumbs)
;});
}
// ein Video laden
function loadVideo(title, from, to){
// Hier sieht man, wie 'from' und 'to' als "#" Anker übergeben werden!!
// Ich habe die Viedeos in den einzelnen Ordner _1, _2, _3 genannt, theoretisch, kann mann auch alle 3 einfach "video" nennen,
// da sie sich aufgrund der unterschiedlichen Endung ohnehin unterscheiden.
$('#video').append(createSource($videoPath + title + '/_1.mp4#t='+from+','+to, 'video/mp4'));
$('#video').append(createSource($videoPath + title + '/_2.ogg#t='+from+','+to, 'video/ogg'));
$('#video').append(createSource($videoPath + title + '/_3.webm#t='+from+','+to, 'video/webm'));
};
// source elemente in das Video laden
function createSource(src, type){
var source = document.createElement('source');
source.src = src;
source.type = type;
return source;
};
// einen Button herstellen
function createButton(parent, value) {
var myButton = document.createElement('input');
myButton.type = 'button';
myButton.value = value;
parent.prepend(myButton);
return myButton;
};
// eine Debugg funktion mit der man ein Objekt, komplett durchlaufen und auslesen kann
function showObjProps(obj) {
var output = '';
for (property in obj) {
output += property + ': ' + obj[property]+'; ';
}
alert(output);
};
// die Rollover Eigenschaften der Links definieren
$list.find('.st_link').bind('mouseenter',function(){
$(this).stop().animate({'opacity':'1'});
}).bind('mouseleave',function(){
$(this).stop().animate({'opacity':'0.5'});
});
// ein menüitem anklicken (up and down arrow)
// zeigt die thumbs an ….
$list.find('.st_arrow_down').live('click',function(){
var $this = $(this);
hideThumbs();
$this.addClass('st_arrow_up').removeClass('st_arrow_down');
var $elem = $this.closest('li');
$elem.addClass('current').animate({'height':'200px'},200);
var $thumbs_wrapper = $this.parent().next();
var pos = $this.position();
$thumbs_wrapper.show(200);
if($thumbs_wrapper.is('.desc_wrapper') ) {
$thumbs_wrapper.next().show(200);
$thumbs_wrapper.animate({'left': (pos.left + 120) + 'px'},200);
}
});
// …oder versteckt sie wieder
$list.find('.st_arrow_up').live('click',function(){
var $this = $(this);
$this.addClass('st_arrow_down').removeClass('st_arrow_up');
hideThumbs();
});
// live() oder bind()?
// in diesem Fall wird der click event mit live an die thumbnails gebunden
// beide Funktionen sind ähnlich, aber bind(), bindet den Event, an dieses
// eine Objekt, während live(), den Event an dieses eine und alle noch
// folgenden gleichen Objekte, also auch wenn man ein thumbnail löschen würde
// und dafür eine anderes ersetzt, bleibt die Bindung erhalten, was hier ja auf jedenfall
// gewünscht ist.
$list.find('.st_thumbs img').live('click',function(){
var $this = $(this);
// loading anzeigen….
$loader.show();
// enthält das title attribut, die zeichenfolge irgendwas .jpg, und zwar am ende?
var search = $this.attr('title').search(/.+\.jpg/);
// wird kein treffer gefunden, gibt die funktion search() -1 zurück.
if( search != -1 ) {
// ist search() nicht -1, brauchen wir ein <img>, es könnte aber noch ein video geladen sein.
var $currImage = $('#st_main').children(':first');
//ist firstchild der Player?
if( $currImage.is('#cuePlayer') ) {
// video auswerfen!
$currImage.find('#video').stop();
// durch das img ersetzen!
$currImage.fadeOut(2000,function(){
$(this).replaceWith('<img class="st_preview"/>');
});
}
// image in das img laden
$('<img class="st_preview"/>').load(function(){
var $this = $(this);
$currImage = $('#st_main').children('img:first');
$this.insertBefore($currImage);
$loader.hide();
$currImage.fadeOut(2000,function(){
$(this).remove();
});
}).attr('src',$this.attr('alt'));
} else {
// gibt search() -1 zurück, ist kein Bild, demnach ein Video gefragt
// ist firstchild der Player?
if($('#st_main').children(':first').is('#cuePlayer') ) {
$video = $('#video');
// die alten sources rauswerfen….
$video.stop();
$video.empty();
// und die neuen Videos reinladen, im Gegesatz zum Photo, wird für das Video das 'title'-Attribut des Thumbnails zum bilden der Aufrauf-URL verwendet, denn das 'alt'-Attribut, wird ja für die thumbnail.src gebraucht.
loadVideo($this.attr('title'));
// das video laden
$video.load();
// ist firstchild nicht der Player?
} else { $currImage = $('#st_main').children('img:first');
// neues videoelement erstellen
var $video = document.createElement('video');
// img durch html5 video element ersetzen
$currImage.fadeOut(2000,function() {
$(this).replaceWith($video);
// die angefragten sources reinladen
loadVideo($this.attr('title'));
// den loader verstecker
$loader.hide();
//und die cuePlayer section darumwickeln
}).wrap("<section id='cuePlayer'></section>");
// Video Eigenschaften definieren.
var vState = 'Pause'
$video.id = 'video';
$video.controls=true;
$video.autoplay = true;
$video.preload='none';
// Und die Handler zu den Events, die abgehört werden sollen, laden….
// Ich hab hier nur 3 die wichtigsten, also die minimal-config ausgeführt
// Alle Events und API der HTML5 Viedeo Componente, sind hier zu finden,
// http://www.w3.org/2010/05/video/mediaevents.html
// Anhand des dort gezeigten Beispiels, lässt sich genau nachverfolgen, welcher Event, wann gefeuert wird.
// Eventlistener und Handler 'loadedmetadata'-Event ( für IE6, IE7 und IE8 müsste der Aufruf so aussehen: $video.attachEvent(…..),
// ebenso der nächste, wir haben damit also schonmal 3 Verschiedene Eventhandlings für 5 Browser, ohne Mobilgeräte).
// Erschliesst sich mir nicht so ganz, denn das Video feuert ja den Event selbst, warum muss dann ein Eventlistener,
// den eigenen Event abhören??? funktioniert aber in Chrome & Safari nicht anders. Nicht notwendig in Firefox & Opera,
// da wäre $video.onloadedmetadata direkt als Eigenschaft vorhanden, was mir auch logischer erscheint und da funktioniert auch
// der Listener nur, wenn die Callback Funktion des Handlers, anonym und direkt im Eventlistener gestartet wird, für Chrome & Safari
// könnte man auch eine seperate Funktion mit Namen aufrufen. Dieser Event ist minimales MUST HAVE, denn es ist der Event,
// zu dem die Videodaten, wie Länge, Breite, Duration ect. im Skript bekannt werden und damit, DER PLATZ schlechthin, um CSS u. Parameter
// für Elemente zu setzen, die von der Beschaffenheit des Videos abhängen, wie Fortschritsbalken oder Laufzeitanzeige ect.
$video.addEventListener('loadedmetadata',
function(e) {
if(!$video.autoplay) vState = 'Play';
var playpause = createButton($('#video').parent(), vState);
playpause.id = 'playpause';
$('#playpause').bind('click',function(){
playpause.value = $video.paused ? 'Pause' : 'Play';
if ($video.paused) {
$video.play();
} else {
$video.pause();
}
}).css({'height': '20px',
'width' : '100px',
'top' : this.offsetTop,
'left' : '15px',
'border-radius':'5px'
});
$('#cuePlayer').css({
'height': (this.videoHeight + 40)+'px',
'width': this.videoWidth + 'px'});
}, false);
// Eventlistener und Handler 'canplaythrough'-Event
// Nicht ganz so essentiell, wie der Vorher aber auch wichtig. Der Event, wird gefeuert, wenn das Video soweit vorgeladen wurde,
// Das es komplett gespielkt werden kann, ohne unterbrechen zu müssen um nachzuladen, und ist somit eigentlich der richtige Moment,
// um das Video zu starten,
// Oder einen Play-Button für den Benutzer freizugeben.
$video.addEventListener('canplaythrough',
function(e) {
$video.play();
$loader.hide();
}, false);
// Die Mousehandler an den Player Binden
$('#cuePlayer').bind('mouseenter',
function(){
$('#playpause').show(200);
}).bind('mouseleave',function(){
$('#playpause').hide(200);
});
// Und Die Mousehandler für komplette Action
}).bind('mouseenter',function(){
$(this).stop().animate({'opacity':'1'});
}).bind('mouseleave',function(){
$(this).stop().animate({'opacity':'0.5'});
});
// Funktion um das Momentan geöffnete Menü zu schliessen
function hideThumbs(){
$list.find('li.current')
.animate({'height':'50px'},400,function(){
$(this).removeClass('current');
})
.find('.st_thumbs_wrapper')
.hide(200)
.andSelf()
.find('.st_link span')
.addClass('st_arrow_down')
.removeClass('st_arrow_up')
.andSelf()
.find('.desc_wrapper')
.hide(200);
}
// die Thumbnailnavigations divs skrollbar machen
// mit on-mouse-move-Handler, um die Thumbs bei Rollover automatisch zu scrollen.
function makeScrollable($outer, $inner){
var extra = 800;
var divWidth = $outer.width();
$outer.css({
overflow: 'hidden'
});
var lastElem = $inner.find('img:last');
$outer.scrollLeft(0);
$outer.unbind('mousemove').bind('mousemove',function(e){
extra = 800;
divWidth = $outer.width();
var containerWidth = lastElem[0].offsetLeft + lastElem.outerWidth() + 2*extra;
var left = (e.pageX – $outer.offset().left) * (containerWidth-divWidth) / divWidth – extra;
$outer.scrollLeft(left);
});
}
});
OK, das war jetzt eine Menge Code, ist aber leider nicht Anders zu machen. Wer kein Assetmanagement verwenden möchte oder wem das zuviel Coding ist, der kann sich auch