So erstellen Sie ein jQuery Image Cropping Plugin aus Scratch - Teil I

Webanwendungen müssen benutzerfreundliche Lösungen für das Hochladen und Bearbeiten von Rich Content bieten. Dieser Vorgang kann für einige Benutzer mit minimalen Fähigkeiten zur Bearbeitung von Fotos Schwierigkeiten verursachen. Das Zuschneiden ist eine der am häufigsten verwendeten Techniken zur Bearbeitung von Fotos. In diesem Schritt-für-Schritt-Tutorial wird der gesamte Entwicklungsprozess eines Plug-ins für das Zuschneiden von Bildern für die jQuery-JavaScript-Bibliothek beschrieben.


Schritt 1. Einrichten des Arbeitsbereichs

Zunächst richten wir unseren Projektarbeitsbereich für dieses Lernprogramm ein. Beginnen Sie mit dem Erstellen einer Hierarchie von Verzeichnissen und leeren Dateien, die wie in der folgenden Abbildung dargestellt benannt sind:

Als Nächstes müssen Sie die jQuery-JavaScript-Bibliothek herunterladen und in der / resources / js / Mappe. Das in diesem Tutorial verwendete Bild muss einen Namen haben beispiel.jpg und im Inneren platziert / Ressourcen / Bilder / Mappe. Sie können dieses Bild verwenden (Dank an gsso-stock), die mit den Quelldateien dieses Tutorials oder einer von Ihnen geliefert werden. Und die letzte Datei ist die Gliederung.gif Datei, die in der / resources / js / imageCrop / Mappe.


Schritt 2. Erstellen der Testseite

Um unser Plug-in zu testen, müssen wir es an ein Image anhängen. Bevor wir mit der Arbeit beginnen, erstellen wir eine einfache Seite mit diesem Bild.

Das HTML

Öffne die index.html Datei in Ihrem bevorzugten Texteditor und schreiben Sie den folgenden Code.

     jQuery Image Cropping Plug-In       

jQuery Image Cropping Plug-In

jQuery Image Cropping Plug-In

Hier ist nichts Besonderes: Nur reiner HTML-Code. Wir haben ein Stylesheet für die Seite, jQuery, unsere Plug-In-Dateien (die derzeit leer sind) geladen und ein Bild in das Dokument eingefügt.

Das CSS

Jetzt bearbeiten style.css wie oben gezeigt.

 * Marge: 0; Umriss: 0; Polsterung: 0;  body background-color: #ededed; Farbe: # 646464; Schriftfamilie: 'Verdana', 'Geneva', serifenlos; Schriftgröße: 12px; Text-Schatten: 0 1px 0 #ffffff;  h1 font-size: 24px; Schriftgewicht: normal; Marge: 0 0 10px 0;  div # wrapper margin: 25px 25px 25px 25px;  div.bild-decorator -moz-border-radius: 5px 5px 5px 5px; -moz-box-shadow: 0 0 6px # c8c8c8; -webkit-border-radius: 5px 5px 5px 5px; -webkit-box-shadow: 0 0 6px # c8c8c8; Hintergrundfarbe: #ffffff; Rahmen: 1px fest # c8c8c8; Grenzradius: 5px 5px 5px 5px; Box-Schatten: 0 0 6px # c8c8c8; Anzeige: Inline-Block; Höhe: 360px; Polsterung: 5px 5px 5px 5px; Breite: 480px; 

Wir haben den Aspekt unserer Seite angepasst, indem wir die Hintergrundfarbe geändert haben und dem Titel und dem Bild ein grundlegendes Styling hinzufügen.


Schritt 3. Ein grundlegendes jQuery-Plug-In schreiben

Beginnen wir mit dem Erstellen eines grundlegenden jQuery-Plug-Ins.

"In diesem Beitrag erfahren Sie mehr darüber, wie Sie Ihr eigenes Plug-In schreiben. Es beschreibt die Grundlagen, bewährten Vorgehensweisen und häufigen Fallstricke, auf die Sie achten müssen, wenn Sie mit dem Schreiben Ihres Plug-Ins beginnen."

