Ich betrachte den Fall, dass der Nutzer eine Farbe auswählen möchte, die perfekt auf ein im Post enthaltenes Bild abgestimmt ist. Dann wäre es wünschenswert, wenn die Auswahl direkt durch Anklicken einer bestimmten Stelle in einem ausgewählten Bild erfolgen könnte. Das im ersten Teil entwickelte Plugin werde ich um diese Funktionalität erweitern. Folgende Schritte sind notwendig:
- Die Meta-Box wird erweitert, sodass ein Bild aus der Media-Library geladen werden kann.
- Dem ausgewählten Bild wird eine Event-Handler-Funktion zugeordnet, die beim Anklicken des Bildes aufgerufen wird.
- Die Handler-Funktion extrahiert den Farbwert des Bildes an der angeklickten Position. Dazu muss das Bild zunächst in ein Canvas-Element importiert werden.
- Der Color-Picker wird mit dem Farbwert initialisiert.
Abbildung links zeigt meine Meta-Box bei der Bearbeitung meines Posts 'blühende Brennnesseln', in die ich über den Button 'Choose or upload an image' ein Bild importiert habe. Ich habe den violetten Lichtstreifen im Bild angeklickt, die Farbe wurde in den Color-Picker übernommen. Dementspechend hat mein Post eine violette Menüleiste.
1. Erweiterung der Meta-Box
Zuerst muss der HTML-Code für den Inhalt der Meta-Box erweitert werden. Zum einen wird ein Button benötigt, über den der Nutzer in die Medienbibliothek gelangt. Zum anderen bietet es sich an, ein leeres Div-Element als Container für das ggf. vom Nutzer ausgewählte Bild anzulegen. Die Funktion 'specific_colors_inner_box' sieht dann wie folgt aus:
function specific_colors_inner_box(){
?>
<p id="specific_colors_p">
<label>Color value for the navigation bar:<label>
<input class="meta-color-picker" name="meta-color-nav" id="meta-color-nav" type="text"
value="<?php echo esc_attr( get_post_meta( get_the_ID(), 'meta-color-nav', true ) ); ?>"/>
<input type="button" id="meta-image-button" class="button" value="Choose or upload an image" />
<div id="meta-image-div"></div>
</p>
<?php
}
2. Initialisierung der Media-Library
Ich wechsele nun zur Javascript-Datei. Der Javascript-Code muss erweitert werden, damit beim Klick auf den Button mit der ID 'meta-image-button' die Media-Library geöffnet wird.
jQuery(document).ready(function($){
$('.meta-color-picker').wpColorPicker();
var meta_image_frame;
$('#meta-image-button').click(function(e){
e.preventDefault();
if ( meta_image_frame ) {
meta_image_frame.open();
return;
}
meta_image_frame = wp.media.frames.meta_image_frame = wp.media({
title: meta_image.title,
button: { text: meta_image.button },
library: { type: 'image' }
});
// Runs when an image is selected.
meta_image_frame.on('select', function(){
var media_attachment = meta_image_frame.state().get('selection').first().toJSON();
$('#meta-image-div').html( '<img id="specific_colors_img" src="'+media_attachment.url+
'" alt="" style="max-width:100%;"/>' );
});
meta_image_frame.open();
});
});
Im Event-Handler für das 'select'-Ereignis wird dem Container-Div 'meta-image-div' das ausgewählte Bild als Kindelement zugeordnet.
Bei der Initialisierung der Media-Bibliothek wird auf ein Objekt 'meta_image' mit den Eigenschaften 'title' und 'button' zugegriffen. Wo das Objekt herkommt, wird im Folgenden erläutert.
Damit die Javascript-Methoden zur Initialisierung der Media-Bibliothek überhaupt zur Verfügung stehen, müssen in der PHP-Datei noch die benötigten Scripts und Styles angefordert werden. Dies geschieht in einem Handler für die Aktion 'admin_enqueue_scripts'. Er existiert bei mir bereits unter dem Funktionsnamen 'specific_colors_add_picker'. Dort ergänze ich nun folgende Anweisungen:
wp_enqueue_media();
wp_localize_script( 'specific_colors_js', 'meta_image',
array('title' => 'Choose or Upload an Image',
'button' => 'Use this Image'
)
);
Die Funktion 'wp_enqueue_media()' stellt alle benötigten Scripts und Styles für die Media-Bibliothek bereit. Die Funktion 'wp_localize_script' ergänzt den Javascript-Code für mein Script mit dem Namen 'specific_colors_js' um ein Objekt mit dem Namen 'meta_image'. Seine Eigenschaften werden als Array von Eigenschaft-Wert-Paaren übergeben. Ich hätte auch auf diesen Aufruf verzichten und stattdessen das Objekt direkt im Javascript-Code initialisieren können. Es lohnt sich jedoch, die Funktion kennenzulernen, denn sie bietet die Möglichkeit, die von einem Skript benötigten Daten dynamisch zu ermitteln und an das Skript zu übergeben, ohne dass die Javascript-Datei geändert werden muss.
3. Implementierung der Farbauswahl durch Anklicken des Bildes
Ich definiere nun, was passieren soll, wenn der Nutzer das ausgewählte Bild anklickt. Die Handler-Funktion für das 'click'-Ereignis ergänze ich innerhalb des 'select'-Handlers nachdem das Bild mit der ID 'specific_colors_img' erstellt wurde (vgl. Abschnitt 2).
...
meta_image_frame.on('select', function(){
...
$("#specific_colors_img").click(function(event){
var img = document.getElementById('specific_colors_img');
var canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height);
var p = canvas.getContext('2d').getImageData(event.offsetX, event.offsetY, 1, 1).data;
var hex = rgbToHex(p[0], p[1], p[2]);
$('.meta-color-picker').wpColorPicker('color', hex);
});
...
Die Handler-Funktion fügt die Bilddaten in ein dynamisch erstelltes Canvas-Element ein. Die Eigenschaften event.offsetX und event.offsetY enthalten die X- und Y-Koordinaten der Position des Mauszeigers beim Anklicken des Bildes. Die Funktion 'getImageData' liefert die Rot-, Grün- und Blauwerte des Bildes an dieser Position. Die Hilfsfunktion 'rgbToHex' rechnet die drei Werte in die übliche Hexadezimaldarstellung um. Mit dem Hex-Wert wird im letzten Schritt der Color-Picker neu initialisiert.
Hier noch der Code der Hilfsfunktionen:
function rgbToHex(r, g, b) {
return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
}
function componentToHex(c) {
var hex = c.toString(16);
return hex.length == 1 ? "0" + hex : hex;
}
4. Installation des Plugins
Der Plugin-Ordner, der die PHP- und Javascript-Dateien enthält, muss nun in eine zip-Datei verpackt werden. Diese zip-Datei lässt sich bei WordPress im Plugins-Bereich hochladen und aktivieren.
Links
WordPress Code Reference --> zum Nachschlagen aller verwendeten WordPress-Funktionen
WordPress Meta Boxes Guide --> ein gut verständliches Tutorial, welches die Möglichkeiten zur Gestaltung von Meta-Boxen aufzeigt.
W3Schools Canvas Reference --> Beispiele zur Verwendung der Methode 'getImageData'