 Привіт, мене звати Інгвар, я працюю як вебосемпті адвокат Google. Сьогодні я не буду говорити про історі вебосемпті чи вдаватися титарі того, як він працює, про це вже і багато доповідей та статей. Ну, тому що я хочу сфокусуватися на чистопрактичній стороні і питання, яке мабуть найчастіше чує від розробників. Окей, мені цікаю вебосемпті, як мені спробити його на практиці. Як на мене основна перевага вебосемпті для вебосробників полягає у розширені екосистеми. Якщо потрібна вам бібліотека вже існує, але написана на інший мов відзначно від Мініві ЧС, то за допомогою вебосемпті ви можете її скомпірувати та використити у вебсередовищі з мінімальними старатами швидкості. Саме це я і хочу зробити сьогодні, провівши вас через процес портування від початку до кінця. Для цього прикладу я візьму в бібліотеку «Кля роботи з ображнями», написано на расті, і використую на звичайні вебсторінці. Я обрав раст, тому що це сучасно безпечна мова, яка не потребує річного керування пам'ятю, але при цьому інвестувала багато в генералі швидкого і маленького коду і закромав підтримку вебосемпті. Перший, що треба зробити, це ініціалювати проект. Я сферив поражню папку і викликаю «Карго інітліб». «Карго» – це як НПМ для расту. І він створює стантартний шаблон бібліотеки з кількома файлом. Далі нам буде потрібний «Васмбанджін». Оскільки різні мови мають різні системи і представлення типів, для комунікації між ними потрібний паршар, який буде конвертувати значення з одного представлення в інше. «Васмбанджін» слугує таким паршарком саме між «JS» і вебасем бібліотеки з кількома файлом. В нього доволі детальна документація, і як ви можете побачити, тут доволі багато різних прикладів. Від простого «Hello World» до складніших типов «RGL» і вебар «TC». Але оскільки я буду працювати з ображнями, то найближчий приклад для мене буде «Canvas Hello World». В ньому показано, як отримати доступ до «Canvas with Rust» коду і намалювати смайл. Для простоти я скопію звідси тип бібліотеки і список залежностей, і буду рухати вже від цього коду. Для прикладу я відразу знаю, що мені не потрібно буде нічого робити з «JS API», і мені не потрібен документ, елемент і бані для «Window». Тому я хочу приймати «Canvas» напряму як параметр. Тому я просто приберу ці залежності з конфігурації. Тепер я можу почати писати сам код. Для цього я видаю автосгенеровний код з шаблону і додам атрибути «Vasmbangin». Він позначає, що функція має бути експортована на «JS» з конвертацій типів. І тепер оголошу власне функцію звої просет-іміч, яка буде приймати «Canvas» як елемент, тобто стипом HTML-Canvas-element. Тепер нам потрібно збудувати код. Найпростіше спосіб це зробити – це взяти «Vasmapack», який був створене тієї ж команди «Vasmbangin» і об'єднує всі необхідні команди в одну – компіляцію WebAssembly, додаткова оптимізація і генерацію «JS». На цій сторінці ви можете знайти різні інсталіатори для різних систем, але ускільки в мене він жести її, то я за екропу пропущу. Натоміст, я можу відразу ввілкати «Vasmapack» пілд і вказати, що хочуть ціль «Web», не «Bandarin & Node.js» і він почне компіляцію. Тим часом я гляну ще раз на приклад «Canvas Hello World» і я можу пропустити, де він отримує сам «Canvas» і на там скупівати чисту частину, де він отримує 2D-контакт для обмалювання. Скупівують цю частину мої функції і далі отримаю ширину і висоту «Canvas» і також спережу їх у окремні змінні. У нас є пара половин милок компіляції. Закрома, мені треба імпортувати «Vasmapack» для того, щоб отримати, в принципі, працював і для другої помилки я просто прийму підказку від компілятора. Тепер помилок не маю, перекомпілюються якусь ще раз. Я бачу, що він синервував папку «Package», у який є «WebAssembly.js» і навіть типи для «TypeScript». Закрома, я можу бачити, що я бібліотека уже експортує звичайну «js» функцію, «Process Image», яка приймає «Canvas» як елемент. Тепер мені треба отримати зображення «Scanvas» на стороні «Rust». Для цього я можу використати «DomMethodCatImageTata», який дотворяє отримувати зображення у форматі «MassivoByte.rgba». Якщо зайти на «DocsArrest.web.js» це веб-сайт із захотерованої документації для всіх «Rust» бібліотек, то я можу пошукати «CatImageTata» і побачити, які типи оголошуються на стороні «Rust» для цього методу. Я бачу, що він приймає всі числа це числа сплаваючою точкою і потребує до такого фічу «ImageTata». Давайте я її скопіюю і додам у свій «CarboTomel». Тепер я можу викликати «GetImageTata» з нурями для «X» і «Y» і шириною вистою сконвертовані в F64. Це вертає мені результат з об'єктом «ImageTata» я його розгорну за допомогою «Unwrap» в сам «ImageTata». Перші прочитати мені з нього самі байти мені треба знову граєнти документацію і я бачу метод «Data», який гвертає. Викликаю його і далі бачу, що цей метод вартає байти у «Obhort»ці «Clamped» і щоб її розгорнути мені треба просто отримати листість під індексом 0. Все, тепер я маю байти у форматі «RageBae» Тепер я знову піду на «DocsRS» і гляну документацію для базової бібліотеки, для роботи зображніми у расті «Image». У ній є лізноманітні функції і формати для роботи зображніми, але зокрема, оскільки мене вже у «RageBae» отримане сканвасу, то я пошукаю «RageBae.Image» і можу знайти саме такий тип і бачу, що він не просто під типом «ImagePuffer». Тепер сам «ImagePuffer» містить лізноманітні функції ширини, висоти і масилу байти. Саме те, що мені треба. Я додам «Image» як залежність для свого коду і викличю цей метод і збережу результату зміну «Image». Продивімо ширину, висоту і власне байти. Далі дивіться ще раз на документацію бачу, що результат повернений як «Option», це аналог, або значення, або «UndefinedUGS» і його розгорну теж через «Unwrap» як все інше. Тут я поки залишу тоді документару, де можна щось робити зображенням і, натомість тим часом, гляну як його конвертувати назад. Я бачу, що є метод СРО, які дозволяють тримати внутрішній контейнер, тобто самі байти в оригінальному форматі. Я його викличу, отримую ці байти і збережу зміну на своїй ролі «ImageData». Тепер мені треба створити сам «ImageData». Я знову гляну на документацію на веб-сес, щоб зрозуміти, як його сконструювати назад. І я бачу з конструктора, з який отримує посилання на байти «Шерену висоту», який мені підходить. Так, викличу «ImageData» і зкупію назву цього конструктора, скільки вона доволі довга. І передам йому «Шерену», «Висоту» і самі байти. І оскільки він теж повертає результат, я знову викличу «Unwrap», щоб розгорнути тільки в успішній «ImageData». Нарешті, я можу глянути метод «PutImageData» і покласти уже новий сконструюваний «ImageData» назад на «Canvas». Бачу, він приймає посилання «ImageData» і «XY». Тобто я передам йому посилання на мою зміну. І «XY» задам по-нулях. Тепер я можу це все скомпілювати. Поки воно компілюється, я піду на «Unsplash» і вибору якусь картинку прикладу загорами, на які я можу протестувати цей код. Знайшов якусь скопію її адресу і створюю «Index.js» і «Index.jml» для самої веб-аплікухи. «Index.jml» буде включати «Index.js» як модуль і також має містити «Canvas» для власне відображення готового зображення. «Index.js» буде містити асенхронний код, тому я в ньому створюю відразу асенхронну функцію і також імпортую інсервізацію веб-асемблі із генерованого JS. Тепер в автокомліті я можу вибрати експортован функцію process-image. Тепер я можу викликати інсервізацію веб-асемблі функцію init і зачикати на її завершення через await і можу створити тимчасове зображення з URL-ом, який я скопію вавд і «Unsplash». Я його передам як source. І також я вкажу атрибут «Origin Anonymous» для того, що я міг завантажити зображення з іншого до мену. Тепер я знову використовую await і методи decode для того, щоб завантажити і декодувати зображення. Тепер я можу з нього отримати ширну і висоту і скопіювати їх на сам canvas. Так, мені треба тривати сам canvas. Для цього я використую кет-элемент-py.it. Тепер я можу отримати його 2D-context і власне відмалювати завантаження зображення. Інтрапердати. У зображенні IXY то просто по нулях. Тепер ви чимали, я додам кнопку для власне виклику обробки web-sendly. Називу її на приклад «Process with Wasp». Присводи якісь ID. І тепер в JS я можу отримати цю кнопку і присвоїти й on-click handler, який буде власне викликати «Process Image» для обробки за допомоги web-sendly. Тепер я можу запустити сервер спутований браузером. Я тут пропущу ці кроки і спробити поклікати цю кнопку. Наразі нічого не відбувається. Ніяких помолок JS, але ніяких змін до зображення візуально-таваж. Але це очіко. Все, що код наразі робить, це отримує зображення с канвасу, конвертує зображення на расті, конвертує його назад і знову зберігає на канвас. Давайте додамо посередні якісь ефекти. Для цього прийду назад до docs.rs і тут я бачу модуль ImageOps, який містить у різній операції для роботи з зображеннями. Тут є багато різних стандартних трансформацій. Для прикладу я можу зайти в операції по роботи з кольором і вибрати, наприклад, хьюратейт, який змінює тональність зображення. Зокрема можу використувати варіацію хьюратейтінплейс. Оскільки ми не хочемо спорігати і можемо просто змінювати ту яку ми маємо. Цей метод приймає поверотональність зображення формі кута на колі між 0,360 градусів. Я його викличу на своєму зображенні. Наприклад, з параметром 90 градусів. Тепер мені треба пофіксити пемок компілятора. Зміна має бути змінною, а не константею і може видалити тут документар. Тепер можемо перекомбілювати цей код і коли його новлю сторінку до цього разу кожен клік на кнопку влас змінює панель зображення кожен раз на 1,4 від півно 4 кліки вертає його до початку. Наразі ця реалізація не зовсім фективна, тому що вона читає зображення з канусу заново на кожен клік, кожен нат з кнопки. Навіть про тому, що у нас уже є свіжа модифікована копія зображення з минулого разу і ми знаємо, що вона відповідає стану на канусі. Я використую цю можливість, щоб продемонструвати як спортовати структури класи і зросту. Я знову використую все той же атрибут у вас і байнджен, але цього разу створює структуру і вона буде названа Image Processor. Тепер у ній мені треба заберегти всі зміні, які потрібні обробки зображень, зокрема контекст, на який вони будуть відмарювуватись, і власне уже сконвертоване зображення у форматі Algebra і Image. Тепер з тим вже атрибутом я можу дати блок із методами. Один із методів буде позначений за допомогою у вас байджен-конструктор. Він каже, що цей метод має бути спортований як JS-конструктор для класу. Створюю функціоню, яка буде приймати власне canvas і вертати цей Image Processor. В нього піде вся ця частина, яка ініціорізує, читає як початково зображення із canvas. В кінці я верну новостворний Image Processor і в ньому збережу контекст і власне уже сконвертоване зображення. В іншій метод буде займатися чисто зміною тональності зображення. Він буде назватися hereRotate оперувати на поселення зображення і у нього перенесу чисто виклик самого ефекту. Налешті, останна функція буде займатися відмалювуванням готового зображення назад на canvas. Я її назвую і draw і перенесу в неї все, що лишилось. Так я розбив одну функцію на декілька окремих кроків, від одного. Треба пофіксити пару помилок компіляції переважно просто отримуючи підказки від компілятора, приймаючи їх і тільки для шириний висоти я тепер їх можу отримати безпосередньо з конвертованого зображення від форматував код черного помилка. Тепер я можу перекомпілювати проект. Коли дивлюся на це неровні типи, я бачу, що тепер замість функції Process Image Image Processor експортованія клас і в ньому є методи, конструктор додаткова функція Free для керування пам'ятю на стороні WebAssembly. Я його імпортує завість оригінальної функції і тепер я його сконструюю від разу, як тільки зображення відволюване на Canvas. Продам йому сам Canvas. Обравни кнопки маєте перекликати тільки hr і 0.0 і вже не має читати зображення з Canvas ще разу. Мої їх просто викничу і тепер обновлю сторінку і тепер візуально нічого не змінилося тільки до того, але трохи ефективніше, оскільки зображення вже збираєшне і перевекористовується між викликами. Інший плюс у такої організації коду з те, що я можу відносно легко додавати будь-які інші ефекти. Наприклад, тут я пропущу деталі реалізації, але загалом по тому ж принципу я додав метод Grayscale і оси цю івагі його закремої кнопкою. Він загалом трішки сладніший, але конвертує зображення у його чернобіло версії. По такому ж принципу можна додавати безліч інших ефектів, як тіща вже є в бібліотекі іміч, так і з інших бібліотек і власні. І врешті можна йти опублікувати цей клас від бібліотеку на НПМ. Насправді, в процесі цієї доповіді я наткнувся на бібліотеку PhotonRS, яка саме цією робить. Це одна реалізація бібліотеки для роботи за враженнями, яка в одночасці опублікована на країця ЙО, як RAS бібліотека і завдяки УАСМ Байджен, скопілювано до WebAssembly і опубліковано на НПМ і може бути використана також як звичайний джейс бібліотека з різними ефектами для зображення. Такась енергія доциляє отримати найкращі з різних екосистем і портувати код між різними платформами. І вона стає можливою завдяки WebAssembly. Сподіваюся, ці приклади були корисними і після цієї доповіді ви зможете також спробувати скопілювати якусь з'яснуючий бібліотек до WebAssembly