Öffnen /resources/js/imageCrop/jquery.imagecrop.js und fügen Sie den folgenden Code hinzu.

 // Ein Plug-In immer umwickeln '(function ($) // Plug-In geht hier hin) (jQuery);' (Funktion ($) $ .imageCrop = Funktion (Objekt, customOptions) ; $ .fn.imageCrop = Funktion (customOptions) // Über jedes Objekt it.each (function () var currentObject = this, image) = new Image (); // und füge imageCrop hinzu, wenn das Objekt geladen wird image.onload = function () $ .imageCrop (currentObject, customOptions);; // Die src zurücksetzen, weil zwischengespeicherte Bilder manchmal kein Bild laden .src = currentObject.src;); // Wenn das Plug-In keinen intrinsischen Wert zurückgibt, muss immer die // Funktion das Schlüsselwort 'this' zurückgeben, damit die Kettenfähigkeit erhalten bleibt;;) (jQuery);

Wir haben jQuery gerade um die neue Funktionseigenschaft erweitert jQuery.fn Objekt. Jetzt haben wir ein sehr einfaches Plug-In, das jedes Objekt durchläuft und anhängt imageCrop wenn das Objekt geladen ist. Beachten Sie, dass die zwischengespeicherten Bilder nicht ausgelöst werden Belastung Manchmal setzen wir das zurück src Attribut, um dieses Problem zu beheben.


Schritt 4. Anpassbare Optionen hinzufügen

Durch die Berücksichtigung von Anpassungsoptionen ist ein Plug-In für den Benutzer wesentlich flexibler.

 $ .imageCrop = function (object, customOptions) // Anstatt eine längere Anzahl von Argumenten anzufordern, übergeben Sie die // Plug-In-Optionen in einem Objektliteral, das über die // Standardeinstellungen des Plug-Ins erweitert werden kann. var defaultOptions =  allowMove: true, allowResize: true, allowSelect: true, minSelect: [0, 0], outlineOpacity: 0.5, overlayOpacity: 0.5, selectionPosition: [0, 0], selectionWidth: 0, selectionHeight: 0; // Optionen auf default setzen var options = defaultOptions; // Und mische sie mit den benutzerdefinierten Optionen zusammen setOptions (customOptions); ; 

Wir haben ein Array mit den Standardoptionen definiert und dann mit den benutzerdefinierten Optionen zusammengeführt, indem Sie die setOptions Funktion. Gehen wir weiter und schreiben den Körper dieser Funktion.

? // Aktuelle Optionen mit der benutzerdefinierten Option zusammenführen Funktion setOptions (customOptions) options = $ .extend (options, customOptions); ; 

Das $ .extend () Funktion verbindet den Inhalt von zwei oder mehr Objekten mit dem ersten Objekt.

Die Optionen

In der folgenden Liste werden die einzelnen Optionen des Plug-Ins beschrieben.

  • allowMove - Gibt an, ob die Auswahl verschoben werden kann (Standardwert ist) wahr).
  • allowResize - Gibt an, ob die Größe der Auswahl geändert werden kann (Standardwert ist wahr).
  • allowSelect - Gibt an, ob der Benutzer eine neue Auswahl treffen kann (Standardwert ist wahr).
  • minSelect - Mindestbereich für die Registrierung einer neuen Auswahl (Standardwert ist [0, 0]).
  • GliederungOpacity - Die Deckkraft der Gliederung (Standardwert ist 0,5).
  • overlayOpacity - Overlay-Deckkraft (Standardwert ist 0,5).
  • selectionPosition - Die Auswahlposition (Standardwert ist [0, 0]).
  • AuswahlBreite - Die Auswahlbreite (Standardwert ist 0).
  • AuswahlHöhe - Die Auswahlhöhe (Standardwert ist 0).

Schritt 5. Einrichten der Ebenen

In diesem Schritt ändern wir das DOM, um für den nächsten Schritt vorbereitet zu sein: die Schnittstelle des Plug-Ins.

Zuerst initialisieren wir die Bildebene.

? // Die Bildebene initialisieren var $ image = $ (object); 

Initialisieren Sie nun einen Bildhalter.

? // einen Bildhalter initialisieren var $ holder = $ ('
') .css (position:' relative ') .width ($ image.width ()) .height ($ image.height ()); // Wickle den Halter um das Bild. $ Image.wrap ($ holder) .css (position: 'absolute');

