Bilderanimation: ishow

Erstellt am 07.03.2022 Lesedauer 1 - 2 Min.

Eine ausschließlich CSS-basierte „Diashow“ mit verschiedenen Animationsmöglichkeiten. Jedes Bild kann optional ein individuelles Sprungziel beim Anklicken/Antippen haben.

Das Modul erwartet Bilder im angegebene Verzeichnis. Die Daten dafür können mit dem Yaml-Eintrag upload unter Angabe dieses Pfades in einem Zug auf den Server geladen werden.

Aufruf

[ishow IMAGEPATH DURATION SWIPE DTYPE DRIM]

Parameter

imagepath

Der Root-basierte Pfad zum Bildverzeichnis.

Alle Bilder im Verzeichnis werden angezeigt, das erste definiert die Höhe der Animation.

„Das erste Bild“ wird alphabetisch in der Reihenfolge der Bidltype svg, webp,png, jpg, gif gesucht. D.h. bei den Bildern bild1.jpg,bild2.webp, bild3.svg legt bild3.svg die Höhe fest.

duration

Anzeigedauer pro Bild, Standard sind 4 Sekunden

swipe

Überblenddauer zwischen den Bildern, Standard ist eine Sekunde

dtype

Animationstyp Verfügbar sind

show

(default): Bilder erscheinen/verschwinden zentriert

left

Animation von rechts nach links

right

… von links nach rechts

up

… von unten nach oben

down

… von oben nach unten

pump

zentriertes Vergrößern/Verkleinern (in die Mitte)

zoom

zentriertes verkleiner/vergrößern (über den Rand)

fly

Einfliegen von links, ausfliegen nach rechts

drim

ein optionaler Rahmen um die Show

(default 0→aus): Alles ≠ 0. |

Das Modul

Für die Animation wird mittels PHP wird der erforderliche CSS-Code erzeugt, der die Diashow steuert und die Bilder in der Ausgabe plaziert.

Für die Adressierung der Bilder werden IDs generiert, deshalb kann eine Seite nur eine (damit erzeugte) Animation enthalten.

