Tutorial Teks SVG: Anotasi Teks di Web

Diterbitkan: 2022-03-11

Dengan HTML5 dan CSS3, browser web memperoleh sejumlah teknologi luar biasa: grafik 3D, soket, utas, dan banyak lagi. Dengan ini, aplikasi web dapat memanfaatkan beberapa kemampuan paling canggih dari komputer dan sistem operasi yang digunakannya. Peramban web menawarkan ekosistem serbaguna yang kuat untuk pengembangan aplikasi, yang terbukti dari kebangkitan baru-baru ini banyak aplikasi web canggih yang kita tidak bisa hidup tanpanya. Namun, sesuatu yang masih kurang adalah keindahan anotasi dan dekorasi teks HTML. Apa itu dekorasi teks? Garis bawah berlekuk-lekuk, sorotan kasar, dan coretan bergelombang adalah beberapa hal yang tidak didukung oleh browser web. Ini mungkin terdengar lebih rumit daripada berguna, tetapi kemampuan Pengembang JavaScript untuk menghasilkan gaya ini mungkin terbukti berguna dalam aspek-aspek seperti sumber daya e-learning dan pembaca ebook berbasis web. Selain itu, ini dapat berkontribusi pada peningkatan pengalaman pengguna dalam aplikasi web yang berkisar pada prinsip-prinsip desain alami. Paling tidak, membangun alat seperti itu menyenangkan dan memberikan wawasan tentang banyak kebiasaan browser web.

Tutorial Teks SVG - anotasi teks

Pengembang telah menemukan banyak solusi untuk batasan browser web. Banyak dari solusi ini melibatkan penggunaan CSS dengan cara yang kurang intuitif, karena beberapa menggunakan gambar dalam elemen semu "::after". Ini berhasil, tetapi mempertahankan banyak gambar untuk setiap pasangan gaya-warna sering kali terbukti sulit. Artikel ini membahas anatomi library JavaScript yang mencoba menyelesaikan masalah ini dengan elegan.

Pustaka adalah open source, dan tersedia di GitHub: Text Annotator

Ringkasan

Saat mengembangkan perpustakaan ini, perhatian khusus diberikan untuk memastikan kompatibilitas dengan browser web paling populer (termasuk IE 9+). Namun, tidak seperti kebanyakan cara mengatasi masalah ini, perpustakaan tidak bergantung pada trik CSS yang tidak jelas; atau lebih buruk, simbol Unicode khusus. Alih-alih menggunakan SVG untuk mencapai dekorasi teks yang jauh lebih baik dan lebih bersih.

Pada dasarnya, perpustakaan mengimplementasikan "kelas" Annotator yang dapat digunakan untuk membuat elemen DIV secara otomatis, menempatkannya di bawah teks yang akan dianotasi, dan mengisi latar belakangnya dengan gambar SVG. Beberapa DIV dapat digabungkan untuk menyesuaikan dekorasi lebih lanjut. Pendekatan ini kompatibel lintas-browser, memberikan fleksibilitas atas pemosisian elemen dekoratif, dan memungkinkan ekstensi yang lebih mudah dengan templat khusus.

Pustaka telah dikembangkan menggunakan Google Closure Tools karena bersifat modular dan lintas-browser, yang membantu menghasilkan kode JavaScript yang ringkas dan cepat tanpa ketergantungan tambahan.

Arsitektur

Pustaka telah dirancang sebagai kumpulan "kelas" JavaScript, dan memaparkan semua fungsi yang diperlukan kepada pengguna melalui "kelas" Annotator:

perpustakaan teks annotator