Wie Sie sehen, hat die Halterebene die gleiche Größe wie das Bild und eine relative Position. Als nächstes rufen wir die .wickeln() Funktion, um das Bild in den Halter zu legen.

Über dem Bild befindet sich die Überlagerungsebene.

? // Initialisiere eine Overlay-Ebene und platziere sie über dem Bild var $ overlay = $ ('
') .css (Deckkraft: Optionen.overlayOpacity, Position:' absolut ') .width ($ image.width ()) .height ($ image.height ()) .insertAfter ($ image);

Diese Ebene hat die gleiche Größe wie das Bild, wurde aber auch absolut positioniert. Den Wert für die Deckkraft erhalten wir aus dem options.overlayOpacity und lassen Sie es von jQuery anwenden. Dieses Element hat auch eine ID, sodass wir seine Eigenschaften über das Stylesheet des Plug-Ins ändern können. Ganz unten nennen wir das .insertAfter () Methode, um die Überlagerungsebene direkt nach dem Bild zu platzieren.

Die nächste Schicht ist die Auslöseschicht. Wir platzieren es hinter der Overlay-Ebene, genau wie bei den vorherigen.

? // Initialisiere eine Trigger-Ebene und platziere sie über der Overlay-Ebene var $ trigger = $ ('
') .css (backgroundColor:' # 000000 ', Deckkraft: 0, Position:' absolut ')) .width ($ image.width ()) .height ($ image.height ()) .insertAfter ($ overlay) ;

Die Hintergrundfarbe spielt keine Rolle, muss aber anders als transparent sein (standardmäßig). Diese Ebene ist vom Benutzer nicht sichtbar, behandelt jedoch einige Ereignisse.

Wir werden die Gliederungsebene über der Triggerebene platzieren.

? // Initialisiere eine Gliederungsebene und platziere sie über der Triggerebene var $ outline = $ ('
') .css (opacity: options.outlineOpacity, Position:' absolut ') .insertAfter ($ trigger);

Und zum Schluss die letzte Schicht.

? // Eine Selektionsebene initialisieren und über der Gliederungsebene platzieren var $ selection = $ ('
') .css (Hintergrund:' url ('+ $ image.attr (' src ') +') keine Wiederholung ', Position:' absolut ') .insertAfter ($ contour);

Das .attr () Die Methode gibt den Wert eines angegebenen Attributs zurück. Wir haben es verwendet, um die Bildquelle abzurufen und als Hintergrund für die Auswahlebene festzulegen.

Absolute Positionierung innerhalb der relativen Positionierung

Sie wissen dies vielleicht bereits, aber ein Element mit relativer Positionierung gibt Ihnen die Möglichkeit, Elemente absolut darin zu positionieren. Deshalb hat die Trägerschicht eine relative Position und alle ihre Kinder eine absolute Position.

Eine hervorragende Erklärung für diesen Trick finden Sie in diesem Artikel.


Schritt 6. Aktualisieren der Schnittstelle

Zunächst initialisieren wir einige Variablen.

? // Globale Variablen initialisieren var selectionExists, selectionOffset = [0, 0], selectionOrigin = [0, 0]; 

Das selectionExists informiert uns, wenn eine Auswahl vorliegt. Das selectionOffset enthält den Versatz relativ zum Bildursprung und die selectionOrigin zeigt den Ursprung der Auswahl an. Nach wenigen Schritten wird es viel klarer.

Die folgenden Bedingungen sind erforderlich, wenn die Auswahl beim Laden des Plug-Ins vorhanden ist.

? // Überprüfen Sie, ob die Auswahlgröße größer als das akzeptierte Minimum ist //, und legen Sie die Existenz der Auswahl entsprechend fest. If (options.selectionWidth> options.minSelect [0] && options.selectionHeight> options.minSelect [1]) selectionExists = true; else selectionExists = false; 

Als nächstes rufen wir die an updateInterface () Funktion zum ersten Mal, um die Schnittstelle zu initialisieren.

? // Zum ersten Mal die Funktion 'updateInterface' aufrufen, um // die Plug-In-Schnittstelle zu initialisieren. UpdateInterface (); 

Wir werden in Kürze den Körper dieser Funktion schreiben. Jetzt kümmern wir uns um unsere erste Veranstaltung.