ishow pfad duration=4 swipe=1 dtype=show drim=0
<?php
 $dir = '§§§pfad§§§';
 $duration = §§§duration§§§;
 $swipe = §§§swipe§§§;
 $dtype = '§§§dtype§§§';
 $drim = '§§§drim§§§'; // <>0 → Rahmen
 $links = $_SERVER["DOCUMENT_ROOT"].'§§§pfad§§§links.ini';
 $files = glob($_SERVER['DOCUMENT_ROOT'] .$dir.'*{svg,webp,png,jpg,gif,avif}', GLOB_BRACE);
 // Es müssen Bilder gefunden werden
 $fcount = count($files);
 if ($fcount>0) {
	 // Gibt es Links?
	(file_exists($links)) ? $besch = parse_ini_file($links) : $besch = []; 
	 // Rahmenformat, wenn drim<>0 ist
	($drim<>'0') ? $drim ='border:solid rgb(230,230,230) 1px;border-radius:6px;padding:3px' : $drim ='';
	// Grundlegende Stile
	$ishow = '<style>.iout {width: 100%; margin:0 auto; position:relative; overflow:hidden;'. $drim .'}';
	 $ishow .= ".ishow div{width:100%;position:absolute; height:auto;text-align:center;transform:translateX(110%);";
	 $ishow .= "display:flex; justify-content: center;  align-items: center;height:100%;}";
	 $ishow .= ".ishow div img, .fill img {max-width:100%;height: auto;padding:0px;margin:0 auto;display:block;overflow: hidden;}";
	 $ishow .= ".fill {vertical-align:center;}";
	 $ishow .= ".fill img {visibility:hidden;}";
	// Container für die Bilder erzeugen
	$ishow .= '#ic';
	for ($i = $fcount - 1; $i > 0; $i--) {
		$ishow .= $i.',#ic';
	}
	$full = ($duration + $swipe) * $fcount;
	$ishow .= '0 {animation: '.$full.'s theshow infinite ease-in-out; ' . ((count($besch)>0) ? 'cursor: pointer;' :'') .'}';
 
	for ($i = 1; $i < $fcount; $i++) {
		$ishow .= '#ic'.$i.' {animation-delay:'.($duration + $swipe) * $i.'s}';
	}
	// Timing für jedes Bild setzen
	$seq = round(($duration + $swipe) / $full * 100, 2);
	$sep = round(($swipe / $seq) * 100, 2);
	$ishow .= ' @keyframes theshow {';
	// Stile für die verschiedenen Präsentationstypen
	switch ($dtype) {
	case "left":
		$ishow .= "0%{transform: translateX(110%); }";
		$ishow .= $sep."% {transform: translateX(0);}";
		$ishow .= $seq."% {transform: translateX(0);}";
		$ishow .= $seq + $sep."%{transform: translateX(-110%); }";
		$ishow .= "100%{transform: translateX(-110%); }";
		break;
	case "right":
		$ishow .= "0%{transform: translateX(-110%); }";
		$ishow .= $sep."% {transform: translateX(0);}";
		$ishow .= $seq."% {transform: translateX(0);}";
		$ishow .= $seq + $sep."%{transform: translateX(110%); }";
		$ishow .= "100%{transform: translateX(110%); }";
		break;
	case "up":
		$ishow .= "0%{transform: translate(0%,110%);}";
		$ishow .= $sep."% {transform: translateY(0%)}";
		$ishow .= $seq."% {transform: translate(0%,0%);}";
		$ishow .= $seq + $sep."%{transform: translateY(-110%)}";
		$ishow .= "100%{transform: translateY(-110%)}";
		break;
	case "down":
		$ishow .= "0%{transform: translate(0%,-110%);}";
		$ishow .= $sep."%{transform: translateY(0%)}";
		$ishow .= $seq."%{transform: translate(0%,0%);}";
		$ishow .= $seq + $sep."%{transform: translateY(110%)}";
		$ishow .= "100%{transform: translateY(110%)}";
		break;
	case "pump":
		$ishow .= "0%{transform: scale(0);}";
		$ishow .= $sep."% {transform: scale(1);}";
		$ishow .= $seq."% {transform: scale(1);}";
		$ishow .= $seq + $sep."%{transform:scale(0);}";
		$ishow .= "100%{transform: translateX(-110%);}";
		break;
	case "zoom":
		$ishow .= "0%{transform: translateX(0%) scale(10);opacity: 0;}";
		$ishow .= $sep."% {transform: scale(1);opacity: 1;}";
		$ishow .= $seq."% {transform: scale(1);opacity: 1;}";
		$ishow .= $seq + $sep."%{transform:scale(10);opacity: 0;}";
		$ishow .= "100%{transform: translateX(-110%) scale(1);opacity: 0;}";
		break;
	case "fly":
		$ishow .= "0%{transform: scale(0.5) translate(-250%, -250%) skew(45deg, 0deg) rotate(180deg);}";
		$ishow .= $sep."% {transform: translateX(0%) rotate(0deg);}";
		$ishow .= $seq."% {transform: translateX(0%);}";
		$ishow .= $seq + $sep."%{transform: scale(0.5) translate(250%, -250%) skew(-45deg, 0deg) rotate(-180deg);}";
		$ishow .= "100%{transform: translateX(-200%,-200%) skew(45deg, 0deg) rotate(180deg);;}";
		$ishow .= "100%{transform: scale(0.5) translate(250%, -250%) skew(-45deg, 0deg) rotate(-180deg);}";
		break;
	case "show":
	default:
		$ishow .= "0%{transform: translateX(0%);opacity: 0 ;}";
		$ishow .= $sep."% {opacity: 1; }";
		$ishow .= $seq."%{opacity: 1; } ";
		$ishow .= $seq + $sep."%{opacity: 0; }";
		$ishow .= "100%{transform: translateX(0%);opacity: 0;}";
		break;
	}
	// Stile abschließen und den „sichtbaren Teil“ bauen
	$ishow .= '}</style>'."\n".'<div class="iout"><div class="ishow">'.PHP_EOL;
	// Die Bilddateien holen
	$i = 0;	
	foreach($files as $file) {
		// Das erste Bild in der Reihe legt die Containergröße fest
		if (0 == $i) {
			$first = $dir . basename($file);
		}
		// Bildcontainer
		$tx = pathinfo($file,PATHINFO_FILENAME);
		(isset($besch[$tx])) ? $dlink = True : $dlink = false;		
		if ($dlink) {
			(strpos($besch[$tx],'ttp')==1) ? $ext = '" target="_blank"' : $ext = '"';
		} 
		$ishow .= '<div id="ic'.$i.'">'. ($dlink ? '<a href="'.$besch[$tx].$ext. '>' : '').'<img src="' . $dir . basename($file) .'"/>'.($dlink ? '</a>' : '').'</div>'.PHP_EOL;
		$i++;
	}
	// Abstandshalter für dynamische Skalierung
	$ishow .= '</div><div class="fill"><img loading=lazy src="'.$first.'" /></div></div>'."\n";
 }
 else {
	$ishow = '<p><em>Hier sollte eine Diashow angezeigt werden ( '. $dir .' ), allerdings wurden keine Bilder dafür gefunden.</em></p>';
}
echo $ishow;
?>

Sprungziele

Im Bildverzeichnis kann eine Datei „links.ini“ den Bildern Sprungziele zuordnen:

bildateiname-ohne-Extender=Hyperlink
  • Bilder mit gleichem Namen unterschiedlichen Typs haben das selbe Sprungziel.
  • Die Links können lokal und extern sein. Externe Links werden am "ttp" an der zweiten Stelle1 erkannt und in ein neues Fenster umgelenkt. Lokale Verknüpfungen (ohne „ttp“) wechseln den Fensterinhalt.
  • Hat ein Bild eine Sprungmarke, erscheint unabhängig davon, ob das Bild mit einem Sprungziel verknüpft ist, immer ein „Zeigefinger“ über der Galerie.

Beispiel

[ishow /media/bilder/ 2 0.5 fly x]

Erzeugte Ausgabe

Die Bilder mit Sprungzielen haben lokale und externe, weitestgehend sinnfreie Adressen. Abgesehen vom NoSi-Logo haben sie keinen Kontext zum Linkziel.

1Das deckt mit einem kurzen Suchmuster http und https ab.