Für ein aktuelles WordPress-Kundenprojekt sollen Firmenlogos automatisiert vor einem kreisförmigen Hintergrund dargestellt werden. Die Aufgabenstellung war, die Logos trotz unterschiedlicher Seitenverhältnisse größtmöglich in den Kreis einzupassen, ohne dass eines irgendwo über den Rand drüberschaut. Mit Unterstufenmathematik recht einfach gelöst, nur wissen muss mans ;-)
Das Grundsetup: ein quadratisches DIV mit dem Kreis als Hintergrund, vor diesem soll das Logo dargestellt werden. Das HTML/PHP dazu:
<div class="kreis"><img style="position: absolute; left: ?px; top: ?px;" alt="" src="logo.jpg" width="?" height="?" /></div>
mit den einfachen CSS-Angaben
.kreis {
position: relative;
background: url(kreis.png);
width: 122px;
height: 122px; }
.kreis img {
position: absolute; }
Die Logos haben aber sehr unterschiedliche Seitenverhältnisse, somit ändert sich mit jedem dargestellten Logo die maximal mögliche Breite und Höhe sowie die Darstellungsposition. Ich benötigte also ein Codeschnipsel, das mir diese Werte je nach Logo korrekt ermittelt. Mit ein wenig Unterstufenmathematik war das kein Problem:
Man braucht den Radius des Kreises sowie die Originalbreite und -höhe der Logodatei. Wenn man sich das Logo im Kreis anschaut, gibts ein rechtwinkeliges Dreieck, dessen Informationen wir verwenden können, um die neue Breite und Höhe sowie die Position des Logos auszurechnen. Das Dreieck besteht aus der Diagonale des Logos (die immer dem doppelten Kreisradius entspricht!) sowie der gesuchten Logobreite und der gesuchten Logohöhe.
Wenn wir das Originallogo hernehmen, findet sich dort dasselbe Dreieck, nur größer. Man darf daher zu Recht davon ausgehen, dass die Winkel in diesem Dreieck gleich denen in unserem gesuchten Dreieck im verkleinerten Logo sind. Im rechtwinkeligen Dreieck gilt:
tan α = Gegenkathete / Ankathete
Diese beiden haben wir – die Gegenkathete ist die Höhe des Logos, die Ankathete ist die Breite. Originalbreite & -höhe des Logos kann man mit der PHP-Funktion getimagesize() auslesen.
tan α = h/b
α = arctan(h/b)
Damit haben wir den Winkel α – und dieser ist im Mini-Logo gleich wie in der Originaldatei! Und somit ist das Errechnen der restlichen Dreieckseiten im Mini-Logo wirklich einfach:
sin α = Gegenkathete / Hypotenuse
Die Hypotenuse ist der doppelte Kreisradius r (den wissen wir), die Gegenkathete ist die Logohöhe, die wir errechnen wollen. Somit ergibt sich:
sin α = h / (2 * r)
sin α * r * 2 = h
Somit haben wir die Höhe des verkleinerten Logos, die sich innerhalb des Kreises ausgeht.
cos α = Ankathete / Hypotenuse
Die Hypotenuse ist wiederum der doppelte Kreisradius r , die Ankathete ist die Logobreite. Somit ergibt sich:
cos α = b/ (2 * r)
cos α * r * 2 = b
Sinnvollerweise sollte man Höhe und Breite noch via PHP mit round() behandeln, damit ganze Zahlen rauskommen.
Um das Logo mit left und top zu positionieren, brauchen wir jetzt noch den Abstand des linken oberen Punktes des Logos vom linken oberen Punktes des Kreis-DIVs. Einfach: wir wissen den Kreisradius und die Logobreite und -höhe. Wie im Bild zu sehen ergibt sich also:
oberer Abstand = radius – h/2
linker Abstand = radius – b/2
Das Script um die Werte zu errechnen ist ziemlich einfach:
// Zuerst $radius und Dateipfad zum Logo definieren
$logofile = "/dateipfad/zum/logo.jpg";
$radius = 58; // in Pixel, entspricht der halben Höhe des DIV.kreis
// Originalhoehe / Originalbreite per getimagesize auslesen
if(file_exists($logofile)) $logosize = getimagesize($logofile);
$originalbreite = $logosize[0];
$originalhoehe = $logosize[1];
$tanAlpha = $originalhoehe/$originalbreite;
$alpha = atan($tanAlpha);
$logopos['hoehe'] = round(sin($alpha)*2*$radius,0);
$logopos['breite'] = round(cos($alpha)*2*$radius,0);
$logopos['x'] = $radius-($logopos['breite']/2);
$logopos['y'] = $radius-($logopos['hoehe']/2);
Die errechneten Werte nun noch dem Bild per PHP zuweisen – fertig:
<div class="kreis"><img style="position: absolute; left: <?php echo $logopos['x']; ?>px; top: <?php echo $logopos['y']; ?>px;" src="logo.jpg" width="<?php echo $logopos['breite']; ?>" height="<?php echo $logopos['hoehe']; ?>" /></div>
- Rezension vs. Rezession - Mi. 27.12.2023
- Was Corona und Lotto gemeinsam haben - Di. 9.11.2021
- Heute vor 20 Jahren hat das große Abenteuer Segeln für mich begonnen :-) - Mi. 28.4.2021