? if (options.allowSelect) // Binden Sie einen Event-Handler an das 'mousedown' -Ereignis der Trigger-Ebene. $ trigger.mousedown (setSelection); 

Wir nennen .Maus nach unten() ob options.allowSelect ist wahr. Dies bindet einen Event-Handler an die Maus nach unten Ereignis der Trigger-Schicht. Wenn also ein Benutzer auf das Bild klickt, wird die setSelection () wird aufgerufen.

? // Hole den aktuellen Offset eines Elements function getElementOffset (object) var offset = $ (object) .offset (); return [offset.left, offset.top]; ; // Die aktuelle Mausposition relativ zur Bildpositionsfunktion abrufen getMousePosition (event) var imageOffset = getElementOffset ($ image); var x = event.pageX - imageOffset [0], y = event.pageY - imageOffset [1]; x = (x < 0) ? 0 : (x > $ image.width ())? $ image.width (): x; y = (y < 0) ? 0 : (y > $ image.height ())? $ image.height (): y; return [x, y]; ; 

Die erste Funktion, getElementOffset (), gibt die linken und oberen Koordinaten des angegebenen Objekts relativ zum Dokument zurück. Wir haben diesen Wert durch Aufruf von erhalten .Versatz () Methode. Die zweite Funktion, getMousePosition (), gibt die aktuelle Mausposition zurück, jedoch relativ zur Bildposition. Wir arbeiten also mit Werten, die nur zwischen 0 und der Bildbreite / -höhe auf der x / y-Achse liegen.

Lassen Sie uns eine Funktion zum Aktualisieren unserer Ebenen schreiben.

? // Aktualisieren Sie die Overlay-Layer-Funktion updateOverlayLayer () $ overlay.css (display: selectionExists? 'Block': 'none'); ; 

Diese Funktion prüft den Wert von selectionExists Variable und bestimmt, ob die Overlay-Ebene angezeigt werden soll oder nicht.

? // Aktualisieren Sie die Trigger-Layer-Funktion updateTriggerLayer () $ trigger.css (Cursor: Optionen.allowSelect? 'Crosshair': 'default'); ; 

Das updateTriggerLayer () Funktion ändert den Cursor in Fadenkreuz oder Standard, abhängig von options.allowSelect Wert.

Als nächstes schreiben wir die updateSelection () Funktion. Es wird nicht nur die Auswahlschicht, sondern auch die Gliederungsebene aktualisiert.

? // Aktualisieren Sie die Auswahlfunktion updateSelection () // Aktualisieren Sie die Gliederungsebene $ outline.css (Cursor: 'default', display: selectionExists? 'Block': 'none', links: options.selectionPosition [0], oben : options.selectionPosition [1]) .width (options.selectionWidth) .height (options.selectionHeight); // Aktualisieren Sie die Auswahlebene $ selection.css (backgroundPosition: (- options.selectionPosition [0] - 1) + 'px' + (- options.selectionPosition [1] - 1) + 'px', Cursor: Optionen. allowMove? 'move': 'default', display: selectionExists? 'block': 'none', left: options.selectionPosition [0] + 1, oben: options.selectionPosition [1] + 1) .width ((options .selectionWidth - 2> 0) (options.selectionWidth - 2): 0) .height ((options.selectionHeight - 2> 0)? (options.selectionHeight - 2): 0); ; 

Diese Funktion legt zunächst die Eigenschaften der Gliederungsebene fest: Cursor, Anzeige, Größe und Position. Als nächstes kommt die Auswahlschicht. Der neue Wert der Hintergrundposition lässt die Bilder nahtlos überlappen.

Jetzt benötigen wir eine Funktion, um den Cursor bei Bedarf zu aktualisieren. Wenn wir zum Beispiel eine Auswahl treffen, möchten wir, dass der Cursor a bleibt Fadenkreuz egal in welcher Schicht wir sind.

? // Aktualisiere den Cursor-Typ function updateCursor (CursorType) $ trigger.css (Cursor: CursorType); $ contour.css (Cursor: CursorType); $ selection.css (Cursor: CursorType); ; 

Ja, es ist so einfach wie es aussieht. Ändern Sie einfach den Cursortyp in den angegebenen!

