Cara membuat jQuery Plugin Cropping gambar dari awal - bagian I
Indonesian (Bahasa Indonesia) translation by Yudha Zubair (you can also view the original English article)
Aplikasi web perlu menyediakan easy-to-use solusi untuk meng-upload dan memanipulasi konten yang kaya. Proses ini dapat membuat kesulitan untuk beberapa pengguna yang memiliki minimal foto editing keterampilan. Cropping adalah salah satu teknik manipulasi foto yang paling banyak digunakan, dan tutorial langkah demi langkah ini akan mencakup proses pembangunan seluruh gambar cropping plug-in untuk perpustakaan JavaScript jQuery.
Langkah 1. Menyiapkan ruang kerja
Pertama, kita akan mengatur ruang kerja proyek kami untuk tutorial ini. Memulai dengan menciptakan hirarki direktori dan file kosong bernama sebagai dicontohkan dalam gambar di bawah ini:

Selanjutnya, Anda akan perlu untuk men-download jQuery JavaScript library dan menempatkannya dalam folder /resources/js
. Gambar yang digunakan dalam tutorial ini harus bernama example.jpg
dan ditempatkan di dalam folder /resources/images/.
Anda dapat menggunakan gambar ini (Terima kasih kepada gsso-stock), diberikan dengan source file tutorial ini, atau salah satu dari Anda sendiri. Dan file yang terakhir adalah file outline.gif
, yang harus ditempatkan di dalam /resources/js/imageCrop/
folder.
Langkah 2. Membuat halaman pengujian
Untuk menguji plug-in, kita harus pasangkan ke gambar. Sebelum mulai bekerja di itu, kita akan menciptakan containg halaman sederhana gambar.
HTML
Buka file index.html
pada editor teks favorit Anda dan tuliskan kode berikut.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"> <head> <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" /> <title>jQuery Image Cropping Plug-In</title> <link href="style.css" media="screen" rel="stylesheet" type="text/css" /> <link href="resources/js/imageCrop/jquery.imagecrop.css" media="screen" rel="stylesheet" type="text/css" /> <script src="resources/js/jquery-1.6.2.min.js" type="text/javascript"></script> <script src="resources/js/imageCrop/jquery.imagecrop.js" type="text/javascript"></script> </head> <body> <div id="wrapper"> <h1>jQuery Image Cropping Plug-In</h1> <div class="image-decorator"> <img alt="jQuery Image Cropping Plug-In" height="360" id="example" src="resources/images/example.jpg" width="480" /> </div><!-- .image-decorator --> </div><!-- #wrapper --> </body> </html>
Tidak ada yang mewah di sini: sekadar kode HTML. Kami memiliki stylesheet yang dimuat untuk halaman, jQuery, kami plug-in file (yang saat ini kosong) dan menempatkan gambar dalam dokumen.
CSS
Sekarang edit style.css seperti ditunjukkan di atas.
* { margin : 0; outline : 0; padding : 0; } body { background-color : #ededed; color : #646464; font-family : 'Verdana', 'Geneva', sans-serif; font-size : 12px; text-shadow : 0 1px 0 #ffffff; } h1 { font-size : 24px; font-weight : normal; margin : 0 0 10px 0; } div#wrapper { margin : 25px 25px 25px 25px; } div.image-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; background-color : #ffffff; border : 1px solid #c8c8c8; border-radius : 5px 5px 5px 5px; box-shadow : 0 0 6px #c8c8c8; display : inline-block; height : 360px; padding : 5px 5px 5px 5px; width : 480px; }
Kami telah menyesuaikan aspek halaman kami dengan mengubah warna latar belakang dan menambahkan beberapa style dasar untuk judul dan gambar.
Langkah 3. Menulis basic jQuery Plug-In
Mari kita mulai dengan membuat plug-in jQuery basic.
"Pelajari lebih lanjut tentang cara menulis sendiri plug-in, melalui posting ini. Ini menguraikan dasar-dasar, praktek terbaik dan common pitfalls harus diperhatikan ketika Anda mulai menulis plug-in."
Buka /resources/js/imageCrop/jquery.imagecrop.js
dan tambahkan kode berikut.
// Always wrap a plug-in in '(function($) { // Plug-in goes here }) (jQuery);' (function($) { $.imageCrop = function(object, customOptions) {}; $.fn.imageCrop = function(customOptions) { //Iterate over each object this.each(function() { var currentObject = this, image = new Image(); // And attach imageCrop when the object is loaded image.onload = function() { $.imageCrop(currentObject, customOptions); }; // Reset the src because cached images don't fire load sometimes image.src = currentObject.src; }); // Unless the plug-in is returning an intrinsic value, always have the // function return the 'this' keyword to maintain chainability return this; }; }) (jQuery);
Kami telah hanya diperpanjang jQuery dengan menambah properti fungsi baru jQuery.fn
objek. Sekarang kita memiliki yang sangat dasar plug-in yang iterates atas setiap objek dan menempel imageCrop
ketika objek dimuat. Perhatikan bahwa cache gambar tidak menjalankan load
kadang-kadang, jadi kami reset src
atribut untuk memperbaiki masalah ini.
Langkah 4. Menambahkan pilihan disesuaikan
Memungkinkan untuk kustomisasi pilihan membuat plug-in jauh lebih fleksibel bagi pengguna.
$.imageCrop = function(object, customOptions) { // Rather than requiring a lengthy amount of arguments, pass the // plug-in options in an object literal that can be extended over // the plug-in's defaults var defaultOptions = { allowMove : true, allowResize : true, allowSelect : true, minSelect : [0, 0], outlineOpacity : 0.5, overlayOpacity : 0.5, selectionPosition : [0, 0], selectionWidth : 0, selectionHeight : 0 }; // Set options to default var options = defaultOptions; // And merge them with the custom options setOptions(customOptions); };
Kami memiliki sebuah array dengan pilihan default ditetapkan, kemudian bergabung dengan pilihan kustom dengan memanggil fungsi setOptions
. Mari kita pergi lebih jauh dan menulis body fungsi ini.
... // Merge current options with the custom option function setOptions(customOptions) { options = $.extend(options, customOptions); };
Fungsi $.extend()
menyatu isi dari dua atau lebih objek bersama-sama ke dalam obyek yang pertama.
Pilihan
Daftar berikut ini menjelaskan setiap opsi plug-in.
- allowMove - menentukan jika pilihan dapat dipindahkan (nilai default
true
). - allowResize - menentukan jika pilihan dapat diubah ukurannya (nilai default
true
). - allowSelect - menunjukkan jika pengguna dapat membuat pilihan baru (nilai default
true
). - minSelect - ukuran luasan minimal untuk mendaftarkan pilihan baru (nilai default adalah [
0, 0
]). - outlineOpacity - opacity garis besar (nilai default adalah
0,5
). - overlayOpacity - overlay opacity (nilai default adalah
0,5
). - selectionPosition - posisi pilihan (nilai default adalah [
0, 0
]). - selectionWidth - lebar pilihan (nilai default adalah
0
). - selectionHeight - seleksi tinggi (nilai default adalah
0
).
Langkah 5. Menyiapkan layer
Pada langkah ini, kita akan memodifikasi DOM untuk mendapatkan siap untuk langkah berikutnya: interface plug-di itu.



Pertama, kita akan menginisialisasi layer gambar.
... // Initialize the image layer var $image = $(object);
Sekarang menginisialisasi holder gambar.
... // Initialize an image holder var $holder = $('<div />') .css({ position : 'relative' }) .width($image.width()) .height($image.height()); // Wrap the holder around the image $image.wrap($holder) .css({ position : 'absolute' });
Seperti yang Anda lihat, layer pemegang memiliki ukuran yang sama sebagai gambar dan posisi yang relatif. Selanjutnya, kita memanggil fungsi .wrap()
untuk menempatkan gambar di dalam pemegang.
Di atas gambar akan menjadi lapisan overlay.
... // Initialize an overlay layer and place it above the image var $overlay = $('<div id="image-crop-overlay" />') .css({ opacity : options.overlayOpacity, position : 'absolute' }) .width($image.width()) .height($image.height()) .insertAfter($image);
Lapisan ini adalah ukuran yang sama sebagai gambar, tetapi juga telah diberikan posisi absolute. Kami mendapatkan nilai untuk opacity dari options.overlayOpacity
dan membiarkan jQuery menerapkannya. Elemen ini juga memiliki sebuah id, sehingga kami bisa merubah properti melalui plug-in yang stylesheet. Di bagian bawah, kita memanggil metode .insertAfter()
untuk menempatkan layer overlay tepat setelah gambar.
Lapisan berikutnya adalah layer memicu; kami akan menempatkan setelah layer overlay, seperti yang kita lakukan dengan yang sebelumnya.
... // Initialize a trigger layer and place it above the overlay layer var $trigger = $('<div />') .css({ backgroundColor : '#000000', opacity : 0, position : 'absolute' }) .width($image.width()) .height($image.height()) .insertAfter($overlay);
Warna latar belakang tidak benar-benar peduli tapi itu harus berbeda dari transparan (yang adalah secara default). layer ini tidak terlihat dari pengguna tetapi ini akan menangani beberapa event.
Kami akan menempatkan layer outline di atas layer trigger.
... // Initialize an outline layer and place it above the trigger layer var $outline = $('<div id="image-crop-outline" />') .css({ opacity : options.outlineOpacity, position : 'absolute' }) .insertAfter($trigger);
Dan akhirnya layer terakhir.
... // Initialize a selection layer and place it above the outline layer var $selection = $('<div />') .css({ background : 'url(' + $image.attr('src') + ') no-repeat', position : 'absolute' }) .insertAfter($outline);
.Attr() metode mengembalikan nilai atribut yang ditetapkan. Kami menggunakannya untuk mendapatkan gambar src, dan mengaturnya sebagai latar belakang untuk lapisan seleksi.
Absolute Positioning dalam posisi relatif
Anda mungkin sudah tahu ini, tetapi sebuah elemen dengan posisi relatif menyediakan Anda dengan kontrol untuk benar-benar posisi elemen itu. Inilah sebabnya mengapa layer holder memiliki posisi yang relatif dan semua child yang posisi absolute.
Penjelasan yang sangat baik trik ini tercakup dalam artikel ini.
Langkah 6. Memperbarui antarmuka
Pertama, kita akan menginisialisasi beberapa variabel.
... // Initialize global variables var selectionExists, selectionOffset = [0, 0], selectionOrigin = [0, 0];
selectionExists
akan menginformasikan kepada kami jika ada pilihan. selectionOffset
akan berisi offset relatif terhadap gambar asal, dan selectionOrigin
akan menunjukkan asal-usul selekasi. Hal ini akan lebih jelas setelah beberapa langkah.
Kondisi berikut ini diperlukan jika ada seleksi ketika plug-in load.
... // Verify if the selection size is bigger than the minimum accepted // and set the selection existence accordingly if (options.selectionWidth > options.minSelect[0] && options.selectionHeight > options.minSelect[1]) selectionExists = true; else selectionExists = false;
Selanjutnya kami akan memanggil fungsi updateInterface()
untuk pertama kalinya untuk menginisialisasi antarmuka.
... // Call the 'updateInterface' function for the first time to // initialize the plug-in interface updateInterface();
Kami akan menulis body fungsi ini segera. Sekarang, mari kita mengurus event pertama kami.
... if (options.allowSelect) // Bind an event handler to the 'mousedown' event of the trigger layer $trigger.mousedown(setSelection);
Kita memanggil .mousedown()
jika options.allowSelect
adalah true
. Ini akan mengikat sebuah event handler acara mousedown
layer trigger. Jadi, jika pengguna mengklik gambar, setSelection()
akan dipanggil.
... // Get the current offset of an element function getElementOffset(object) { var offset = $(object).offset(); return [offset.left, offset.top]; }; // Get the current mouse position relative to the image position function 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]; };
Fungsi pertama, getElementOffset()
, mengembalikan kiri dan atas koordinat objek tertentu relatif terhadap dokumen. Kita telah diperoleh nilai ini dengan memanggil metode .offset().
fungsi Kedua, getMousePosition()
, mengembalikan mouse saat ini posisi, tetapi relatif ke posisi gambar. Jadi, kami akan bekerja dengan nilai-nilai yang hanya antara 0 dan gambar lebar/tinggi di x/y-sumbu, masing-masing.
Mari kita menulis fungsi untuk memperbarui layer kami.
... // Update the overlay layer function updateOverlayLayer() { $overlay.css({ display : selectionExists ? 'block' : 'none' }); };
Fungsi ini memeriksa nilai dari variabel selectionExists
, dan menentukan jika layer overlay harus ditampilkan atau tidak.
... // Update the trigger layer function updateTriggerLayer() { $trigger.css({ cursor : options.allowSelect ? 'crosshair' : 'default' }); };
Fungsi updateTriggerLayer()
perubahan kursor crosshair
atau default
, tergantung pada nilai options.allowSelect
.
Selanjutnya, kita akan menulis fungsi updateSelection()
. Ini akan memperbarui tidak hanya layer seleksi, tetapi layer outline juga.
... // Update the selection function updateSelection() { // Update the outline layer $outline.css({ cursor : 'default', display : selectionExists ? 'block' : 'none', left : options.selectionPosition[0], top : options.selectionPosition[1] }) .width(options.selectionWidth) .height(options.selectionHeight); // Update the selection layer $selection.css({ backgroundPosition : ( - options.selectionPosition[0] - 1) + 'px ' + ( - options.selectionPosition[1] - 1) + 'px', cursor : options.allowMove ? 'move' : 'default', display : selectionExists ? 'block' : 'none', left : options.selectionPosition[0] + 1, top : options.selectionPosition[1] + 1 }) .width((options.selectionWidth - 2 > 0) ? (options.selectionWidth - 2) : 0) .height((options.selectionHeight - 2 > 0) ? (options.selectionHeight - 2) : 0); };
Pertama, fungsi ini menset properti layer outline: kursor, layar, ukuran dan posisi. Berikutnya datang layer seleksi; nilai baru dari posisi latar belakang akan membuat gambar yang tumpang tindih mulus.
Sekarang, kita membutuhkan fungsi untuk memperbarui kursor bila diperlukan. Sebagai contoh, ketika kita membuat pilihan, kami ingin kursor crosshair
pun layer yang kita adalah di atas tetap.
... // Update the cursor type function updateCursor(cursorType) { $trigger.css({ cursor : cursorType }); $outline.css({ cursor : cursorType }); $selection.css({ cursor : cursorType }); };
Ya, itu yang sederhana seperti kelihatannya. Hanya mengubah jenis kursor ke spesifik!
Dan sekarang, fungsi terakhir langkah ini; kita membutuhkannya untuk memperbarui plug-in yang antarmuka dalam situasi yang berbeda - pada memilih, pada Resize, melepaskan pemilihan, dan bahkan ketika menginisialisasi plug-in.
... // Update the plug-in's interface function updateInterface(sender) { switch (sender) { case 'setSelection' : updateOverlayLayer(); updateSelection(); break; case 'resizeSelection' : updateSelection(); updateCursor('crosshair'); break; default : updateTriggerLayer(); updateOverlayLayer(); updateSelection(); } };
Seperti yang Anda lihat, fungsi updateInterface()
filter beberapa kasus dan panggilan fungsi-fungsi penting yang kita baru saja tulis.
Langkah 7. Pengaturan pilihan
Sampai sekarang, kami merawat pilihan penyesuaian dan antarmuka, tetapi tidak berkaitan dengan bagaimana pengguna berinteraksi dengan plug-in. Mari kita menulis sebuah fungsi yang menetapkan pilihan baru ketika gambar diklik.
... // Set a new selection function setSelection(event) { // Prevent the default action of the event event.preventDefault(); // Prevent the event from being notified event.stopPropagation(); // Bind an event handler to the 'mousemove' and 'mouseup' events $(document).mousemove(resizeSelection).mouseup(releaseSelection); // Notify that a selection exists selectionExists = true; // Reset the selection size options.selectionWidth = 0; options.selectionHeight = 0; // Get the selection origin selectionOrigin = getMousePosition(event); // And set its position options.selectionPosition[0] = selectionOrigin[0]; options.selectionPosition[1] = selectionOrigin[1]; // Update only the needed elements of the plug-in interface // by specifying the sender of the current call updateInterface('setSelection'); };
Pertama, fungsi setSelection
memanggil dua metode: event.preventDefault()
dan event.stopPropagation().
Hal ini mencegah aksi default dan setiap orangtua penangan dari memberitahu event. Metode .mousemove()
mengikat sebuah event handler mousemove
event. Ini akan memanggil fungsi resizeSelection()
setiap kali pengguna menggerakkan mouse pointer. Untuk memberitahukan bahwa pilihan baru yang sedang dibuat, selectionExists
variabel yang dibuat true
dan ukuran pilihan diatur ke 0. Selanjutnya, kita mendapatkan asal pilihan dengan memanggil fungsi sebelumnya ditulis, getMousePosition(),
dan memasukan dengan nilai options.selectionPosition.
Akhirnya, kita memanggil fungsi updateInterface()
untuk memperbarui antarmuka plug-in yang dibuat.
Langkah 8. Resize pemilihan
Di langkah sebelumnya, kami menulis fungsi untuk menetapkan pilihan baru. Mari kita sekarang menulis fungsi untuk mengubah pilihan itu.
... // Resize the current selection function resizeSelection(event) { // Prevent the default action of the event event.preventDefault(); // Prevent the event from being notified event.stopPropagation(); var mousePosition = getMousePosition(event); // Get the selection size 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'); };
Untuk mengubah ukuran pilihan, kita perlu mengambil posisi mouse saat ini. Karena nilai yang dikembalikan adalah relatif terhadap ukuran gambar, kita perlu untuk mengurus hanya nilai negatif. Itu tidak akan melebihi batas-batas gambar. Seperti yang Anda tahu, kita tidak bisa memiliki nilai negatif untuk properti width
atau height
dari elemen. Untuk memecahkan masalah ini, kami memangiil Math.abs()
untuk mendapatkan nilai mutlak dan kemudian kita reposisi pemilihan.
Langkah 9. Melepaskan pemilihan
Dan sekarang fungsi akhir:
... // Release the current selection function releaseSelection(event) { // Prevent the default action of the event event.preventDefault(); // Prevent the event from being notified event.stopPropagation(); // Unbind the event handler to the 'mousemove' event $(document).unbind('mousemove'); // Unbind the event handler to the 'mouseup' event $(document).unbind('mouseup'); // Update the selection origin selectionOrigin[0] = options.selectionPosition[0]; selectionOrigin[1] = options.selectionPosition[1]; // Verify if the selection size is bigger than the minimum accepted // and set the selection existence accordingly if (options.selectionWidth > options.minSelect[0] && options.selectionHeight > options.minSelect[1]) selectionExists = true; else selectionExists = false; // Update only the needed elements of the plug-in interface // by specifying the sender of the current call updateInterface('releaseSelection'); };
Ketika pemilihan dilepaskan, releaseSelection()
fungsi menghapus sebelumnya terlampir event handlers fungsi setSelection()
dengan memanggil metode .unbind().
Selanjutnya, ini update asal seleksi dan tes ukuran minimum yang diterima untuk pemilihan untuk ada.
Sekarang, kami hampir siap. Tutup file ini dan mempersiapkan langkah berikutnya.
Langkah 10. Styling Plug-In
Buka /resources/js/imageCrop/jquery.imagecrop.css
stylesheet, dan tambahkan baris berikut.
div#image-crop-overlay { background-color : #ffffff; overflow : hidden; } div#image-crop-outline { background : #ffffff url('outline.gif'); overflow : hidden; }
Ada ada yang rumit di sini; kami telah menambahkan beberapa styling layer overlay dan outline.
Langkah 11. Pengujian hasil akhir
Untuk menguji kami plug-in, kita perlu pasangkan ke gambar. Mari kita melakukan itu dan mengedit halaman index.html.
Buka script
tag...
<script type="text/javascript"> ... </script>
... dan menulis kode JavaScript yang berikut.
$(document).ready(function() { $('img#example').imageCrop({ overlayOpacity : 0.25 }); });
Kami sudah terpasang kami plug-in gambar elemen dengan id example
, dan mengatur beberapa opsi yang kustom. Kami menggunakan metode .ready()
untuk menentukan ketika DOM sudah terisi penuh.



Dan hanya itu! Simpan file dan membuka browser Anda untuk menguji itu.
Selanjutnya
Sekarang kita memiliki gambaran dasar cropping jQuery plug-in yang memungkinkan kita untuk Pilih area gambar. Dalam tutorial berikutnya, kami akan menambahkan lebih banyak pilihan penyesuaian, membangun jendela pratinjau, menulis beberapa server-side scripting cropping gambar... dan banyak lagi. Saya harap Anda telah menikmati waktu kita telah menghabiskan waktu bersama dan menemukan tutorial ini berguna. Terima kasih sudah membaca!