Фільтри дозволяють застосовувати ряд ефектів до растрових об'єктів і екранним об'єктів (від тіні до скосів і розмиття). Кожен фільтр визначено як клас. Тому застосування фільтрів передбачає створення екземплярів об'єктів фільтрів, що не відрізняються від створення будь-якого іншого об'єкта. Після створення екземпляра об'єкта фільтра його можна легко застосувати до екранного об'єкту, скориставшись властивістю filters об'єкта. У разі об'єкта BitmapData це робиться за допомогою методу applyFilter ().
створення фільтра
Щоб створити об'єкт фільтра, просто викличте метод конструктора для обраного класу фільтра. Наприклад, щоб створити об'єкт DropShadowFilter, скористайтеся наступним кодом:
Хоча тут це не показано, конструктор DropShadowFilter () (як і конструктори всіх класів фільтра) приймає ряд необов'язкових параметрів, які можна використовувати для налаштування зовнішнього вигляду ефекту фільтра.
застосування фільтру
Після створення об'єкта фільтра його можна застосувати до екранного об'єкту або об'єкту BitmapData. Метод застосування фільтра залежить від об'єкта, до якого він застосовується.
Застосування фільтру до екранного об'єкту
Коли ефекти фільтрів застосовуються до екранного об'єкту, це відбувається за допомогою властивості filters. Властивість filters екранного об'єкта є екземпляром Array, елементи якого є об'єктами фільтрів, застосованими до екранного об'єкту. Щоб застосувати до екранного об'єкту один фільтр, створіть екземпляр фільтра, додайте його до примірника Array і надайте цей об'єкт Array властивості filters екранного об'єкта:
Якщо потрібно присвоїти об'єкту кілька фільтрів, просто додайте всі фільтри до примірника Array перед присвоєнням його властивості filters. До об'єкту Array можна додати кілька об'єктів, передавши їх конструктору в якості параметрів. Наприклад, цей код застосовує фільтр фаски і фільтр світіння до раніше створеного екранному об'єкту:
Для створення масиву, що містить фільтри, можна використовувати конструктор new Array () (як показано в попередніх прикладах), або скористатися синтаксисом литерала Array, помістивши фільтри в квадратні дужки ([]). Наприклад, наступний рядок коду:
виконує ту саму дію, що і рядок коду
Якщо до екранних об'єктів застосовується кілька фільтрів, вони вступають в силу послідовно і мають кумулятивний ефект. Наприклад, якщо масив фільтрів в своєму розпорядженні два елементами (фільтром фаски, який додається першим, і фільтром тіні, який додається другим), фільтр тіні застосовується як до фільтру фаски, так і до екранного об'єкту. Це відбувається через те, що фільтр тіні знаходиться в масиві фільтрів на другій позиції. Якщо потрібно застосовувати фільтри без кумулятивного ефекту, необхідно застосувати кожен фільтр до нової копії екранного об'єкта.
Якщо один або кілька фільтрів тільки присвоюються екранному об'єкту, можна створити екземпляр фільтра і привласнити його об'єкту в одній інструкції. Наприклад, наступний рядок коду застосовує фільтр розмиття до екранного об'єкту з ім'ям myDisplayObject:
Попередній код створює екземпляр Array за допомогою синтаксису литерала Array (квадратні дужки), створює екземпляр BlurFilter як елемент об'єкта Array і привласнює цей об'єкт Array властивості filters екранного об'єкта з ім'ям myDisplayObject.
Видалення фільтрів з екранного об'єкта
Видалення всіх фільтрів з екранного об'єкта настільки ж просто, як і присвоєння нульового значення властивості filters:
Якщо до об'єкта застосовані кілька фільтрів і потрібно видалити тільки один з фільтрів, слід виконати ряд дій, щоб змінити масив властивості filters. Додаткові відомості див. У розділі Можливі проблеми при роботі з фільтрами.
Застосування фільтру до об'єкта BitmapData
Застосування фільтру до об'єкта BitmapData вимагає використання методу applyFilter () для об'єкта BitmapData:
Метод applyFilter () застосовує фільтр до вихідного об'єкту BitmapData, в результаті чого з'являється нове фільтроване зображення. Цей метод не змінює вихідний оригінал; замість цього результат застосування фільтра до вихідного зображення зберігається в екземплярі BitmapData, по відношенню до якого застосовується метод applyFilter ().
Як працюють фільтри
Фільтрація екранних об'єктів виконується шляхом кешування копії вихідного об'єкта в якості прозорого растрового зображення.
Після застосування фільтра до екранного об'єкту Виконавча кешируєт об'єкт в якості растрового зображення до тих пір, поки об'єкт має дійсний список фільтрів. Початкове растрове зображення потім використовується в якості вихідного зображення для всіх застосованих згодом ефектів фільтрів.
Кожен екранний об'єкт, як правило, має два растрових зображення: одне з вихідним нефільтрованим екранним об'єктом, а інше для кінцевого зображення, отриманого після фільтрації. Кінцеве зображення використовується при візуалізації. Якщо екранний об'єкт не змінюється, кінцеве зображення не оновлюється.
Можливі проблеми при роботі з фільтрами
При роботі з фільтрами необхідно враховувати ряд потенційних джерел плутанини або проблем.
Кешування фільтрів і растрових зображень
Щоб застосувати фільтр до екранного об'єкту, необхідно включити кешування растрових зображень для цього об'єкта. У разі застосування фільтра до екранного об'єкту, властивість cacheAsBitmap якого має значення false. властивості об'єкта cacheAsBitmap автоматично встановлюється значення true. Якщо згодом ви видалите всі фільтри з екранного об'єкта, властивості cacheAsBitmap буде призначено останнім із привласнених значень.
Зміна фільтрів під час виконання
Якщо до екранного об'єкту вже застосований один або кілька фільтрів, набір фільтрів неможливо змінити шляхом додавання додаткових фільтрів або видалення фільтрів з масиву властивості filters. Замість цього, щоб додати або змінити застосовуваний набір фільтрів, необхідно внести зміни в окремий масив, а потім привласнити даний масив властивості filters екранного об'єкта для фільтрів, що застосовуються до об'єкта. Це найпростіше зробити шляхом зчитування масиву властивості filters в змінну Array і внесення модифікацій в цей тимчасовий масив. Після цього масив повторно призначається властивості filters екранного об'єкта. У більш складних випадках може бути необхідно зберегти окремий головний масив фільтрів. У нього вносяться зміни, а потім головний масив повторно призначається властивості filters екранного об'єкта після кожної зміни.
Додавання додаткового фільтра
Процес додавання додаткового фільтра до екранного об'єкту, до якого вже застосований один або кілька фільтрів, показаний в наступному коді. Спочатку до екранного об'єкту з ім'ям myDisplayObject застосовується фільтр світіння; потім при натисканні на екранний об'єкт викликається функція addFilters (). У цій функції до myDisplayObject застосовуються два додаткових фільтра:
Видалення фільтра з набору фільтрів
Якщо до екранного об'єкту застосовано кілька фільтрів і потрібно видалити один з цих фільтрів, продовжуючи застосовувати інші фільтри до об'єкта, фільтри копіюються в тимчасовий масив, непотрібний фільтр видаляється з масиву, а потім виконується повторне призначення тимчасового масиву властивості filters екранного об'єкта. У розділі «Отримання значень і видалення елементів масиву» вказано ряд способів видалення одного або декількох елементів з будь-якого масиву.
Найбільш прямий спосіб полягає у видаленні самого верхнього фільтра об'єкта (фільтра, застосованого до об'єкта останнім). Метод pop () класу Array використовується для видалення фільтра з масиву:
Точно так же, щоб видалити найнижчий фільтр (перший фільтр, застосований до об'єкта), використовується той же код, підставляють метод shift () класу Array замість методу pop ().
Щоб видалити фільтр з середини масиву фільтрів (припускаючи, що масив має більше двох фільтрів), необхідно скористатися методом splice (). Ви повинні знати покажчик (позицію в масиві) видаляється фільтра. Наприклад, наступний код видаляє другий фільтр (фільтр з покажчиком 1) з екранного об'єкта:
Визначення покажчика фільтра
Необхідно знати, який фільтр слід видалити з масиву, щоб дізнатися покажчик фільтра. Необхідно або дізнатися (вивчивши спосіб розробки програми), або обчислити покажчик видаляється фільтра.
Найбільш оптимальний підхід полягає в розробці власного додатка, щоб видаляється фільтр завжди знаходився на одній і тій же позиції в наборі фільтрів. Наприклад, якщо у вас є одиничний екранний об'єкт, до якого застосовано фільтр згортки і фільтр тіні (саме в такому порядку), і потрібно видалити фільтр тіні, зберігши фільтр згортки, цей фільтр знаходиться в відомої позиції (самий верхній фільтр). Завдяки цьому ви завжди можете заздалегідь дізнатися, який метод Array використовувати (в даному випадку Array.pop () для видалення фільтра тіні).
Якщо фільтр, який потрібно видалити, завжди належить певному типу, але не обов'язково займає одну і ту ж позицію в наборі фільтрів, ви можете перевірити тип даних для кожного фільтра в масиві, щоб визначити, який з них слід видалити. Наприклад, наступний код визначає, який фільтр в наборі є фільтром світіння, і видаляє цей фільтр з набору.
У більш складному випадку, наприклад, тоді, коли видаляється фільтр вибирається під час виконання, найкращий підхід полягає в збереженні окремої постійної копії масиву фільтра, який служить головним списком фільтрів. Кожен раз при внесенні змін до набір фільтрів змініть головний список, а потім використовуйте цей масив фільтра як властивість filters екранного об'єкта.
Наприклад, в наступному прикладі коду до екранного об'єкту застосовується ряд фільтрів згортки для створення різних візуальних ефектів. Пізніше в додатку один з цих фільтрів видаляється, в той час як інші залишаються. В даному випадку код зберігає головну копію масиву фільтрів, а також посилання на підлягає видаленню фільтр. Пошук і видалення певного фільтра схожі на попередній підхід, за винятком того, що замість створення тимчасової копії масиву фільтрів обробляється головна копія, яка потім застосовується до екранного об'єкту.
В даному підході (коли ви порівнюєте збережену посилання на фільтр з елементами в масиві фільтрів, щоб визначити, який фільтр слід видалити) необхідно зберегти окрему копію масиву фільтрів. Код не діє, якщо ви порівнюєте збережену посилання на фільтр з елементами в тимчасовому масиві, скопійованими з властивості filters екранного об'єкта. Це відбувається тому, що коли ви привласнюєте масив властивості filters. Виконавча створює копію кожного об'єкта фільтра в масиві внутрішнім чином. Ці копії (на відміну від вихідних об'єктів) застосовуються до екранного об'єкту. І коли ви зчитуєте властивість filters в тимчасовий масив, тимчасовий масив містить посилання на скопійовані об'єкти фільтра, а не на посилання на вихідні об'єкти фільтра. Внаслідок цього, якщо в попередньому прикладі ви намагалися визначити покажчик filterToRemove. порівнюючи його з фільтрами в тимчасовому масиві фільтрів, збіги знайдено не було.
Фільтри і трансформації об'єкта
Жодна з фільтрованих областей (наприклад, тінь), що знаходяться за межами обмежує прямокутного вікна екранного об'єкта, не розглядається як частина поверхні з метою розпізнавання вказується точки (визначення накладення або перетину примірника з іншим примірником). Так як методи розпізнавання вказується точки для класу DisplayObject засновані на векторах, розпізнавання неможливо виконати по відношенню до растровому результату. Наприклад, якщо ви застосуєте фільтр фаски до примірника кнопки, розпізнавання не буде доступно для скошеної частини екземпляра.
Масштабування, обертання і зрушення не підтримуються фільтрами; якщо сам фільтрований об'єкт масштабується (якщо scaleX і scaleY Не є 100%), ефект фільтру не масштабується разом з екземпляром. Це означає, що вихідна фігура примірника обертається, масштабується або зсувається, але фільтр не обертається, не масштабується і не зрушується разом з екземпляром.
Примірник можна анімувати за допомогою фільтра, щоб створити реалістичні ефекти або вкладені екземпляри і скористатися класом BitmapData, щоб анімувати фільтри для отримання цього ефекту.
Фільтри і об'єкти Bitmap
Якщо до об'єкта BitmapData застосовується будь-який фільтр, властивості cacheAsBitmap автоматично присвоюється значення true. Таким чином, фільтр фактично застосовується до копії об'єкта, а не до оригіналу.
Ця копія потім поміщається на основний екран (над вихідним об'єктом) якомога ближче до найближчого пікселя. Якщо межі вихідного растрового об'єкта змінюються, растрове зображення фільтрованої копії відтворюється на основі оригіналу, а не розтягується і не спотворюється.
Якщо ви видалите всі фільтри для екранного об'єкта, властивість cacheAsBitmap прийме значення, яке було йому присвоєно перед застосуванням фільтра.