Und jetzt die letzte Funktion dieses Schrittes; Wir benötigen es, um die Oberfläche des Plug-Ins in verschiedenen Situationen zu aktualisieren - beim Auswählen, beim Ändern der Größe, beim Freigeben der Auswahl und sogar bei der Initialisierung des Plug-Ins.

? // Aktualisieren Sie die Schnittstellenfunktion des Plug-Ins. UpdateInterface (Sender) switch (Sender) case 'setSelection': updateOverlayLayer (); updateSelection (); brechen; case 'resizeSelection': updateSelection (); updateCursor ("Fadenkreuz"); brechen; default: updateTriggerLayer (); updateOverlayLayer (); updateSelection (); ; 

Wie Sie sehen können, die updateInterface () Die Funktion filtert einige Fälle und ruft die erforderlichen Funktionen auf, die wir gerade geschrieben haben.


Schritt 7. Einstellen der Auswahl

Bisher haben wir uns um die Anpassungsoptionen und die Benutzeroberfläche gekümmert, aber nichts mit der Interaktion des Benutzers mit dem Plug-In zu tun. Schreiben wir eine Funktion, die eine neue Auswahl einstellt, wenn auf das Bild geklickt wird.

? // Neue Auswahlfunktion setzen setSelection (event) // Verhindert die Standardaktion des Ereignisses event.preventDefault (); // Verhindern, dass das Ereignis benachrichtigt wird event.stopPropagation (); // Einen Event-Handler an die Ereignisse 'mousemove' und 'mouseup' binden $ (document) .mousemove (resizeSelection) .mouseup (releaseSelection); // Benachrichtigen, dass eine Auswahl vorhanden ist selectionExists = true; // Die Auswahlgröße zurücksetzen options.selectionWidth = 0; options.selectionHeight = 0; // Hole den Auswahlursprung selectionOrigin = getMousePosition (event); // und seine Position options setzen.selectionPosition [0] = selectionOrigin [0]; options.selectionPosition [1] = selectionOrigin [1]; // Aktualisieren Sie nur die erforderlichen Elemente der Plug-In-Schnittstelle //, indem Sie den Absender des aktuellen Aufrufs angeben. UpdateInterface ('setSelection'); ; 

Zuerst die setSelection Funktion ruft zwei Methoden auf: event.preventDefault () und event.stopPropagation (). Dadurch wird verhindert, dass die Standardaktion und alle übergeordneten Handler über das Ereignis benachrichtigt werden. Das .mousemove () Methode bindet einen Event-Handler an die mousemove Veranstaltung. Das wird das anrufen resizeSelection () Funktion jedes Mal, wenn der Benutzer den Mauszeiger bewegt. Um zu benachrichtigen, dass eine neue Auswahl getroffen wird, wird die selectionExists Variable wird gemacht wahr Die Auswahlgröße wird auf 0 gesetzt. Als Nächstes erhalten wir den Auswahlursprung durch Aufrufen unserer zuvor geschriebenen Funktion, getMousePosition (), und übergeben Sie den Wert an die options.selectionPosition. Zum Schluss nennen wir das updateInterface () Funktion zum Aktualisieren der Schnittstelle des Plug-Ins gemäß den vorgenommenen Änderungen.


Schritt 8. Anpassen der Auswahl

Im vorherigen Schritt haben wir eine Funktion zum Einstellen einer neuen Auswahl geschrieben. Lassen Sie uns nun eine Funktion zum Ändern der Größe dieser Auswahl schreiben.

? // Größe der aktuellen Auswahlfunktion ändern resizeSelection (event) // Die Standardaktion des Ereignisses verhindern event.preventDefault (); // Verhindern, dass das Ereignis benachrichtigt wird event.stopPropagation (); var mousePosition = getMousePosition (Ereignis); // Ermittle die Auswahlgröße options.selectionWidth = mousePosition [0] - selectionOrigin [0]; options.selectionHeight = mousePosition [1] - selectionOrigin [1]; if (options.selectionWidth < 0)  options.selectionWidth = Math.abs(options.selectionWidth); options.selectionPosition[0] = selectionOrigin[0] - options.selectionWidth;  else options.selectionPosition[0] = selectionOrigin[0]; if (options.selectionHeight < 0)  options.selectionHeight = Math.abs(options.selectionHeight); options.selectionPosition[1] = selectionOrigin[1] - options.selectionHeight;  else options.selectionPosition[1] = selectionOrigin[1]; // Update only the needed elements of the plug-in interface // by specifying the sender of the current call updateInterface('resizeSelection'); ; 