Berikut adalah garis besar fungsi yang tersedia:

  • annotateDocument - elemen anotasi, yang ditandai dengan atribut "data-annotate".

  • menggarisbawahi - menggarisbawahi elemen

  • sorot - elemen sorotan

  • pemogokan - elemen pemogokan

  • underlineSelected - menggarisbawahi teks yang dipilih

  • highlightSelected - menyorot teks yang dipilih

  • strikeSelected - menyerang teks yang dipilih

  • unnotateElement - menghapus anotasi dari elemen

  • getTemplates - mengembalikan kamus templat anotasi

  • setUnderlineOptions - mengatur pengaturan untuk annotator garis bawah

  • setHighlightOptions - mengatur pengaturan untuk annotator sorotan

  • setStrikeOptions - mengatur pengaturan untuk pemogokan annotator

Kelas annotator memiliki tiga contoh kelas AnnotatorImpl untuk setiap fungsi anotasi: garis bawah, sorot, dan coret.

 tvs.Annotator = function() { this.underliner_ = new tvs.AnnotatorImpl( 'underliner', tvs.Annotator.getTemplates(), tvs.AnnotatorCore.underlinePositioner); this.highlighter_ = new tvs.AnnotatorImpl( 'highlighter', tvs.Annotator.getTemplates(), tvs.AnnotatorCore.highlightPositioner, {opacity: 0.45}); this.striker_ = new tvs.AnnotatorImpl( 'striker', tvs.Annotator.getTemplates(), tvs.AnnotatorCore.strikePositioner); };

Instance AnnotatorImpl dibuat dengan ID dan objek pembantu positioner yang berbeda. ID yang diteruskan digunakan nanti dalam nama kelas CSS dan nama bidang internal, yang membutuhkan ID untuk menjadi unik. Juga, referensi ke daftar templat yang diketahui akan diteruskan (dapat diubah nanti).

Setiap objek positioner adalah implementasi dari antarmuka IPositioner yang hanya memiliki metode “getPosition” dan terlihat sebagai berikut:

 /** * Underline positioner * @implements {tvs.IPositioner} */ tvs.AnnotatorCore.underlinePositioner = /** @type {!tvs.IPositioner} */ ({ /** * @param {Object} elementRect * @param {number} annotationHeight * @return {{left: number, top: number, width: number, height: number}} */ getPosition: function(elementRect, annotationHeight) { return { width: elementRect.width, height: annotationHeight, left: elementRect.left, top: elementRect.bottom - (elementRect.height * 0.1) }; } });

Ini memungkinkan setiap template untuk digunakan dengan anotasi teks garis bawah, sorot, atau coret. Saat anotasi diterapkan ke elemen, kotak pembatas untuk elemen diperoleh dengan memanggil "getElementRects" seperti yang ditunjukkan di bawah ini:

 var rects = elemOrEv.getClientRects();

Metode ini mengembalikan koleksi persegi panjang yang menunjukkan persegi panjang pembatas untuk setiap kotak di klien. Setelah melewati setiap rect ke posisi beton, kita akan mendapatkan batas tujuan.

Templat Anotasi Teks SVG

Seperti disebutkan sebelumnya, hanya ada satu set template yang digunakan untuk semua jenis anotasi teks SVG. Setiap template terdiri dari bagian-bagian template. Bagian template adalah entitas yang mewakili konten bagian, lebar template, dan mode gambar.

Isi

Konten adalah sekumpulan elemen SVG yang direpresentasikan sebagai string. Karena konten ini tidak memiliki simpul SVG root di mana lebar dan tinggi viewport (dalam piksel) ditetapkan, konstruktor bagian template menerimanya sebagai parameter. Misalnya, Anda dapat menentukan ukuran area pandang sebagai 100px x 100px dan menggambar garis ke (50, 50) dan (25, 25). Setelah anotasi diterapkan, semua elemen svg akan disesuaikan dengan ukuran yang diinginkan dengan benar. Nilai konten dapat menggunakan string “{0}” yang akan diganti dengan warna yang dipilih oleh pengguna.

SVG berikut membuat garis diagonal. Kami akan menggunakan ini sebagai salah satu bagian dalam contoh gaya anotasi berikut segera:

 <line x1="0" y1="0" x2="5" y2="5" stroke-width="2" stroke="red" />

