Файлы к данной лекции Вы можете скачать здесь.
В начале 1990-х удивительный мир мультимедиа впервые пришел на персональные компьютеры с Windows. До этого таким машинам тяжело было воспроизводить аудио и видео и работать с компакт-дисками (помните о них?), и обеспечивать тот богатый опыт взаимодействия, который сегодня мы считаем привычным. Опыт работы с мультимедиа был восхитительно новым, и многие люди от всего сердца отдались ему, в том числе и группа инженеров поддержки в Microsoft, которая специализировалась в этой области. Хотя моя команда (мы занимались пользовательским интерфейсом) была расположена более чем в 100 футах от них, мы могли отлично слышать, - в течение всего дня!, - всякие писки и звонки, исходившие из динамиков их машин на фоне мягких звуков дождя в бассейне Амазонки.
Тогда же многие пользователи Windows развлекались, назначая всяческие безумные звуки каждому щелчку мыши, открытию окна, поступлению почты и каждому системному событию, о котором можно подумать. Тем не менее, через месяц-другой этой какофонии, делающей работу похожей на карнавал, большинство людей начало отключать многие, если не все эти звуки.Я, например, в конце концов, выключил их все. Проще говоря, я устал от чрезмерного шума.
В том же духе, вы можете вспомнить, что когда появились, во всей красе, первые DVD, почти каждое меню диска было полно визуальных украшений. Теперь это не так: многие зрители, я думаю, устают ждать, пока все это будет показано, и просто хотят воспользоваться диском по его прямому назначению, приступив к просмотру фильма так быстро, как только возможно.
Сегодня мы переживаем то же самое с высококачественной анимацией. Сейчас, когда большое количество систем имеет высокочувствительные сенсорные экраны и графические процессоры, позволяющие воспроизводить качественные графические эффекты, заманчиво использовать анимацию везде, где это возможно. Однако, несмотря на то, что анимация, на самом дел, добавляет функциональности и смысла происходящему в приложении, ползователи могут устать от нее, как от DVD-меню, особенно, если она начинает вмешиваться в рабочий процесс, постоянно заставляя пользователей ждать, когда закончится анимация. Держу пари, что каждый читатель этого курса, хотя бы однажды, без всякого толка много раз нажимал на кнопку Меню пульта DVD-проигрывателя.
Именно поэтому дизайн приложений для Магазина Windows особое внимание уделяет целенаправленной анимации: если у анимации в вашем приложении нет реальной цели, спросите себя: "Зачем я собираюсь это применять?". Найдите время для того, чтобы посмотреть на то, как Windows 8 и некоторые встроенные приложения используют и не используют анимацию. Обратите внимание на то, как много анимаций предназначены для отслеживания действий, или, иначе, для предоставления немедленной обратной связи при сенсорном взаимодействии. Такой подход целенаправленно помогает пользователям знать, что система восприняла их действия (и, на самом деле, это есть в требованиях сертификации для Магазина Windows). Другие анимации, такие, которые происходят, когда элемент был добавлен в спискок или удален их него, предназначены для привлечения внимания к изменениям, для смягчения их визуального воздействия и создание ощущения плавности. В других случаях вы можете обнаружить приложения, которые, возможно, чрезмерно используют анимацию, просто применяя ее потому что у них есть такая возможность, или пытаясь точно передать поведение физических объектов там, где в этом нет необходимости.
Таким образом, чрезмерная анимация представляет собой, своего рода "визуальное оформление", обладающее тем же эффектом, что и прочие элементы оформления, которые отвлекают пользователя от содержимого, которое ему по-настоящему нужно. (Если вы не можете удержаться от соблазна добавить немного подобных эффектов, предусмотрите, как минимум, возможность для их отключения).Позвольте мне сказать это иначе. Размышляя об анимациях, спросите себя: "О чем они сообщают?". Анимации – это разновидность коммуникации, что-то вроде визуального языка. Я даже рискнул бы сказать (как я решился сделать сейчас), что анимации, на самом деле, лишь сообщают об одном или нескольких событиях следующих трех видов:
Если бы я назначил этим трем категориям процентные значения, представляющие то, как часто они используются или могли бы использоваться, я, возможно, дал бы каждой из них, соответственно, 80%, 15% и 5% (хотя некоторые из анимаций служат нескольким целям). Иными словами, первая часть коммуникации заключается в том, чтобы слушать и отвечать, и именно это приложению следует делать большую часть времени. Вторая часть касается вежливости, которая хороша в разумных пределах, так как рукопожатия, объятия и приветствия, если их слишком много, могут вызвать раздражение. Третья часть, которую можно сравнить с взмахом руки, в свою очередь, может быть полезна лишь тогда, когда для ее использования есть реальные причины, в противном случае она становится лишь средством внешнего оформления.
Есть и еще одна веская причина разумному и экономному использованию анимации: потребление электоэнергии. Неважно, как она реализована, основана ли на ресурсах центрального процессора или графического ядра, анимация – это энергозатратный процесс. Каждый ватт, утекающий из батарей устройства пользователя, должен быть направлен на удовлетворение целей, ради которых он использует устройство, а не выброшен на ветер. Именно поэтому данная лекция называется "Целенаправленная анимация", а не просто "Анимация"!
В любом случае, вы и ваши дизайнеры принимаете окончательное решение о том, как и где использовать анимации. Позвольте мне подчеркнуть, что анимация должна быть частью дизайна приложения, а не одной из деталей его реализации. Анимация – это важная часть общего опыта взаимодействия пользователя и приложения. Часто работа над дизайном приложения сосредоточена на статических каркасах и статических моделях, но ни то, ни другое не отражает динамических элементов наподобие анимаций и переходов. Анимация так же тесно связана с макетом приложения и ее следует проектировать вместе с макетом, на ранних стадиях работы над дизайном приложения.
В этой необычно короткой лекции, таким образом, мы сначала посмотрим, что предоставляет нам библиотека анимаций WinJS (WinJS Animations Library) – коллекция анимаций, построенных на основе CSS, которые уже воплощают стиль Windows 8 во многих обычно используемых операциях. После этго мы рассмотрим возможности CSS, лежащие в основе этих анимаций, которые вы, конечно, можете использовать напрямую. На самом деле, если не говорить об играх и других приложениях, основное содержимое которых состоит из анимированных объектов, вы, вероятно, можете использовать CSS для удовлетворения большинства потребностей в анимации. Это хорошая идея, так как подсистема CSS очень хорошо оптимизирована для того, чтобы извлекать преимущества из аппаратного ускорения, а при выполнении покадровой анимации средствами самого JavaScript это не так. Тем не менее, мы окончим эту лекцию рассмотрением этого последнего подхода, так как есть некоторые советы и секреты, касающиеся того, как сделать это хорошо в приложениях для Магазина Windows.
Прежде чем мы продолжим, я хочу рассказать об одном параметре, который спрятан глубоко в настройках Панели управления, о котором вам надо знать, так как она влияет на то, как ведет себя библиотека анимаций WinJS, и ей следует влиять на ту анимацию, которую вы реализуете своими силами. Находясь на Рабочем столе, откройте панель чудо-кнопок, нажмите на чудо-кнопку Параметры и выберите пункт Панель управления. Затем перейдите в раздел Специальные возможности > Оптимизация изображения на экране, прокрутите содержимое окна к его нижней части и в разделе Упрощение зрительного восприятия изображений на экране, установите флаг "Отключить всю излишнюю анимацию (по возможности)" (Turn off all unnecessary animations (when possible), рис. 7.1.
(рис 7.1) Очень важный параметр, касающийся анимации в Панели управления, вызванной с Рабочего стола
Смысл этого флага заключается в том, что некоторым пользователям анимации по-настоящему мешают, что усложняет их работу с системой в целом. Кроме того, по медицинским причинам, некоторые пользователи могут предпочесть минимизировать движения на экране для того, чтобы сделать работу спокойнее. Таким образом, когда данный параметр включен, анимации WinJS не выполняются. Рекомендуется, чтобы приложения так же отключали большинство собственных анимаций, если не все из них.
Данный параметр Панели управления может быть получен с помощью свойства ):
var settings = new Windows.UI.ViewManagement.UISettings(); var enabled = settings.animationsEnabled;
Так же вы можете просто вызвать метод WinJS.UI. isAnimationEnabled, который возвратит true или false в зависимости от значения этого свойства. WinJS использует этот параметр для управления поведением анимации.
WinJS так же имеет счетчик, который вы можете использовать для временного включения или выключения анимации в соответствии со значением animationsEnabled. Вы можете изменять его, вызывая WinJS.UI.enableAnimations и WinJS.UI.disableAnimations, их эффект последователен, и свойство animationsEnabled считается равным 0, если параметр Панели управления включен, и 1 – если выключен.
Реализуя собственную анимацию, либо с помощью CSS, либо – с помощью механизмов наподобие setInterval или requestAnimationFrame, правильно будет ориентироваться на установку animationsEnabled там, где это имеет смысл. Я добавил это условие, так как если анимация важна для содержимого приложения, наподобие игры, эта установка к нему не применима. То же самое относится к анимации, наподобие часов в приложении-часах. Это касается анимации, которая добавляет эффект быстроты и подвижности к содержимому, но может быть отключена без потери функциональности приложения.
Рассуждая об использовании анимации в приложении, в первую очередь вы должны принять во внимание библиотеку анимации в WinJA, которую можно найти в пространстве имен ). Каждая анимация представлена в виде функции в данном пространстве имен, которую вы вызываете, если хотите, чтобы включилась определенная анимация или переход. Преимущество использования библиотеки заключаются в том, что она уже воплощает в себе стиль Windows, и, на самом деле, применяется WinJS для анимации встроенных элементов управления, всплывающих элементов и так далее, обеспечивая соответствие пользовательского интерфейса руководствам по дизайну. Более того, так как библиотека построена на основе анимаций и переходов CSS, она независима от WinRT и полностью функциональна на страницах веб-контекста, которые может загружать WinJS (но, опять же, и при работе с такими страницами нужно обращать внимание на настройки воспроиз ведени анимации, описанные в предыдущем разделе).
Все анимации, перечисленные в таблице ниже, имеют руководства, касающиеся того, когда и как их следует использовать. Это, опять же, больше вопрос дизайна, чем реализации, как упомянуто выше. Зная о библиотеке анимации, дизайнеры будут более готовы к тому, чтобы видеть, где могут быть применены анимации и включать их в проект на ранней стадии дизайна приложения, что сделает ваши действия, как разработчика, более предсказуемыми.
Вы можете найти полное руководство в материалах "Анимация пользовательского интерфейса" (http://msdn.microsoft.com/library/windows/apps/hh465165.aspx) и "Анимация пользовательского интерфейса со всплывающими элементами" (http://msdn.microsoft.com/library/windows/apps/hh465259.aspx) в документации, где так же содержатся конкретные руководства по отдельным анимациям, представленным ниже. Здесь я лишь привожу их краткий обзор.
Важный вопрос. Встроенные элементы управления и другие элементы пользовательского интерфейса, наподобие тех, с которыми мы работали ранее, уже используют подходящие анимации. Например, вам не нужно анимировать нажатие на кнопку в элементе button, не нужно анимировать появление или исчезновение элементов наподобие WinJS.UI.AppBar. Вы, в основном, будете использовать анимации, реализуя пользовательский интерфейс непосредственно в HTML-макете, или создавая пользовательские элементы управления.
| Название анимации | Методы WinJS.UI.Animation | Описание и использование |
|---|---|---|
| Переход страницы (Page Transition) | enterPage, exitPage |
Анимирует отображение или прекращение отображения содержимого всей страницы, как в случае перехода на первую страницу приложения после экрана-заставки, так и при переходах между страницами приложения. Избегайте использования
enterPage, когда содержимое уже отображается на экране, то есть, используйте его только тогда, когда полностью меняете содержимое экрана.
|
| Переход содержимого (Content Transition) | enterContent, exitContent |
Анимирует отображение или прекращение отображения одного элемента содержимого или их набора, в частности, используется, когда содержимое не готово к показу, когда страница загружена, или когда часть страницы изменяется внутри контейнера. Если содержимое должно переместиться в ответ на изменение контейнера, как в случае изменения размера, вы можете переместить эти элементы с помощью анимаций разворачивания/сворачивания (expand/collapse) или перемещения (reposition). |
| Появление и исчезновение (Fade In/Out) | fadeIn, fadeOut |
Используется для показа или скрытия промежуточных элементов управления или пользовательского интерфейса, как происходит с полосой прокрутки, или когда элемент-заполнитель заменяется на загруженный элемент. Это так же хороший вариант анимации по умолчанию для ситуаций, в которых другие анимации не применимы. |
| Плавный переход между элементами (Crossfade) | crossFade |
Смягчает переход между различными состояниями элемента. Используется в сценариях обновления, как в случаях, когда приложение для чтения новостей обновляет все свое содержимое за один раз. |
| Касание и отрыв указателя (Pointer Up/Down) | pointerUp, pointerDown |
Предоставляет немедленную обратную связь на успешное касание элемента или плитки или щелчок по ним. Обратите внимание на то, что встроенные элементы управления, такие, как кнопка и ListView уже включают в себя эти анимацию. |
| Разворачивание и сворачивание (Expand/Collapse) | createExpandAnimation,
createCollapseAnimation
|
Добавляет или скрывает дополнительное пространство внутри элемента, например, предоставляя место для сообщения об ошибке или скрывая параметры, в которых нет необходимости. |
| Перемещение (Reposition) | createRepositionAnimation |
Используется для перемещения элемента на новое место. |
| Показ и скрытие всплывающих окон (Show/Hide Popup) | showPopup, hidePopup |
Используется для отображения и скрытия всплывающих элементов интерфейса, таких, как меню, всплывающие окна, подсказки и других контекстно-зависимых элементов, которые появляются поверх рабочей области приложения (диалоговые окна, однако, используют Появление (Fade In)). Старайтесь не использовать для элементов, которые являются частью представления приложения – вместо этого используйте анимации Переход содержимого (Content Transition) и Появление и исчезновение Fade In/Out. Так же, у вас нет необходимости использовать это при работе со встроенными элементами управления, так как они уже применяют необходимые анимации. |
| Показ и скрытие элементов пользовательского интерфейса по краям (Show/Hide Edge UI) Показ и скрытие панелей (Show/Hide Panel UI) | showEdgeUI, hideEdgeUI,
showPanel, hidePanel
|
Используются для показа и скрытия элементов пользовательского интерфейса по краям, наподобие панелей приложения и программной клавиатуры. Анимация элементов интерфейса по краям экрана предназначена для элементов, которые выдвигаются на небольшое расстояние. Анимация показа и скрытия панелей предназначена для тех случаев, когда элементы выдвигаются на большее расстояние.
Эти анимации не следует использовать для элементов пользовательского интерфейса, которые не выдвигаются с края экрана и не задвигаются за край экрана. Вместо этого можно использовать анимацию Перемещение (Reposition ). Анимация Плавный переход между элементами (Crossfade) так же обычно применяется после показа и одновременно со скрытием. Встроенные элементы управления, отображаемые по краям, такие, как панель приложения и панель параметров, уже применяют эту анимацию. |
| Считывание (Для плиток) (Peek (for tiles)) | createPeekAnimation |
Анимирует обновление содержимого плитки при поочередном отображении изображения и текста, смотрите Главу 2 курса "Программная логика приложений для Windows 8, созданных с использованием HTML, CSS и JavaScript и их взаимодействие с системой". Так же можно использовать для циклического отображения данных на плитке. Эта анимация используется для живых плиток на Начальном экране Windows. |
| Обновление индикатора событий (Badge Update) | updateBadge |
Используется для обновления числового индиактора событий на плитке. |
| Подсказка прокрутки (Swipe Hint) | swipeReveal |
Используется в ответ на событие касания и удержания для того, чтобы показать, что элемент может быть выделен прокруткой. |
| Выбор и отмена выбора прокруткой (Swipe Select/Deselect) | swipeSelect, swipeDeselect |
Анимирует элемент при прокрутке для выбора или отмены выбора. |
| Добавление и удаление элементов списка (Add/Delete from List) | createAddToListAnimation,
createDeleteFromListAnimation
|
Анимирует добавление элементов в список или удаление их из списка, в таком качестве используется элементом управления ListView. Анимация добавления сначала переместит существующие элементы списка, чтобы освободить место для новых элементов и затем добавит новые элементы. Анимация удаления из списка убирает элементы из списка и перемещает оставшиеся элементы. Избегайте использования этих энимаций для отображения или удаления контейнера или для добавления или удаления всего содержимого коллекции. Вместо этого используйте Переход содержимого (Content Transition). |
| Добавление и удаление элементов списка поиска (Add/Delete from Search List) | createAddToSearchListAnimation,
createDeleteFromSearchListAnimation
|
Эти анимации похожи на те, которые используются для анимации работы со списком, но они созданы для более быстрого внесения изменений, когда заполняется список результатов поиска. Проще говоря, они имеют меньшую длительность. |
| Начало и окончание перетаскивания или перетаскивание между началом и окончанием (Start/End Drag-Drop) | dragSourceStart, dragSourceEnd,
dragBetweenEnter, dragBetweenLeave
|
Дает визуальную обратную связь во время операции перетаскивания, как на Начальном экране, когда вы перемещаете по нему плитки. Анимации в начале и в конце перетаскивания используются для перемещаемых элементов и их следует всего использовать вместе. Анимации между началом и окончанием используются для подготовки места в потенциальной позиции вставки, что помогает пользователю понять, как будет выглядеть содержимое при помещении элемента в данное место. Для этой цели нужно определить размер потенциальной целевой области (прямоугольную), таким образом вы можете отслеживать перемещения указателя в эти области и из них. |
Если вы хотите увидеть, как работают эти анимации, вы можете найти их все в исходном коде WinJS, в файле iu.js. Просто найдите там методы и вы увидите, как они устроены. Анимация Плавный переход между элементами (Crossfade), например, анимирует прозрачность появляющегося элемента от 0 до 1 в течение 167 мс, с применением линейной функции, у исчезающего элемента прозрачность анимируется таким же образом, но от 1 до 0.
Анимация Касание указателя (Pointer Down) изменяет масштаб элемента со 100% до 97,5% в течение 167 мс, в соответствии с кубической кривой безье, в то время как анимация Отрыв указателя (Pointer Up) выполняет противоположные действия.
Знание этих характеристик, или метрик анимации (animation metrics) важно при создании веб-содержимого для интеграции с вашим приложением. Как отмечено выше, требования к сертификации приложений для Windows 8, в частности, раздел 4.5, показывают, что цели касания должны давать визуальную обратную связь. Так как вы не можете использовать WinJS в удаленных веб-страницах, знание того, как работают эти анимации поможет вам имитировать подобное поведение на таких страницах.
Внутри приложения, однако, вы должны получать метрики анимации программным образом, посредством API в ), вместо того, чтобы задавать какие-либо значения в коде. Вы можете найти демонстрацию использования этого API в примере "Метрики анимации" (http://code.msdn.microsoft.com/windowsapps/animation-metrics-sample-acb0220c).
Как ни интересны были бы подобные подробности, конечно, их всегда можно изменить. В конце концов, самое важное то, чтоб вы выбираете анимации не из-за визуальных эффектов, а основываясь на их смысловом значении, используя нужные анимации в нужное время и в нужном месте. Поэтому давайте посмотрим, как это сделать.
Совет №1. Все анимации WinJS реализованы с использованием функций ) и ), которые вы так же можете использовать для пользовательских анимаций.
Совет №2. При исполнении анимаций всегда избегайте изменения содержимого элемента или его CSS-стилей, которые воздействуют на те же его свойства, что и анимации. Результаты непредсказуемы и ненадежны, и могут приводить к проблемам с производительностью.
Для того, чтобы увидеть все WinJS-анимации в действии, запустите пример "Библиотека анимации HTML" (http://code.msdn.microsoft.com/windowsapps/Using-the-Animation-787f3720). В нем показано очень много разных анимаций, и этот пример, без сомнения, получает награду за самое большое количество сценариев: двадцать два! На самом деле, первое, что вам следует сделать, это перейти в Сценарий 22 и посмотреть, включены ли анимации, так как это, при прочих равных условиях, сильно подействует на то, что вы можете увидеть. В этом сценарии вы увидите, установлен ли флаг UISettings.animationsEnabled, и здесь вы можете увеличить или уменьшить счетчик активности анимации в WinJS. Поэтому взгляните на него прямо сейчас, так как если вы похожи на меня (мне не нравится ждать, пока моя панель задач выдвигается и задвигается), вы могли выключить системные анимации для того, чтобы вам удобнее было работать с рабочим столом. Поначалу я не знал, что эта установка воздействует и на WinJS!
Очевидно, я не буду приводить здесь код каждого из 22 сценариев, на самом деле, делать это необязательно, так как многие из них работают сходным образом. Единственное реальное различие наблюдается между теми, методы которых начинаются с create, и теми, у которых это не так, что мы скоро увидим.
Все методы анимаций возвращают promise-объекты, которые вы можете использовать для того, чтобы предпринять дополнительные действия, когда анимация завершена (здесь будет вызван обработчик завершения). Если вы уже знаете немного о CSS-переходах и анимациях, вы можете верно догадываться, что эти promise-объекты включают в себя события наподобие transitionend и animationend, поэтому вам не нжужно непосредственно прослушивать эти события, если вы хотите объединить анимации в цепочку или синхронизировать. Для объединения в цепочку, вы можете просто объединить в цепочку promise-вызовы, для целей синхронизации вы можете получить promise-объекты для нескольких анимаций и подождать их завершения, используя методы наподобие WinJS.Promise.join или WinJS.Promise.any.
Promise-объекты анимаций, кроме того, поддерживают метод cancel, который убирает анимацию элемента. Этот метод немедленно устанавливает значение свойства, на которое воздействует, в его конечное состояние, что приводит к немедленному видимому переходу элемента в это состояние. И отменили ли вы анимацию, или она сама окончилась, promise-объект решает, что операция успешно завершена. Отмена анимации, другими словами, вызывает обработчик завершения promise-объекта, а не его обработчик ошибки.
Помните, что так как все WinJS-анимации реализованы с помощью CSS, они не начинаются, пока вы не передадите управление обратно в поток пользовательского интерфейса. Это означает, что вы можете настроить несколько анимаций, зная, что они начнутся примерно в одно и то же время, как только вы вернетесь из функции. Поэтому, хотя методы анимации возвращают promise-объекты, они не похожи на другие асинхронные операции WinRT, которые начинают исполняться в другом потоке.
В любом случае, давайте взглянем на код! В самом простом случае все, что вам нужно сделать – это вызвать один из методов анимации и анимация будет исполнена, когда вам нужно. Сценарий 6 примера, например, просто добавляет следующие обработчики к событиям MSPointerDown и MSPointerUp трех разных элементов (js/pointerFeedback.js):
function onPointerDown(evt) { WinJS.UI.Animation.pointerDown(evt.srcElement);
}
function onPointerUp(evt) { WinJS.UI.Animation.pointerUp(evt.srcElement);
}
Нам обычно не нужно что-либо делать, когда анимация завершится, поэтому нам не нужно вызывать done или предоставлять завершающую функцию. На самом деле, использование многих из анимаций так же просто.
Анимация crossFade, в свою очередь (Сценарий 10), работает с двумя элементами: появляющимся и исчезающим (все они должны быть видимыми и являться частями DOM в процессе анимации, учтите!). Вызов анимации выглядит так: (js/crossfade.js):
WinJS.UI.Animation.crossFade(incoming, outgoing);
Но это еще не все. Обычная возможность анимаций заключается в том, что вы можете предоставить массив элементов, на которых должна быть исполнена одна и та же анимация, или, в случае с crossfade, два массива элементов. В то время, как это не особенно удобно для анимаций наподобие pointerDown и pointerUp (каждое событие указателя следует обрабатывать независимо), это, без сомнения, удобно для большинства остальных.
Рассмотрим анимацию enterPage. В своей единственной форме она принимает элемент для анимации и необязательное начальное смещение, где должен находиться элемент по отношению к своей конечной позиции. (Вообще говоря, вы вам следует опустить это смещение, если оно вам не нужно, так как это улучшает производительность – в примере туда передается null, что я опустил в нижеприведенном коде). Анимация enterPage так же может принимать коллекцию элементов, такую, как результат работы querySelectorAll. Сценарий 1 (html/enterPage.html и js/enterPage.js) предоставляют возможность выбора того, сколько элементов нужно анимировать раздельно:
switch (pageSections) {
case "1":
// Анимировать всю страницу
enterPage = WinJS.UI.Animation.enterPage(rootGrid);
break;
case "2":
// Анимировать заголовок и тело страницы
enterPage = WinJS.UI.Animation.enterPage([[header, featureLabel], [contentHost, footer]]);
break;
case "3":
// Анимировать заголовок, области ввода и вывода
enterPage = WinJS.UI.Animation.enterPage([[header, featureLabel], [inputLabel, input], [outputLabel, output, footer]]);
break;
}
В то время, как аргумент элемента – это массив, аргумент смещения, если он задан, может быть либо отдельным смещением, которое применяется ко всем элементам, либо массивом, задающим отдельные смещения для каждого элемента. Каждое смещение – это объект, свойства которого определяют смещение. Смотрите js/dragBetween.js для Сценария 13, где этот подход используется с анимацией dragBetweenEnter:
WinJS.UI.Animation.dragBetweenEnter([box1, box2],
[{ top: "-40px", left: "0px" }, { top: "40px", left: "0px" }]);
Вот модификация, где одно и то же смещение применяется к обоим элементам:
WinJS.UI.Animation.dragBetweenEnter([box1, box2], { top: "0px", left: "40px" });
Сценарий 4 (js/transitioncontent.js) показывает, как вы можете объединить в цепочку два promise-объекта для выполнения перехода между двумя различными блоками содержимого:output передается в качестве первого параметра в
exitContent и enterContent. код должен выглядеть как показано здесь, с outgoing, который передается в exitContent и incoming, который передается в enterContent.
WinJS.UI.Animation.exitContent(outgoing, null).done( function () {
outgoing.style.display = "none";
incoming.style.display = "block";
return WinJS.UI.Animation.enterContent(incoming, null);
});
Происходящее становится немного интереснее, когда мы посмотрим в методы анимации create*, которые касаются так называемой анимации макета (layout animation), для выполнения добавления и удаления элементов в списке, разворачивания и сворачивания содержимого и так далее. Каждый из них предусматривает трехступенчатую обработку, где вы создаете анимацию, выполняете манипуляции с DOM, и затем исполняете анимацию, как показано в Сценарии 7 (js/addAndDeleteFromList.js):
// Создать анимацию addToList. var addToList = WinJS.UI.Animation.createAddToListAnimation(newItem, affectedItems); // Вставить новый элемент в дерево DOM. Элементы, на которые это повлияло, поменяют положение. list.insertBefore(newItem, list.firstChild); // Исполнить анимацию. addToList.execute();
Причина для трехступенчатой обработки заключается в применении анимацию к только что добавленному элементу, или элементу, который убирают из списка, всем им нужно присутствовать в DOM во время исполнения анимации. Такой порядок работы позволяет вам создавать анимацию на основе начального состояния содержимого, манипулировать DOM (или просто устанавливать стили, и так далее) для создания конечного состояния и затем исполнять анимацию, позволив всему встать на свои места. Вы затем можете использовать метод done promise-объекта, возвращенного из execute для выполнения любой окончательной обработки. Сценарий 5 (js/expandAndCollapse.js) разьясняет это:
// Создание анимации сворачивания.
var collapseAnimation = WinJS.UI.Animation.createCollapseAnimation(element, affected);
// Удаляем сворачивающийся элемент из содержимого документа, таким образом, зависимые элементы меняют
// положение. Не удаляйте сворачиваемый элемент из DOM и не скрывайте его в данный момент, в противном случае
// анимация этого элемента не будет выполнена.
element.style.position = "absolute";
element.style.opacity = "0";
// Исполнение анимации сворачивания.
collapseAnimation.execute().done(
// После завершения анимации (или если произошла ошибка), скрываем элемент.
function () { element.style.display = "none"; },
function () { element.style.display = "none"; }
);
В качестве последнего примера, так как я знаю, что вы достаточно сообразительны для того, чтобы самостоятельно посмотреть другие варианты, хочу показасть Сценарий 21 (js/customAnimation.js). Здесь показано, как использовать методы WinJS.UI.executeAnimation и WinJS.UI.executeTransition:
function runCustomShowAnimation() {
var showAnimation = WinJS.UI.executeAnimation(
target,
{
// Обратите внимание: этот ключевой кадр относится к ключевому кадру, определенному в customAnimation.css.
// Если он не определен в CSS, анимация не будет работать.
keyframe: "custom-opacity-in",
property: "opacity",
delay: 0, duration: 500,
timing: "linear", from: 0,
to: 1
}
);
}
function runCustomShowTransition() {
var showTransition = WinJS.UI.executeTransition(
target,
{
property: "opacity", delay: 0,
duration: 500,
timing: "linear", to: 1
}
);
}
Если вы хотите объединить несколько анимаций (как делается во многих анимациях WinJS), отметим, что обе эти функции возвращают promise-объекты, в итоге, вы можете комбинировать несколько результатов с помощью WinJS.Promise.join и использовать один обработчик завершения, который выполняет пост-обработку. Это именно то, что происходит внутри WinJS.
И если вы уже знаете что-либо о CSS-анимациях и переходах, вы, возможно, можете сказать, что объекты, которые вы передаете executeAnimation и executeTransition – это просто краткие наименования стилей CSS, которые вы используете. Коротко говоря, эти методы дают вам простой способ создавать собственные пользовательские анимации и переходы, пользуясь возможностями CSS. Посмотрим сейчас непосредственно на эти возможности.
Разработчики часто спрашивают, как создать параллактическую или панорамную анимацию фона, как на Начальном экране Windows. Если вы не знакомы с этой концепцией, перейдите на Начальный экран и прокрутите его, обращая внимание на то, что фон так же прокручивается, но медленнее, чем плитки. Это создает ощущение, будто плитки плавают над фоном.
Хотя в JavaScript можно реализовать подобный эффект (смотрите пример "KidBook" (http://ie.microsoft.com/testdrive/HTML5/KidsBook/Default.html) на сайте Internet Explorer TestDrive), мы не рекомендуем этого делать, или, по крайней мере, рекомендуем предусмотреть параметр, позволяющий отключить его. Речь идет о том, что особенности работы с потоками и модель отрисовки в JavaScript могут привести к прерывистым перемещениям, за исключением работы подобной анимации на мощных устройствах. Этот эффект будет ярко выражен на маломощных компьютерах, особенно на ARM-устройствах. Кроме того, подобная анимация может потреблять слишком много ресурсов процессора и нерационально использовать батареи.
Это – один из случаев, где использование C++ и DirectX (или даже C#/VB и XAML) имеет явное преимущества перед JavaScript, и это нужно принять во внимание, если подобный эффект в вашем приложении абсолютно необходим.
Файлы к данной лекции Вы можете скачать здесь.
В начале 1990-х удивительный мир мультимедиа впервые пришел на персональные компьютеры с Windows. До этого таким машинам тяжело было воспроизводить аудио и видео и работать с компакт-дисками (помните о них?), и обеспечивать тот богатый опыт взаимодействия, который сегодня мы считаем привычным. Опыт работы с мультимедиа был восхитительно новым, и многие люди от всего сердца отдались ему, в том числе и группа инженеров поддержки в Microsoft, которая специализировалась в этой области. Хотя моя команда (мы занимались пользовательским интерфейсом) была расположена более чем в 100 футах от них, мы могли отлично слышать, - в течение всего дня!, - всякие писки и звонки, исходившие из динамиков их машин на фоне мягких звуков дождя в бассейне Амазонки.
Тогда же многие пользователи Windows развлекались, назначая всяческие безумные звуки каждому щелчку мыши, открытию окна, поступлению почты и каждому системному событию, о котором можно подумать. Тем не менее, через месяц-другой этой какофонии, делающей работу похожей на карнавал, большинство людей начало отключать многие, если не все эти звуки.Я, например, в конце концов, выключил их все. Проще говоря, я устал от чрезмерного шума.
В том же духе, вы можете вспомнить, что когда появились, во всей красе, первые DVD, почти каждое меню диска было полно визуальных украшений. Теперь это не так: многие зрители, я думаю, устают ждать, пока все это будет показано, и просто хотят воспользоваться диском по его прямому назначению, приступив к просмотру фильма так быстро, как только возможно.
Сегодня мы переживаем то же самое с высококачественной анимацией. Сейчас, когда большое количество систем имеет высокочувствительные сенсорные экраны и графические процессоры, позволяющие воспроизводить качественные графические эффекты, заманчиво использовать анимацию везде, где это возможно. Однако, несмотря на то, что анимация, на самом дел, добавляет функциональности и смысла происходящему в приложении, ползователи могут устать от нее, как от DVD-меню, особенно, если она начинает вмешиваться в рабочий процесс, постоянно заставляя пользователей ждать, когда закончится анимация. Держу пари, что каждый читатель этого курса, хотя бы однажды, без всякого толка много раз нажимал на кнопку Меню пульта DVD-проигрывателя.
Именно поэтому дизайн приложений для Магазина Windows особое внимание уделяет целенаправленной анимации: если у анимации в вашем приложении нет реальной цели, спросите себя: "Зачем я собираюсь это применять?". Найдите время для того, чтобы посмотреть на то, как Windows 8 и некоторые встроенные приложения используют и не используют анимацию. Обратите внимание на то, как много анимаций предназначены для отслеживания действий, или, иначе, для предоставления немедленной обратной связи при сенсорном взаимодействии. Такой подход целенаправленно помогает пользователям знать, что система восприняла их действия (и, на самом деле, это есть в требованиях сертификации для Магазина Windows). Другие анимации, такие, которые происходят, когда элемент был добавлен в спискок или удален их него, предназначены для привлечения внимания к изменениям, для смягчения их визуального воздействия и создание ощущения плавности. В других случаях вы можете обнаружить приложения, которые, возможно, чрезмерно используют анимацию, просто применяя ее потому что у них есть такая возможность, или пытаясь точно передать поведение физических объектов там, где в этом нет необходимости.
Таким образом, чрезмерная анимация представляет собой, своего рода "визуальное оформление", обладающее тем же эффектом, что и прочие элементы оформления, которые отвлекают пользователя от содержимого, которое ему по-настоящему нужно. (Если вы не можете удержаться от соблазна добавить немного подобных эффектов, предусмотрите, как минимум, возможность для их отключения).Позвольте мне сказать это иначе. Размышляя об анимациях, спросите себя: "О чем они сообщают?". Анимации – это разновидность коммуникации, что-то вроде визуального языка. Я даже рискнул бы сказать (как я решился сделать сейчас), что анимации, на самом деле, лишь сообщают об одном или нескольких событиях следующих трех видов:
Если бы я назначил этим трем категориям процентные значения, представляющие то, как часто они используются или могли бы использоваться, я, возможно, дал бы каждой из них, соответственно, 80%, 15% и 5% (хотя некоторые из анимаций служат нескольким целям). Иными словами, первая часть коммуникации заключается в том, чтобы слушать и отвечать, и именно это приложению следует делать большую часть времени. Вторая часть касается вежливости, которая хороша в разумных пределах, так как рукопожатия, объятия и приветствия, если их слишком много, могут вызвать раздражение. Третья часть, которую можно сравнить с взмахом руки, в свою очередь, может быть полезна лишь тогда, когда для ее использования есть реальные причины, в противном случае она становится лишь средством внешнего оформления.
Есть и еще одна веская причина разумному и экономному использованию анимации: потребление электоэнергии. Неважно, как она реализована, основана ли на ресурсах центрального процессора или графического ядра, анимация – это энергозатратный процесс. Каждый ватт, утекающий из батарей устройства пользователя, должен быть направлен на удовлетворение целей, ради которых он использует устройство, а не выброшен на ветер. Именно поэтому данная лекция называется "Целенаправленная анимация", а не просто "Анимация"!
В любом случае, вы и ваши дизайнеры принимаете окончательное решение о том, как и где использовать анимации. Позвольте мне подчеркнуть, что анимация должна быть частью дизайна приложения, а не одной из деталей его реализации. Анимация – это важная часть общего опыта взаимодействия пользователя и приложения. Часто работа над дизайном приложения сосредоточена на статических каркасах и статических моделях, но ни то, ни другое не отражает динамических элементов наподобие анимаций и переходов. Анимация так же тесно связана с макетом приложения и ее следует проектировать вместе с макетом, на ранних стадиях работы над дизайном приложения.
В этой необычно короткой лекции, таким образом, мы сначала посмотрим, что предоставляет нам библиотека анимаций WinJS (WinJS Animations Library) – коллекция анимаций, построенных на основе CSS, которые уже воплощают стиль Windows 8 во многих обычно используемых операциях. После этго мы рассмотрим возможности CSS, лежащие в основе этих анимаций, которые вы, конечно, можете использовать напрямую. На самом деле, если не говорить об играх и других приложениях, основное содержимое которых состоит из анимированных объектов, вы, вероятно, можете использовать CSS для удовлетворения большинства потребностей в анимации. Это хорошая идея, так как подсистема CSS очень хорошо оптимизирована для того, чтобы извлекать преимущества из аппаратного ускорения, а при выполнении покадровой анимации средствами самого JavaScript это не так. Тем не менее, мы окончим эту лекцию рассмотрением этого последнего подхода, так как есть некоторые советы и секреты, касающиеся того, как сделать это хорошо в приложениях для Магазина Windows.
Прежде чем мы продолжим, я хочу рассказать об одном параметре, который спрятан глубоко в настройках Панели управления, о котором вам надо знать, так как она влияет на то, как ведет себя библиотека анимаций WinJS, и ей следует влиять на ту анимацию, которую вы реализуете своими силами. Находясь на Рабочем столе, откройте панель чудо-кнопок, нажмите на чудо-кнопку Параметры и выберите пункт Панель управления. Затем перейдите в раздел Специальные возможности > Оптимизация изображения на экране, прокрутите содержимое окна к его нижней части и в разделе Упрощение зрительного восприятия изображений на экране, установите флаг "Отключить всю излишнюю анимацию (по возможности)" (Turn off all unnecessary animations (when possible), рис. 7.1.
(рис 7.1) Очень важный параметр, касающийся анимации в Панели управления, вызванной с Рабочего стола
Смысл этого флага заключается в том, что некоторым пользователям анимации по-настоящему мешают, что усложняет их работу с системой в целом. Кроме того, по медицинским причинам, некоторые пользователи могут предпочесть минимизировать движения на экране для того, чтобы сделать работу спокойнее. Таким образом, когда данный параметр включен, анимации WinJS не выполняются. Рекомендуется, чтобы приложения так же отключали большинство собственных анимаций, если не все из них.
Данный параметр Панели управления может быть получен с помощью свойства ):
var settings = new Windows.UI.ViewManagement.UISettings(); var enabled = settings.animationsEnabled;
Так же вы можете просто вызвать метод WinJS.UI. isAnimationEnabled, который возвратит true или false в зависимости от значения этого свойства. WinJS использует этот параметр для управления поведением анимации.
WinJS так же имеет счетчик, который вы можете использовать для временного включения или выключения анимации в соответствии со значением animationsEnabled. Вы можете изменять его, вызывая WinJS.UI.enableAnimations и WinJS.UI.disableAnimations, их эффект последователен, и свойство animationsEnabled считается равным 0, если параметр Панели управления включен, и 1 – если выключен.
Реализуя собственную анимацию, либо с помощью CSS, либо – с помощью механизмов наподобие setInterval или requestAnimationFrame, правильно будет ориентироваться на установку animationsEnabled там, где это имеет смысл. Я добавил это условие, так как если анимация важна для содержимого приложения, наподобие игры, эта установка к нему не применима. То же самое относится к анимации, наподобие часов в приложении-часах. Это касается анимации, которая добавляет эффект быстроты и подвижности к содержимому, но может быть отключена без потери функциональности приложения.
Рассуждая об использовании анимации в приложении, в первую очередь вы должны принять во внимание библиотеку анимации в WinJA, которую можно найти в пространстве имен ). Каждая анимация представлена в виде функции в данном пространстве имен, которую вы вызываете, если хотите, чтобы включилась определенная анимация или переход. Преимущество использования библиотеки заключаются в том, что она уже воплощает в себе стиль Windows, и, на самом деле, применяется WinJS для анимации встроенных элементов управления, всплывающих элементов и так далее, обеспечивая соответствие пользовательского интерфейса руководствам по дизайну. Более того, так как библиотека построена на основе анимаций и переходов CSS, она независима от WinRT и полностью функциональна на страницах веб-контекста, которые может загружать WinJS (но, опять же, и при работе с такими страницами нужно обращать внимание на настройки воспроиз ведени анимации, описанные в предыдущем разделе).
Все анимации, перечисленные в таблице ниже, имеют руководства, касающиеся того, когда и как их следует использовать. Это, опять же, больше вопрос дизайна, чем реализации, как упомянуто выше. Зная о библиотеке анимации, дизайнеры будут более готовы к тому, чтобы видеть, где могут быть применены анимации и включать их в проект на ранней стадии дизайна приложения, что сделает ваши действия, как разработчика, более предсказуемыми.
Вы можете найти полное руководство в материалах "Анимация пользовательского интерфейса" (http://msdn.microsoft.com/library/windows/apps/hh465165.aspx) и "Анимация пользовательского интерфейса со всплывающими элементами" (http://msdn.microsoft.com/library/windows/apps/hh465259.aspx) в документации, где так же содержатся конкретные руководства по отдельным анимациям, представленным ниже. Здесь я лишь привожу их краткий обзор.
Важный вопрос. Встроенные элементы управления и другие элементы пользовательского интерфейса, наподобие тех, с которыми мы работали ранее, уже используют подходящие анимации. Например, вам не нужно анимировать нажатие на кнопку в элементе button, не нужно анимировать появление или исчезновение элементов наподобие WinJS.UI.AppBar. Вы, в основном, будете использовать анимации, реализуя пользовательский интерфейс непосредственно в HTML-макете, или создавая пользовательские элементы управления.
| Название анимации | Методы WinJS.UI.Animation | Описание и использование |
|---|---|---|
| Переход страницы (Page Transition) | enterPage, exitPage |
Анимирует отображение или прекращение отображения содержимого всей страницы, как в случае перехода на первую страницу приложения после экрана-заставки, так и при переходах между страницами приложения. Избегайте использования
enterPage, когда содержимое уже отображается на экране, то есть, используйте его только тогда, когда полностью меняете содержимое экрана.
|
| Переход содержимого (Content Transition) | enterContent, exitContent |
Анимирует отображение или прекращение отображения одного элемента содержимого или их набора, в частности, используется, когда содержимое не готово к показу, когда страница загружена, или когда часть страницы изменяется внутри контейнера. Если содержимое должно переместиться в ответ на изменение контейнера, как в случае изменения размера, вы можете переместить эти элементы с помощью анимаций разворачивания/сворачивания (expand/collapse) или перемещения (reposition). |
| Появление и исчезновение (Fade In/Out) | fadeIn, fadeOut |
Используется для показа или скрытия промежуточных элементов управления или пользовательского интерфейса, как происходит с полосой прокрутки, или когда элемент-заполнитель заменяется на загруженный элемент. Это так же хороший вариант анимации по умолчанию для ситуаций, в которых другие анимации не применимы. |
| Плавный переход между элементами (Crossfade) | crossFade |
Смягчает переход между различными состояниями элемента. Используется в сценариях обновления, как в случаях, когда приложение для чтения новостей обновляет все свое содержимое за один раз. |
| Касание и отрыв указателя (Pointer Up/Down) | pointerUp, pointerDown |
Предоставляет немедленную обратную связь на успешное касание элемента или плитки или щелчок по ним. Обратите внимание на то, что встроенные элементы управления, такие, как кнопка и ListView уже включают в себя эти анимацию. |
| Разворачивание и сворачивание (Expand/Collapse) | createExpandAnimation,
createCollapseAnimation
|
Добавляет или скрывает дополнительное пространство внутри элемента, например, предоставляя место для сообщения об ошибке или скрывая параметры, в которых нет необходимости. |
| Перемещение (Reposition) | createRepositionAnimation |
Используется для перемещения элемента на новое место. |
| Показ и скрытие всплывающих окон (Show/Hide Popup) | showPopup, hidePopup |
Используется для отображения и скрытия всплывающих элементов интерфейса, таких, как меню, всплывающие окна, подсказки и других контекстно-зависимых элементов, которые появляются поверх рабочей области приложения (диалоговые окна, однако, используют Появление (Fade In)). Старайтесь не использовать для элементов, которые являются частью представления приложения – вместо этого используйте анимации Переход содержимого (Content Transition) и Появление и исчезновение Fade In/Out. Так же, у вас нет необходимости использовать это при работе со встроенными элементами управления, так как они уже применяют необходимые анимации. |
| Показ и скрытие элементов пользовательского интерфейса по краям (Show/Hide Edge UI) Показ и скрытие панелей (Show/Hide Panel UI) | showEdgeUI, hideEdgeUI,
showPanel, hidePanel
|
Используются для показа и скрытия элементов пользовательского интерфейса по краям, наподобие панелей приложения и программной клавиатуры. Анимация элементов интерфейса по краям экрана предназначена для элементов, которые выдвигаются на небольшое расстояние. Анимация показа и скрытия панелей предназначена для тех случаев, когда элементы выдвигаются на большее расстояние.
Эти анимации не следует использовать для элементов пользовательского интерфейса, которые не выдвигаются с края экрана и не задвигаются за край экрана. Вместо этого можно использовать анимацию Перемещение (Reposition ). Анимация Плавный переход между элементами (Crossfade) так же обычно применяется после показа и одновременно со скрытием. Встроенные элементы управления, отображаемые по краям, такие, как панель приложения и панель параметров, уже применяют эту анимацию. |
| Считывание (Для плиток) (Peek (for tiles)) | createPeekAnimation |
Анимирует обновление содержимого плитки при поочередном отображении изображения и текста, смотрите Главу 2 курса "Программная логика приложений для Windows 8, созданных с использованием HTML, CSS и JavaScript и их взаимодействие с системой". Так же можно использовать для циклического отображения данных на плитке. Эта анимация используется для живых плиток на Начальном экране Windows. |
| Обновление индикатора событий (Badge Update) | updateBadge |
Используется для обновления числового индиактора событий на плитке. |
| Подсказка прокрутки (Swipe Hint) | swipeReveal |
Используется в ответ на событие касания и удержания для того, чтобы показать, что элемент может быть выделен прокруткой. |
| Выбор и отмена выбора прокруткой (Swipe Select/Deselect) | swipeSelect, swipeDeselect |
Анимирует элемент при прокрутке для выбора или отмены выбора. |
| Добавление и удаление элементов списка (Add/Delete from List) | createAddToListAnimation,
createDeleteFromListAnimation
|
Анимирует добавление элементов в список или удаление их из списка, в таком качестве используется элементом управления ListView. Анимация добавления сначала переместит существующие элементы списка, чтобы освободить место для новых элементов и затем добавит новые элементы. Анимация удаления из списка убирает элементы из списка и перемещает оставшиеся элементы. Избегайте использования этих энимаций для отображения или удаления контейнера или для добавления или удаления всего содержимого коллекции. Вместо этого используйте Переход содержимого (Content Transition). |
| Добавление и удаление элементов списка поиска (Add/Delete from Search List) | createAddToSearchListAnimation,
createDeleteFromSearchListAnimation
|
Эти анимации похожи на те, которые используются для анимации работы со списком, но они созданы для более быстрого внесения изменений, когда заполняется список результатов поиска. Проще говоря, они имеют меньшую длительность. |
| Начало и окончание перетаскивания или перетаскивание между началом и окончанием (Start/End Drag-Drop) | dragSourceStart, dragSourceEnd,
dragBetweenEnter, dragBetweenLeave
|
Дает визуальную обратную связь во время операции перетаскивания, как на Начальном экране, когда вы перемещаете по нему плитки. Анимации в начале и в конце перетаскивания используются для перемещаемых элементов и их следует всего использовать вместе. Анимации между началом и окончанием используются для подготовки места в потенциальной позиции вставки, что помогает пользователю понять, как будет выглядеть содержимое при помещении элемента в данное место. Для этой цели нужно определить размер потенциальной целевой области (прямоугольную), таким образом вы можете отслеживать перемещения указателя в эти области и из них. |
Если вы хотите увидеть, как работают эти анимации, вы можете найти их все в исходном коде WinJS, в файле iu.js. Просто найдите там методы и вы увидите, как они устроены. Анимация Плавный переход между элементами (Crossfade), например, анимирует прозрачность появляющегося элемента от 0 до 1 в течение 167 мс, с применением линейной функции, у исчезающего элемента прозрачность анимируется таким же образом, но от 1 до 0.
Анимация Касание указателя (Pointer Down) изменяет масштаб элемента со 100% до 97,5% в течение 167 мс, в соответствии с кубической кривой безье, в то время как анимация Отрыв указателя (Pointer Up) выполняет противоположные действия.
Знание этих характеристик, или метрик анимации (animation metrics) важно при создании веб-содержимого для интеграции с вашим приложением. Как отмечено выше, требования к сертификации приложений для Windows 8, в частности, раздел 4.5, показывают, что цели касания должны давать визуальную обратную связь. Так как вы не можете использовать WinJS в удаленных веб-страницах, знание того, как работают эти анимации поможет вам имитировать подобное поведение на таких страницах.
Внутри приложения, однако, вы должны получать метрики анимации программным образом, посредством API в ), вместо того, чтобы задавать какие-либо значения в коде. Вы можете найти демонстрацию использования этого API в примере "Метрики анимации" (http://code.msdn.microsoft.com/windowsapps/animation-metrics-sample-acb0220c).
Как ни интересны были бы подобные подробности, конечно, их всегда можно изменить. В конце концов, самое важное то, чтоб вы выбираете анимации не из-за визуальных эффектов, а основываясь на их смысловом значении, используя нужные анимации в нужное время и в нужном месте. Поэтому давайте посмотрим, как это сделать.
Совет №1. Все анимации WinJS реализованы с использованием функций ) и ), которые вы так же можете использовать для пользовательских анимаций.
Совет №2. При исполнении анимаций всегда избегайте изменения содержимого элемента или его CSS-стилей, которые воздействуют на те же его свойства, что и анимации. Результаты непредсказуемы и ненадежны, и могут приводить к проблемам с производительностью.
Для того, чтобы увидеть все WinJS-анимации в действии, запустите пример "Библиотека анимации HTML" (http://code.msdn.microsoft.com/windowsapps/Using-the-Animation-787f3720). В нем показано очень много разных анимаций, и этот пример, без сомнения, получает награду за самое большое количество сценариев: двадцать два! На самом деле, первое, что вам следует сделать, это перейти в Сценарий 22 и посмотреть, включены ли анимации, так как это, при прочих равных условиях, сильно подействует на то, что вы можете увидеть. В этом сценарии вы увидите, установлен ли флаг UISettings.animationsEnabled, и здесь вы можете увеличить или уменьшить счетчик активности анимации в WinJS. Поэтому взгляните на него прямо сейчас, так как если вы похожи на меня (мне не нравится ждать, пока моя панель задач выдвигается и задвигается), вы могли выключить системные анимации для того, чтобы вам удобнее было работать с рабочим столом. Поначалу я не знал, что эта установка воздействует и на WinJS!
Очевидно, я не буду приводить здесь код каждого из 22 сценариев, на самом деле, делать это необязательно, так как многие из них работают сходным образом. Единственное реальное различие наблюдается между теми, методы которых начинаются с create, и теми, у которых это не так, что мы скоро увидим.
Все методы анимаций возвращают promise-объекты, которые вы можете использовать для того, чтобы предпринять дополнительные действия, когда анимация завершена (здесь будет вызван обработчик завершения). Если вы уже знаете немного о CSS-переходах и анимациях, вы можете верно догадываться, что эти promise-объекты включают в себя события наподобие transitionend и animationend, поэтому вам не нжужно непосредственно прослушивать эти события, если вы хотите объединить анимации в цепочку или синхронизировать. Для объединения в цепочку, вы можете просто объединить в цепочку promise-вызовы, для целей синхронизации вы можете получить promise-объекты для нескольких анимаций и подождать их завершения, используя методы наподобие WinJS.Promise.join или WinJS.Promise.any.
Promise-объекты анимаций, кроме того, поддерживают метод cancel, который убирает анимацию элемента. Этот метод немедленно устанавливает значение свойства, на которое воздействует, в его конечное состояние, что приводит к немедленному видимому переходу элемента в это состояние. И отменили ли вы анимацию, или она сама окончилась, promise-объект решает, что операция успешно завершена. Отмена анимации, другими словами, вызывает обработчик завершения promise-объекта, а не его обработчик ошибки.
Помните, что так как все WinJS-анимации реализованы с помощью CSS, они не начинаются, пока вы не передадите управление обратно в поток пользовательского интерфейса. Это означает, что вы можете настроить несколько анимаций, зная, что они начнутся примерно в одно и то же время, как только вы вернетесь из функции. Поэтому, хотя методы анимации возвращают promise-объекты, они не похожи на другие асинхронные операции WinRT, которые начинают исполняться в другом потоке.
В любом случае, давайте взглянем на код! В самом простом случае все, что вам нужно сделать – это вызвать один из методов анимации и анимация будет исполнена, когда вам нужно. Сценарий 6 примера, например, просто добавляет следующие обработчики к событиям MSPointerDown и MSPointerUp трех разных элементов (js/pointerFeedback.js):
function onPointerDown(evt) { WinJS.UI.Animation.pointerDown(evt.srcElement);
}
function onPointerUp(evt) { WinJS.UI.Animation.pointerUp(evt.srcElement);
}
Нам обычно не нужно что-либо делать, когда анимация завершится, поэтому нам не нужно вызывать done или предоставлять завершающую функцию. На самом деле, использование многих из анимаций так же просто.
Анимация crossFade, в свою очередь (Сценарий 10), работает с двумя элементами: появляющимся и исчезающим (все они должны быть видимыми и являться частями DOM в процессе анимации, учтите!). Вызов анимации выглядит так: (js/crossfade.js):
WinJS.UI.Animation.crossFade(incoming, outgoing);
Но это еще не все. Обычная возможность анимаций заключается в том, что вы можете предоставить массив элементов, на которых должна быть исполнена одна и та же анимация, или, в случае с crossfade, два массива элементов. В то время, как это не особенно удобно для анимаций наподобие pointerDown и pointerUp (каждое событие указателя следует обрабатывать независимо), это, без сомнения, удобно для большинства остальных.
Рассмотрим анимацию enterPage. В своей единственной форме она принимает элемент для анимации и необязательное начальное смещение, где должен находиться элемент по отношению к своей конечной позиции. (Вообще говоря, вы вам следует опустить это смещение, если оно вам не нужно, так как это улучшает производительность – в примере туда передается null, что я опустил в нижеприведенном коде). Анимация enterPage так же может принимать коллекцию элементов, такую, как результат работы querySelectorAll. Сценарий 1 (html/enterPage.html и js/enterPage.js) предоставляют возможность выбора того, сколько элементов нужно анимировать раздельно:
switch (pageSections) {
case "1":
// Анимировать всю страницу
enterPage = WinJS.UI.Animation.enterPage(rootGrid);
break;
case "2":
// Анимировать заголовок и тело страницы
enterPage = WinJS.UI.Animation.enterPage([[header, featureLabel], [contentHost, footer]]);
break;
case "3":
// Анимировать заголовок, области ввода и вывода
enterPage = WinJS.UI.Animation.enterPage([[header, featureLabel], [inputLabel, input], [outputLabel, output, footer]]);
break;
}
В то время, как аргумент элемента – это массив, аргумент смещения, если он задан, может быть либо отдельным смещением, которое применяется ко всем элементам, либо массивом, задающим отдельные смещения для каждого элемента. Каждое смещение – это объект, свойства которого определяют смещение. Смотрите js/dragBetween.js для Сценария 13, где этот подход используется с анимацией dragBetweenEnter:
WinJS.UI.Animation.dragBetweenEnter([box1, box2],
[{ top: "-40px", left: "0px" }, { top: "40px", left: "0px" }]);
Вот модификация, где одно и то же смещение применяется к обоим элементам:
WinJS.UI.Animation.dragBetweenEnter([box1, box2], { top: "0px", left: "40px" });
Сценарий 4 (js/transitioncontent.js) показывает, как вы можете объединить в цепочку два promise-объекта для выполнения перехода между двумя различными блоками содержимого:output передается в качестве первого параметра в
exitContent и enterContent. код должен выглядеть как показано здесь, с outgoing, который передается в exitContent и incoming, который передается в enterContent.
WinJS.UI.Animation.exitContent(outgoing, null).done( function () {
outgoing.style.display = "none";
incoming.style.display = "block";
return WinJS.UI.Animation.enterContent(incoming, null);
});
Происходящее становится немного интереснее, когда мы посмотрим в методы анимации create*, которые касаются так называемой анимации макета (layout animation), для выполнения добавления и удаления элементов в списке, разворачивания и сворачивания содержимого и так далее. Каждый из них предусматривает трехступенчатую обработку, где вы создаете анимацию, выполняете манипуляции с DOM, и затем исполняете анимацию, как показано в Сценарии 7 (js/addAndDeleteFromList.js):
// Создать анимацию addToList. var addToList = WinJS.UI.Animation.createAddToListAnimation(newItem, affectedItems); // Вставить новый элемент в дерево DOM. Элементы, на которые это повлияло, поменяют положение. list.insertBefore(newItem, list.firstChild); // Исполнить анимацию. addToList.execute();
Причина для трехступенчатой обработки заключается в применении анимацию к только что добавленному элементу, или элементу, который убирают из списка, всем им нужно присутствовать в DOM во время исполнения анимации. Такой порядок работы позволяет вам создавать анимацию на основе начального состояния содержимого, манипулировать DOM (или просто устанавливать стили, и так далее) для создания конечного состояния и затем исполнять анимацию, позволив всему встать на свои места. Вы затем можете использовать метод done promise-объекта, возвращенного из execute для выполнения любой окончательной обработки. Сценарий 5 (js/expandAndCollapse.js) разьясняет это:
// Создание анимации сворачивания.
var collapseAnimation = WinJS.UI.Animation.createCollapseAnimation(element, affected);
// Удаляем сворачивающийся элемент из содержимого документа, таким образом, зависимые элементы меняют
// положение. Не удаляйте сворачиваемый элемент из DOM и не скрывайте его в данный момент, в противном случае
// анимация этого элемента не будет выполнена.
element.style.position = "absolute";
element.style.opacity = "0";
// Исполнение анимации сворачивания.
collapseAnimation.execute().done(
// После завершения анимации (или если произошла ошибка), скрываем элемент.
function () { element.style.display = "none"; },
function () { element.style.display = "none"; }
);
В качестве последнего примера, так как я знаю, что вы достаточно сообразительны для того, чтобы самостоятельно посмотреть другие варианты, хочу показасть Сценарий 21 (js/customAnimation.js). Здесь показано, как использовать методы WinJS.UI.executeAnimation и WinJS.UI.executeTransition:
function runCustomShowAnimation() {
var showAnimation = WinJS.UI.executeAnimation(
target,
{
// Обратите внимание: этот ключевой кадр относится к ключевому кадру, определенному в customAnimation.css.
// Если он не определен в CSS, анимация не будет работать.
keyframe: "custom-opacity-in",
property: "opacity",
delay: 0, duration: 500,
timing: "linear", from: 0,
to: 1
}
);
}
function runCustomShowTransition() {
var showTransition = WinJS.UI.executeTransition(
target,
{
property: "opacity", delay: 0,
duration: 500,
timing: "linear", to: 1
}
);
}
Если вы хотите объединить несколько анимаций (как делается во многих анимациях WinJS), отметим, что обе эти функции возвращают promise-объекты, в итоге, вы можете комбинировать несколько результатов с помощью WinJS.Promise.join и использовать один обработчик завершения, который выполняет пост-обработку. Это именно то, что происходит внутри WinJS.
И если вы уже знаете что-либо о CSS-анимациях и переходах, вы, возможно, можете сказать, что объекты, которые вы передаете executeAnimation и executeTransition – это просто краткие наименования стилей CSS, которые вы используете. Коротко говоря, эти методы дают вам простой способ создавать собственные пользовательские анимации и переходы, пользуясь возможностями CSS. Посмотрим сейчас непосредственно на эти возможности.
Разработчики часто спрашивают, как создать параллактическую или панорамную анимацию фона, как на Начальном экране Windows. Если вы не знакомы с этой концепцией, перейдите на Начальный экран и прокрутите его, обращая внимание на то, что фон так же прокручивается, но медленнее, чем плитки. Это создает ощущение, будто плитки плавают над фоном.
Хотя в JavaScript можно реализовать подобный эффект (смотрите пример "KidBook" (http://ie.microsoft.com/testdrive/HTML5/KidsBook/Default.html) на сайте Internet Explorer TestDrive), мы не рекомендуем этого делать, или, по крайней мере, рекомендуем предусмотреть параметр, позволяющий отключить его. Речь идет о том, что особенности работы с потоками и модель отрисовки в JavaScript могут привести к прерывистым перемещениям, за исключением работы подобной анимации на мощных устройствах. Этот эффект будет ярко выражен на маломощных компьютерах, особенно на ARM-устройствах. Кроме того, подобная анимация может потреблять слишком много ресурсов процессора и нерационально использовать батареи.
Это – один из случаев, где использование C++ и DirectX (или даже C#/VB и XAML) имеет явное преимущества перед JavaScript, и это нужно принять во внимание, если подобный эффект в вашем приложении абсолютно необходим.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.