Um die Auswahl zu ändern, müssen Sie die aktuelle Mausposition abrufen. Da der zurückgegebene Wert relativ zur Bildgröße ist, müssen wir uns nur um die negativen Werte kümmern. Es wird niemals die Bildgrenzen überschreiten. Wie Sie wissen, können wir keinen negativen Wert für den Wert haben Breite oder Höhe Eigenschaften eines Elements. Um das zu lösen, rufen wir an Math.abs () Um den absoluten Wert zu erhalten, positionieren wir die Auswahl neu.


Schritt 9. Die Auswahl freigeben

Und jetzt die letzte Funktion:

? // Die aktuelle Auswahlfunktion freigeben. ReleaseSelection (event) // Verhindert die Standardaktion des Ereignisses event.preventDefault (); // Verhindern, dass das Ereignis benachrichtigt wird event.stopPropagation (); // Entbinden Sie den Event-Handler vom 'mousemove' -Ereignis. $ (Document) .unbind ('mousemove'); // Entbindung des Event-Handlers vom 'mouseup' event $ (document) .unbind ('mouseup'); // Aktualisieren Sie den Auswahlursprung selectionOrigin [0] = options.selectionPosition [0]; selectionOrigin [1] = options.selectionPosition [1]; // Überprüfen Sie, ob die Auswahlgröße größer als das akzeptierte Minimum ist //, und legen Sie die Existenz der Auswahl entsprechend fest. If (options.selectionWidth> options.minSelect [0] && options.selectionHeight> options.minSelect [1]) selectionExists = true; else selectionExists = false; // Aktualisieren Sie nur die erforderlichen Elemente der Plug-In-Schnittstelle //, indem Sie den Absender des aktuellen Aufrufs angeben. UpdateInterface ('releaseSelection'); ; 

Wenn die Auswahl freigegeben wird, wird die releaseSelection () Funktion entfernt die zuvor angefügten Ereignishandler in der setSelection () Funktion durch Aufruf der .lösen() Methode. Als Nächstes wird der Auswahlursprung aktualisiert und die Mindestgröße geprüft, damit die Auswahl vorhanden ist.

Nun sind wir fast fertig. Schließen Sie diese Datei und bereiten Sie sich auf den nächsten Schritt vor.


Schritt 10. Gestalten des Plug-Ins

Öffne das /resources/js/imageCrop/jquery.imagecrop.css Stylesheet und fügen Sie die folgenden Zeilen hinzu.

 div # image-crop-overlay Hintergrundfarbe: #ffffff; Überlauf versteckt;  div # image-crop-outline background: #ffffff-url ('outline.gif'); Überlauf versteckt; 

Hier ist nichts kompliziert. Wir haben den Overlay- und Gliederungsebenen Stil hinzugefügt.


Schritt 11. Testen des Endergebnisses

Um unser Plug-in zu testen, müssen wir es an ein Bild anhängen. Lass uns das machen und das bearbeiten index.html Seite.

Öffne das Skript Etikett?

  

? und schreiben Sie den folgenden JavaScript-Code.

 $ (document) .ready (function () $ ('img # example'). imageCrop (overlayOpacity: 0,25);); 

Wir haben unser Plug-In mit dem Image-Element verbunden Beispiel id, und legen Sie einige benutzerdefinierte Optionen fest. Wir haben das benutzt .bereit() Methode, um zu bestimmen, wann das DOM vollständig geladen ist.

Und das ist es! Speichern Sie die Datei und öffnen Sie Ihren Browser, um sie zu testen.


Was kommt als nächstes

Jetzt haben wir ein einfaches jQuery-Plug-In zum Beschneiden von Bildern, mit dem wir einen Bildbereich auswählen können. Im nächsten Lernprogramm werden wir weitere Anpassungsoptionen hinzufügen, ein Vorschaufenster erstellen und serverseitige Skripts schreiben, um das Bild zuzuschneiden. und vieles mehr. Ich hoffe, Ihnen hat die Zeit, die wir zusammen verbracht haben, gefallen, und dieses Tutorial hat sich als nützlich erwiesen. Danke fürs Lesen!