Lebar

Lebar template adalah string yang dapat berupa “*”, “tinggi”, atau apa pun:

  • "*" mengatur lebar semua elemen dengan bintang yang sama satu sama lain

  • "height" mengatur lebar sama dengan tinggi elemen anotasi

Apa pun yang diatur di sini akan langsung disetel ke lebar CSS dan properti min-width.

properti CSS

Mode Menggambar

Mode draw adalah string yang dapat berupa "repeat" atau "stretch". Seperti yang ditunjukkan nilainya, menyetelnya ke "ulangi" akan mengulangi konten, sementara menyetelnya ke "meregangkan" akan meregangkan konten.

Berikut adalah contoh dari apa yang dapat kita capai dengan mengonfigurasi ketiga parameter ini:

anotasi teks

Anotasi teks pada contoh di atas terdiri dari 4 bagian. Bagian pertama adalah garis diagonal, dengan lebar templat diatur ke "tinggi" dan mode menggambar diatur ke "ulangi". Bagian kedua memiliki lebar templat yang disetel ke "*" dan mode menggambar disetel ke "ulangi". Bagian ketiga diatur menjadi lebar "15px" dan digambar dalam mode "ulangi". Akhirnya, lebar bagian terakhir diatur ke "*" dan mode menggambarnya diatur ke "peregangan".

Ketika lebar ini dievaluasi, bagian pertama membutuhkan 5 piksel (sama dengan tinggi elemen anotasi), bagian ketiga membutuhkan 15 piksel (sebagaimana diatur), dan ruang yang tersisa dibagi rata antara bagian kedua dan keempat.

Ketika bagian teks yang sama disorot menggunakan template yang sama, inilah yang kita dapatkan:

mode menggambar

Seperti yang Anda tahu, tinggi elemen anotasi lebih besar, dan begitu pula lebar bagian pertama (karena lebar templat untuk bagian itu disetel ke "tinggi"). Secara alami, lebar bagian ketiga tetap tidak berubah dari contoh sebelumnya.

Menerapkan efek coret ke teks yang sama dengan template yang sama menghasilkan hasil yang sangat mirip dengan yang pertama. Satu-satunya perbedaan adalah lokasi penempatan elemen anotasi:

mode menggambar anotasi teks

Meskipun anotasi teks ini tampak rumit (penampilannya, memiliki empat bagian berbeda), semuanya menggunakan elemen SVG yang sangat sederhana. Sebagai contoh tambahan, membuat garis berlekuk-lekuk membutuhkan satu bagian, dengan konten SVG sederhana berikut:

 var t = new tvs.Template(new tvs.SvgTemplatePart( '<line y2="16.00" x2="20" y1="4.00" ' + 'x1="10" stroke-linecap="round" ' + 'stroke-width="5" stroke="{0}" fill="none"/>' + '<line y2="4.00" x2="10" y1="16.00" ' + 'x1="0" stroke-linecap="round" ' + 'stroke-width="5" stroke="{0}" fill="none"/>', 20, 20, 'repeat' ))

Saat template ini dievaluasi, konten diubah ukurannya dan "{0}" diganti dengan warna yang ditentukan secara otomatis. Terlebih lagi, menambahkan template baru semudah menambahkannya ke objek JavaScript:

 tvs.AnnotatorDictionary.svgTemplates['brush'] = new tvs.Template(new tvs.SvgTemplatePart( svgContent, 50, 50, '*', 'stretch' ));

Hasil

Setiap anotasi diterapkan dengan menambahkan elemen div dengan posisi absolut ke halaman:

 <div class="tvs-annotate-element"> <div class="tvs-wrap-div"> <table> <tr> <td></td> <td></td> <td></td> </tr> </table> </div> </div>

