Lieber borisbaer,
Soll ich etwa keine Funktionen verwenden?
ganz anders: Versuche die Antwort auf „Was ist ein Marker?“ durch eine Liste an Eigenschaften zu beschreiben. Vielleicht so?
{
id: "1-2-1-half-moon-grass",
text: "Halfmoongrass × 3",
type: "item",
x: 606,
y: 324
};
Dann stellt sich die Frage, was ein solcher Marker alles können soll:
- Automatische Position der Beschriftung
- vertikale und horizontale Linien vom Ursprungspunkt zur Beschriftung ziehen
Das alles kann man in Funktionen stecken, die dann als Methoden eines Marker-Objektes in einer Klasse definiert werden. Dabei kann man sich dann auch überlegen, ob man das tatsächlich mit CSS-Angaben in inline-Styles realisiert, oder gleich ein SVG ins Dokument schreibt. Die Marker-Klasse, die man für einen Marker benötigt, kann die nötigen Werte generieren, damit eine Map-Klasse ihr SVG damit bauen kann.
Die Verwendung könnte so aussehen:
$map = new \MarkedMap();
$map->loadWebpImage(
// path to webp image file
'./games/demons-souls/images/maps/map/boletarian-palace/the-lords-path/1.webp'
);
$map->addMarker(
new \MapMarker([
'id' => '1-2-1-half-moon-grass',
'text' => 'Halfmoongrass × 3',
'type' => 'item',
'x' => 606,
'y' => 324
])
);
Die im Beispiel angenommene \MarkedMap-Klasse könnte so aussehen:
class MarkedMap {
private img; // GD lib image object
private markers = [];
public function __construct () {
// noch nix zu tun
}
public function loadWebpImage ($path) {
$this->img = imagecreatefromwebp($path);
}
public function render () {
// ... magic ... -> SVG ...?
// ... magic ... -> <div>-Suppe mit leckeren inline-styles?
foreach ($this->markers as $marker) {
$rendering = $marker->render();
// tu was mit $rendering['label']['x']
// tu was mit $rendering['label']['y']
// tu was mit $rendering['label']['text']
if (!empty($rendering['lines'])) {
foreach ($rendering['lines'] as $line) {
// tu was mit $line['start']['x']
// tu was mit $line['start']['y']
// tu was mit $line['end']['x']
// tu was mit $line['end']['y']
}
}
}
}
public function setMarker ($marker) {
$this->markers[] = $marker;
}
}
class MapMarker {
private $id = uniqid();
private $text = 'default text';
private $type = 'item';
private $x = 0;
private $y = 0;
public function __construct ($params) {
foreach ($params as $key => $value) {
if (property_exists($this, $key)) {
$this->{$key} = $value;
}
}
}
public function render ($img_height, $img_width) {
// Horizontale Position und Breite des Textes festlegen
// Ergebnis könnte das hier sein
$left = 52;
$top = 12;
$width = strlen($this->title);
return [
'label' => [
'x' => $left,
'y' => $top,
'text' => $this->title
],
'lines' => [
// senkrechte Linie
[
'end' => ['x' => $this->x, 'y' => $top],
'start' => ['x' => $this->x, 'y' => $this->y]
],
// waagrechte Linie
[
'end' => ['x' => $left + $width, 'y' => $top],
'start' => ['x' => $this->x, 'y' => $top]
],
]
];
}
}
Natürlich habe ich keine Ahnung oder Code-auf-die-Schnelle, was die render
-Methode der \MarkedMap-Klasse hier genau macht. Das hängt zum Einen davon ab, ob Du nun SVG erzeugen möchtest, oder mit HTML/CSS-Mitteln hantieren willst. Die Marker bekommen eine eigene Klasse, damit sie ihre Positionierungen cleverer festlegen können, als das eine einzelne Methode in der ganzen \MarkedMap-Klasse könnte (sie wäre dann unhandlich groß und schwer wartbar).
Die SVG-Lösung hat den Charme, dass Du dafür XML generierst, welches sich mit der DOMDocument-Klasse und ihren DOM-Methoden in PHP erzeugen lässt. Also kein XML-Code im PHP-Quelltext. Und anklickbare Links sind damit auch noch möglich (dazu muss natürlich die \MapMarker-Klasse passend erweitert werden)!
Du merkst, ich tendiere zu einer Lösung, die SVG verwendet. Leider habe ich selbst damit kaum Erfahrung, kann also nur theoretisch SVG empfehlen. Eine konkrete Umsetzung würde aber Dein Wissen und Deine Erfahrung wesentlich weiter bringen!
Liebe Grüße
Felix Riesterer