Elemen div diisi dengan tabel di mana setiap sel yang ditambahkan sesuai dengan salah satu bagian dalam template. Konten setiap bagian templat ditambahkan sebagai URI data yang disandikan Base64, dengan warna yang dipilih diterapkan:

 tvs.SvgTemplatePart.prototype.getBackground = function(color) { var image = tvs.AnnotatorCore.formatString(this.content, [color]); var encodedSVG = goog.crypt.base64.encodeString(image); return 'data:image/svg+xml;base64,' + encodedSVG; };

Menanamkan

Untuk pengalaman pengguna yang lebih baik, terutama ketika mencoba menggunakan pustaka JavaScript ini dengan area konten yang dapat diedit, penting bagi Annotator Teks untuk mengetahui batas teks yang saat ini dipilih oleh pengguna. Rangy, pustaka JavaScript rapi yang menangani rentang dan pemilihan, telah digunakan untuk mencapai ini dengan cara lintas-browser. Rangy menyediakan API berbasis standar sederhana untuk melakukan tugas Rentang dan Pemilihan DOM umum di semua browser utama, mengabstraksikan implementasi yang sangat berbeda dari fungsi ini antara Internet Explorer hingga browser yang sesuai dengan DOM. Ini adalah satu-satunya ketergantungan proyek.

Setelah Text Annotator disematkan, menggunakannya adalah hal yang sangat sederhana:

 var annotator = new tvs.Annotator(); annotator.underlineSelected();

Setiap elemen beranotasi ditandai dengan kelas “tvs-annotated-text” dan setiap elemen anotasi memiliki kelas “tvs-annotate-element”. Menghapus anotasi bahkan lebih sederhana, satu baris:

 annotator.unannotateElement(annotatedElement);

keanehan

Saat jendela diubah ukurannya, elemen dapat bergerak, membutuhkan elemen beranotasi untuk "disegarkan". Ini ditangani oleh perpustakaan. Namun; untuk mengurangi dampak pada kinerja, panggilan untuk menyegarkan anotasi dibatasi:

 tvs.AnnotatorImpl = function(id, templates, positioner, options) { // ... this.throttle = new goog.Throttle(goog.bind(this.refreshAllAnnotations, this), 50); tvs.AnnotatorCore.registerForWindowResize( this.id,goog.bind(this.throttle.fire, this.throttle)); }; tvs.AnnotatorImpl.prototype.refreshAllAnnotations = function() { var elems = goog.dom.getElementsByClass(this.getCssClassForAnnotated()); var refFunc = goog.bind(this.refreshAnnotation, this); goog.array.forEach(elems, refFunc); };

Saat menyegarkan, elemen anotasi dapat ditambahkan, diubah ukurannya, atau dihapus dari halaman sesuai kebutuhan.

Kenyamanan

Untuk mempermudah membuat anotasi teks statis pada halaman, Anda hanya perlu atribut data sederhana pada elemen penampung:

 data-annotate='underline squiggly green'

Ini akan membubuhi keterangan konten elemen dengan garis bawah hijau berlekuk-lekuk.

Kesimpulan

Apa lagi yang bisa saya katakan tentang tutorial teks SVG ini? Alat yang menyenangkan namun kuat telah diimplementasikan dengan mudah. Saya tidak berpikir kami akan mendapat banyak manfaat dengan memastikan dukungan untuk Internet Explorer 8, karena kami malah dapat memperumit seluruh implementasi. Namun, dengan beberapa perbaikan dan sedikit kerja pada intinya, kami dapat memperluas perpustakaan untuk dapat menghasilkan batas dekoratif untuk elemen non-tekstual. Selain itu, mungkin merupakan tugas yang menarik untuk menerapkan beberapa mekanisme untuk menyimpan dan kemudian memulihkan status konten yang dapat diedit dari anotasi.

Untuk saat ini, kemungkinan hanya dibatasi oleh imajinasi Anda (dan kemampuan browser). Mungkin Anda ingin garis microprint, atau gradien, atau bahkan animasi. Dengan Text Annotator, Anda bisa.