Этот туториал покажет, как создать горизонтально прокручиваемый просмотрщик изображений. Он будет охватывать анализ XML, загрузку и изменение размера внешних изображений, а также создание интуитивно понятной и гибкой прокрутки!
Краткое введение
Я твердо верю в обучение с помощью кодирования и мастеринга. Итак, в этом уроке я говорю, что делать, а затем показываю эквивалентный код; пожалуйста, копайтесь в коде, меняйте вещи и работайте — я думаю, что это один из лучших способов учиться! Я ожидаю, что у вас уже есть базовое понимание ActionScript, и я не буду объяснять основы. Я надеюсь, что описания будут полезны, но если я не объясню то, что вы не совсем читаете, не стесняйтесь спрашивать об этом в комментариях.
Шаг 1. Настройка XML
Мы хотим, чтобы узлы изображений были включены в наш xml. Каждый узел будет представлять изображение с атрибутами. Здесь мы можем добавить все, что захотим, я буду придерживаться трех атрибутов для каждого узла изображения. ‘Src’ изображения (используется для его загрузки), заголовок и URL, на который мы будем ссылаться из скроллера. Я продолжу и оберну их все в узле изображений (на случай, если позже я захочу включить что-нибудь еще в xml, например, параметры настройки — подсказка).
Каждому узлу изображения понадобится исходное изображение, заголовок и URL. Источником (src) будет изображение, которое загружается в скроллер, заголовок будет тем, что мы называем им, и URL будет URL-адрес, который мы загружаем из скроллера, когда пользователи нажимают на изображение (это может быть увеличенное изображение). или даже сайт). Я получил несколько изображений из библиотеки ресурсов envato и изменил их размеры, чтобы использовать их в качестве эскизов. Я сжал миниатюры, чтобы уместить их в область 140 на 105 пикселей, это не обязательно, но поможет оптимизировать процесс, поскольку мы не будем загружать большие изображения. Скоро вы увидите, что изображение любого размера будет работать, потому что мы закодируем его, чтобы изменить размер любого изображения, которое загружается, чтобы поместиться в область прокрутки!
<изображения> <image src = "images / tn / scottwills_underwater4.jpg" title = "Jelly 4" url = "images / scottwills_underwater4.jpg" /> <image src = "images / tn / scottwills_cat.jpg" title = "Кошка" url = "images / scottwills_cat.jpg" /> <image src = "images / tn / scottwills_modern_sculpture.jpg" title = "Статуя" url = "images / scottwills_modern_sculpture.jpg" /> <image src = "images / tn / madness_arch3.jpg" title = "Arch 3" url = "images / madness_arch3.jpg" /> <image src = "images / tn / scottwills_penguin.jpg" title = "Пингвин" url = "images / scottwills_penguin.jpg" /> <image src = "images / tn / scottwills_horse.jpg" title = "Jelly" url = "images / scottwills_horse.jpg" /> <image src = "images / tn / scottwills_modernsculpture2.jpg" title = "Статуя 2" url = "images / scottwills_modernsculpture2.jpg" /> <image src = "images / tn / madness_arch1.jpg" title = "Arch 1" url = "images / madness_arch1.jpg" /> <image src = "images / tn / madness_arch2.jpg" title = "Arch 2" url = "images / madness_arch2.jpg" /> </ Изображений>
Шаг 2: Настройте Flash
Хорошо, теперь, когда мы закончили работу с нашим XML-файлом, давайте начнем с Flash. Откройте Flash и создайте новый файл (ActionScript 3.0). Отрегулируйте размер сцены примерно до 600 в ширину и 150 в высоту, установите фон на любой понравившийся вам цвет (я выбрал темный цвет, чтобы изображения немного выделялись — # 000033, если вы хотите следовать), и увеличьте рамку Оцените 30 кадров в секунду, чтобы дать нам более плавную анимацию. Тогда давайте продолжим и создадим новый слой с именем «ActionScript». На первом кадре на временной шкале нажмите на панель действий, и мы готовы продолжить!
Шаг 3: Загрузите XML
Нам нужно загрузить информацию из XML-файла (созданного на шаге 1) в наш Flash-файл. Это довольно простой шаг, но фундамент, который может появиться во многих других творческих приложениях. Всего за несколько строк кода мы инициализируем URLLoader, объект XML для хранения наших данных и строку для указания пути к xml. Затем мы загружаем xml через объект urlLoader. Для этого нам нужно, чтобы прослушиватель событий срабатывал при полной загрузке файла, и нам не хотелось бы начинать связываться с данными xml до того, как он завершит загрузку. Как указано в документации, событие complete передает загруженный контент как свойство данных цели события, поэтому мы получаем доступ к фактическому xml как e.target.data и присваиваем его нашему объекту xml.
Давайте продолжим и перепроверим, что мы все настроили правильно, и проследим узлы изображения нашего xml на панели вывода.
// загрузить xml var xmlLoader: URLLoader = new URLLoader (); var xmlData: XML = new XML (); var xmlPath: String = "image-scroller.xml"; xmlLoader.load (новый URLRequest (xmlPath)); trace ("загрузка xml из:" + xmlPath); xmlLoader.addEventListener (Event.COMPLETE, LoadXML); функция LoadXML (e: Event): void { трассировка («загрузка xml завершена»); xmlData = новый XML (e.target.data); проследить (xmlData.image); // мы увидим каждый элемент xml изображения, указанный на панели вывода с этим xmlList } / * окно вывода /////////////// загрузка xml из: image-scroller.xml загрузка xml завершена <image src = "images / tn / scottwills_underwater4.jpg" title = "Jelly 4" url = "images / scottwills_underwater4.jpg" /> <image src = "images / tn / scottwills_cat.jpg" title = "Кошка" url = "images / scottwills_cat.jpg" /> <image src = "images / tn / scottwills_modern_sculpture.jpg" title = "Статуя" url = "images / scottwills_modern_sculpture.jpg" /> <image src = "images / tn / madness_arch3.jpg" title = "Arch 3" url = "images / madness_arch3.jpg" /> <image src = "images / tn / scottwills_penguin.jpg" title = "Пингвин" url = "images / scottwills_penguin.jpg" /> <image src = "images / tn / scottwills_horse.jpg" title = "Jelly" url = "images / scottwills_horse.jpg" /> <image src = "images / tn / scottwills_modernsculpture2.jpg" title = "Статуя 2" url = "images / scottwills_modernsculpture2.jpg" /> <image src = "images / tn / madness_arch1.jpg" title = "Arch 1" url = "images / madness_arch1.jpg" /> <image src = "images / tn / madness_arch2.jpg" title = "Arch 2" url = "images / madness_arch2.jpg" /> * /
Шаг 4: Разбор XML
Загрузка XML — это здорово, но мы также должны прочитать ее и сообщить нашему коду, что делать с данными. Поэтому вместо того, чтобы просто отследить xmlList, мы отправим его другой функции, которая позаботится о создании нашего скроллера. Функция buildScroller примет XMLList, поэтому мы пройдемся по нему, создавая объекты фрагмента ролика для каждого изображения в скроллере и назначая им свойства в соответствии с атрибутами xml узла title, url и src. Позже мы создадим эту функцию, которая будет включать в себя намного больше, чтобы она фактически выполняла то, для чего она названа, и собирала скроллер!
А пока давайте просто проследим эту информацию, чтобы убедиться, что все работает в соответствии с планом. Мы можем даже обернуть функцию buildScroller с помощью операторов трассировки, чтобы мы всегда знали, где мы находимся.
// загрузить xml var xmlLoader: URLLoader = new URLLoader (); var xmlData: XML = new XML (); var xmlPath: String = "image-scroller.xml"; xmlLoader.load (новый URLRequest (xmlPath)); trace ("загрузка xml из:" + xmlPath); xmlLoader.addEventListener (Event.COMPLETE, LoadXML); функция LoadXML (e: Event): void { трассировка («загрузка xml завершена»); xmlData = новый XML (e.target.data); buildScroller (xmlData.image); // вместо того, чтобы отслеживать xmlList, мы отправляем его в нашу функцию buildScroller } // построить скроллер из xml Функция buildScroller (imageList: XMLList): void { трассировка («сборка скроллера»); for (var item: uint = 0; item <imageList.length (); item ++) { var thisOne: MovieClip = new MovieClip (); thisOne.itemNum = item; thisOne.title = imageList [item] .attribute ("title"); thisOne.link = imageList [item] .attribute ("url"); thisOne.src = imageList [item] .attribute ("src"); trace (thisOne.itemNum, thisOne.title, thisOne.link, thisOne.src); } трассировка («завершение построения скроллера»); } / * выход /////// загрузка xml из: image-scroller.xml загрузка xml завершена построить скроллер 0 Jelly 4 images / scottwills_underwater4.jpg images / tn / scottwills_underwater4.jpg 1 изображение кошки / scottwills_cat.jpg images / tn / scottwills_cat.jpg 2 Статуя images / scottwills_modern_sculpture.jpg images / tn / scottwills_modern_sculpture.jpg 3 Arch 3 images / madness_arch3.jpg images / tn / madness_arch3.jpg 4 изображения пингвинов / scottwills_penguin.jpg images / tn / scottwills_penguin.jpg 5 изображений желе / scottwills_horse.jpg images / tn / scottwills_horse.jpg 6 Статуя 2 изображения / scottwills_modernsculpture2.jpg images / tn / scottwills_modernsculpture2.jpg 7 Arch 1 images / madness_arch1.jpg images / tn / madness_arch1.jpg 8 Arch 2 images / madness_arch2.jpg images / tn / madness_arch2.jpg прекращение сборки скроллера * /
Шаг 5: Постройте скроллер MovieClip, чтобы содержать каждое изображение
Теперь, когда функция прокрутки сборки создана и она создает объекты для каждого узла в XML, давайте добавим их на сцену!
Начнем с создания скроллера MovieClip. Это будет контейнер для всех объектов, которые мы хотим прокрутить, поэтому каждый узел изображения будет иметь мувиклип в этом объекте прокрутки. Давайте продолжим и добавим его на сцену, а затем установим значение y на 30. При тестировании мы пока ничего не увидим на сцене, но мы собираемся добавить элементы в скроллер для каждого изображения в xmlList.
var scroller: MovieClip = new MovieClip (); this.addChild (скроллер); scroller.y = 30;
Шаг 6: Добавление предметов в скроллер
У нас уже есть мувиклипы, созданные со свойствами, но нам нужно создать что-то, что мы можем видеть, поэтому давайте создадим область блока, чтобы фактически видеть эти элементы скроллера. Создайте спрайт BlackBox и придайте ему форму с графическим интерфейсом API. Я решил, что хочу, чтобы мой стандартный элемент прокрутки был размером 140×105 пикселей, поэтому я создам черный ящик, чтобы он соответствовал этой области, и я поставлю ему границу в 1 пиксель со всех сторон. Переместите его вверх и влево на один пиксель и дайте ему размеры 142×107.
Мы добавляем спрайт черного ящика в мувиклип thisOne, а также обновляем значение x элемента. Поскольку каждый будет иметь ширину 140, я добавлю несколько отступов (20) и выложу их горизонтально. Я обновлю инструкцию trace, чтобы вывести то, что здесь происходит.
var scroller: MovieClip = new MovieClip (); this.addChild (скроллер); scroller.y = 30; // построить скроллер из xml Функция buildScroller (imageList: XMLList): void { трассировка («сборка скроллера»); for (var item: uint = 0; item <imageList.length (); item ++) { var thisOne: MovieClip = new MovieClip (); //контур var blackBox: Sprite = новый Sprite (); blackBox.graphics.beginFill (0xFFFFFF); blackBox.graphics.drawRect (-1, -1, 142, 107); thisOne.addChild (BlackBox); thisOne.x = (140 + 20) * пункт; thisOne.itemNum = item; thisOne.title = imageList [item] .attribute ("title"); thisOne.link = imageList [item] .attribute ("url"); thisOne.src = imageList [item] .attribute ("src"); trace (thisOne.itemNum, thisOne.title, «добавлено в скроллер»); //Добавьте предмет scroller.addChild (thisOne); } трассировка («завершение построения скроллера»); } / * выход /////// загрузка xml из: image-scroller.xml загрузка xml завершена построить скроллер 0 Желе 4 добавлено в скроллер 1 кот добавлен в скроллер 2 Статуя добавлена в скроллер 3 Arch 3 добавлено в скроллер 4 Пингвин добавлен в скроллер 5 Желе добавлено в скроллер 6 Статуя 2 добавлена в скроллер 7 Arch 1 добавлен в скроллер 8 Arch 2 добавлено в скроллер прекращение сборки скроллера * /
Шаг 7: добавление Click Listener к элементам
Хорошо, это не так много, потому что это выглядит как куча коробок, которые ничего не делают. Давайте добавим слушателя к этим полям, чтобы мы могли сказать, что каждый из них является уникальным элементом в скроллере. Думая об окончательном результате, мы добавим прослушиватель кликов, потому что мы хотим, чтобы пользователи могли щелкнуть элемент в скроллере и перейти по ссылке, которую мы поместили в xml. Давайте сделаем клик buttonMode истинным, чтобы он воспринимался как что-то, что можно кликать. Затем добавьте прослушиватель событий для MouseEvent.CLICK. Пока что мы просто прослушаем это событие click и запустим функцию, чтобы отследить URL, на который мы нацелены.
Через вывод мы видим, что у каждого ящика есть свойства, отправленные ему из xml.
// построить скроллер из xml Функция buildScroller (imageList: XMLList): void { трассировка («сборка скроллера»); for (var item: uint = 0; item <imageList.length (); item ++) { var thisOne: MovieClip = new MovieClip (); //контур var blackBox: Sprite = новый Sprite (); blackBox.graphics.beginFill (0xFFFFFF); blackBox.graphics.drawRect (-1, -1, 142, 107); thisOne.addChild (BlackBox); thisOne.x = (140 + 20) * пункт; thisOne.itemNum = item; thisOne.title = imageList [item] .attribute ("title"); thisOne.link = imageList [item] .attribute ("url"); thisOne.src = imageList [item] .attribute ("src"); // создаем слушателей для этого элемента thisOne.buttonMode = true; thisOne.addEventListener (MouseEvent.CLICK, clickScrollerItem); //Добавьте предмет scroller.addChild (thisOne); } трассировка («завершение построения скроллера»); } function clickScrollerItem (e: MouseEvent): void { trace («нажатый элемент» + e.currentTarget.itemNum + »- URL-адрес посещения:« + e.currentTarget.link); } / * выход ////// загрузка xml из: image-scroller.xml загрузка xml завершена построить скроллер прекращение сборки скроллера щелкнул пункт 2 - посетите URL: images / scottwills_modern_sculpture.jpg щелкнул элемент 0 - посетите URL: images / scottwills_underwater4.jpg щелкнул элемент 1 - посетите URL: images / scottwills_cat.jpg щелкнул пункт 3 - посетите URL: images / madness_arch3.jpg щелкнул элемент 1 - посетите URL: images / scottwills_cat.jpg * /
Шаг 8: Добавление большего количества слушателей к элементам скроллера
Давайте добьем слушателей мероприятия! Мы хотим прослушать каждый из этих пунктов, чтобы знать, когда пользователь щелкает мышью и мышкой.
// построить скроллер из xml Функция buildScroller (imageList: XMLList): void { трассировка («сборка скроллера»); for (var item: uint = 0; item <imageList.length (); item ++) { var thisOne: MovieClip = new MovieClip (); //контур var blackBox: Sprite = новый Sprite (); blackBox.graphics.beginFill (0xFFFFFF); blackBox.graphics.drawRect (-1, -1, 142, 107); thisOne.addChild (BlackBox); thisOne.x = (140 + 20) * пункт; thisOne.itemNum = item; thisOne.title = imageList [item] .attribute ("title"); thisOne.link = imageList [item] .attribute ("url"); thisOne.src = imageList [item] .attribute ("src"); // создаем слушателей для этого большого пальца thisOne.buttonMode = true; thisOne.addEventListener (MouseEvent.CLICK, clickScrollerItem); thisOne.addEventListener (MouseEvent.MOUSE_OVER, overScrollerItem); thisOne.addEventListener (MouseEvent.MOUSE_OUT, outScrollerItem); //Добавьте предмет scroller.addChild (thisOne); } трассировка («завершение построения скроллера»); } function clickScrollerItem (e: MouseEvent): void { trace («нажатый элемент» + e.currentTarget.itemNum + »- URL-адрес посещения:« + e.currentTarget.link); } function overScrollerItem (e: MouseEvent): void { trace ("over" + e.currentTarget.title); } function outScrollerItem (e: MouseEvent): void { trace ("out" + e.currentTarget.title); } /* выход ////////////// загрузка xml из: image-scroller.xml загрузка xml завершена построить скроллер прекращение сборки скроллера над желе 4 из желе 4 над котом из кота над статуей вне Статуя над аркой 3 Арка 3 над аркой 3 щелкнул пункт 3 - посетите URL: images / madness_arch3.jpg Арка 3 над статуей щелкнул пункт 2 - посетите URL: images / scottwills_modern_sculpture.jpg вне Статуя * /
Шаг 9: загрузка и добавление изображений
Теперь часть, которая, я уверен, вас беспокоит, давайте загрузим изображения в элементы скроллера, чтобы мы могли видеть, что они собой представляют! Мы сделаем это в функции buildScroller. Сразу после создания черного ящика и назначения свойств для текущего элемента давайте также создадим еще один спрайт, который будет содержать фактическое изображение.
Мы будем использовать объект загрузчика и объект URLRequest для обработки загрузки изображения, которая вновь стандартизирована с помощью ActionScript 3. Мы передадим src изображения в объект urlrequest, затем загрузим urlrequest с нашим объектом загрузчика и наконец, мы добавим загрузчик в спрайт thisThumb, добавив его по очереди в мувиклип thisOne. Уф.
Это говорит само за себя — и всего за пару строк кода мы загрузили изображения src из нашего xml во Flash!
Функция buildScroller (imageList: XMLList): void { трассировка («сборка скроллера»); for (var item: uint = 0; item <imageList.length (); item ++) { var thisOne: MovieClip = new MovieClip (); //контур var blackBox: Sprite = новый Sprite (); blackBox.graphics.beginFill (0xFFFFFF); blackBox.graphics.drawRect (-1, -1, 142, 107); thisOne.addChild (BlackBox); thisOne.x = (140 + 20) * пункт; thisOne.itemNum = item; thisOne.title = imageList [item] .attribute ("title"); thisOne.link = imageList [item] .attribute ("url"); thisOne.src = imageList [item] .attribute ("src"); // контейнер изображения var thisThumb: Sprite = new Sprite (); // добавить изображение var ldr: Loader = новый Loader (); var urlReq: URLRequest = новый URLRequest (thisOne.src); trace («загрузка эскиза» + item + «в Scroller:« + thisOne.src); ldr.load (urlReq); thisThumb.addChild (LDR); thisOne.addChild (thisThumb); // создаем слушателей для этого большого пальца thisOne.buttonMode = true; thisOne.addEventListener (MouseEvent.MOUSE_OVER, overScrollerItem); thisOne.addEventListener (MouseEvent.MOUSE_OUT, outScrollerItem); thisOne.addEventListener (MouseEvent.CLICK, clickScrollerItem); //Добавьте предмет scroller.addChild (thisOne); } трассировка («завершение построения скроллера»); }
Шаг 10. Добавление прослушивателей событий в процесс загрузки изображений.
Когда мы загружаем изображения, нам нужно создать слушателей событий, которые сообщат нам, когда загрузка будет завершена. Лучшие практики работают с любыми ошибками (в случае опечатки на пути к изображению или если у нас нет доступа или чего-то еще). Поэтому перед загрузкой изображений давайте добавим прослушиватель событий для объекта contentLoaderInfo загрузчика для завершенного события, а также для ошибки ввода-вывода. Затем нам нужно создать функции обработчика событий.
Для completeHandler давайте на данный момент просто проследим заголовок изображения, нам нужно пройти вверх по иерархии заголовка родительского объекта цели события, чтобы найти его, из-за способа, которым мы вложили наш спрайт в объекты нашего элемента скроллера (thisOne Sprite) ,
trace («загрузка миниатюры» + item + «в Scroller:« + url); // назначаем прослушиватели событий для Loader ldr.contentLoaderInfo.addEventListener (Event.COMPLETE, completeHandler); ldr.contentLoaderInfo.addEventListener (IOErrorEvent.IO_ERROR, errorHandler); ldr.load (urlReq); ... function completeHandler (e: Event): void { трассировка («миниатюра завершена» + e.target.loader.parent.parent.title); } function errorHandler (e: IOErrorEvent): void { trace ("thumbnail error =" + e); }
Шаг 11: скручивание изображений
Я использую Tweener для этого урока, но есть разные твининг-движки. Если вы не знакомы с этим
Tweener (caurina.transitions.Tweener) — это класс, используемый для создания анимаций и других переходов с помощью кода ActionScript для проектов, созданных на платформе Flash … С точки зрения непрофессионала, Tweener помогает перемещать объекты на экране, используя только код вместо график
Поэтому сначала загрузите его из репозитория кода Google (обязательно получите версию as3), разархивируйте его и поместите папку caurina в тот же каталог, что и ваш .fla файл, затем импортируйте код в свой проект, поместив его в первую строку кода:
импорт caurina.transitions. *;
Тогда давайте заставим изображения исчезать, как только они загружены, вместо того, чтобы просто выскочить, как они. Сначала мы установим начальное альфа-значение элемента прокрутки на 0, чтобы оно могло правильно отображаться. Затем вернитесь к нашей полной функции обработчика событий прослушивателя и добавьте код Tweener.
thisOne.alpha = 0; ... function completeHandler (e: Event): void { // trace ("thumbnail complete" + e.target.loader.parent.parent.title); Tweener.addTween (e.target.loader.parent.parent, {alpha: 1, time: .5}); }
Шаг 12: Изменение размера изображений
Теперь, так как я предварительно изменил размеры всех своих изображений и создал миниатюры, этот шаг не так важен, но все же его очень удобно включать, чтобы в случае изменения размеров или добавления другого изображения позже, скроллер смог обработать его и изменить размер. Это. Функция изменения размера позволяет масштабировать изображение, чтобы оно поместилось в пределах области, как я объяснял ранее в своем блоге . В основном, хотя, в completeHandler мы изменим размер изображения, чтобы оно соответствовало области, даже если изображение имеет правильный размер, функция resizeMe все равно будет центрировать изображение для нас.
function completeHandler (e: Event): void { // trace ("thumbnail complete" + e.target.loader.parent.parent.name); // размер изображения в скроллере resizeMe (e.target.loader.parent, 140, 105, true, true, false); Tweener.addTween (e.target.loader.parent.parent, {alpha: 1, time: .5}); } // Функция изменения размера // параметры // требуется: mc = мувиклип для изменения размера // required: maxW = либо размер поля для изменения размера, либо просто максимальная желаемая ширина // необязательно: maxH = при желании область изменения размера не квадрат, а максимальная желаемая высота. по умолчанию соответствует maxW (поэтому, если вы хотите изменить размер до 200x200, просто отправьте 200 один раз или resizeMe (изображение, 200);) // необязательно: constrainProportions = boolean, чтобы определить, хотите ли вы ограничить пропорции или наклонить изображение. по умолчанию true. // необязательно: centerHor = центрирует displayObject в области maxW. по умолчанию true. // необязательно: centerVert = центрирует displayObject в области maxH. по умолчанию true. Функция resizeMe (mc: DisplayObject, maxW: Number, maxH: Number = 0, constrainProportions: Boolean = true, centerHor: Boolean = true, centerVert: Boolean = true): void { maxH = maxH == 0? maxW: maxH; mc.width = maxW; mc.height = maxH; if (constrainProportions) { mc.scaleX <mc.scaleY? mc.scaleY = mc.scaleX: mc.scaleX = mc.scaleY; } if (centerHor) { mc.x = (maxW - mc.width) / 2; } if (centerVert) { mc.y = (maxH - mc.height) / 2; } }
Шаг 13: Добавление движения
Мы начнем с простого добавления основ. Мы хотим, чтобы пользователи могли интуитивно управлять этим скроллером, поэтому мы будем использовать их положение мыши только в качестве направления. Если мышь расположена в левой половине сцены, мы хотим переместить скроллер вправо, поэтому пользователь перемещается в направлении, в котором он хочет, чтобы скроллер раскрылся. Я предпочитаю это прямому отношению перемещения скроллера так же, как движется мышь, но это обсуждение другого дня.
Чтобы реализовать это довольно просто, мы просто добавляем прослушиватель событий в конце функции buildScroller, каждый раз, когда вводим фрейм для позиционирования скроллера. Затем в функции обработчика мы создадим оператор if / else и установим новую переменную скорости в зависимости от положения мыши. Если позиция мыши x находится в левой половине сцены, мы хотим, чтобы скроллер двигался в одну сторону, а если он находится в правой половине сцены, мы хотим, чтобы он двигался в другом направлении. Затем мы применяем эту скорость к позиции х контейнера скроллера. Теперь это начинает выглядеть как нечто полезное, потому что теперь оно интерактивное и отзывчивое!
По сути, все, что мы делаем, это перемещаем клип контейнера скроллера в одно направление другого, но мы делаем это каждый кадр, поэтому он анимирует положение с течением времени. Помните, что этот скроллер содержит все элементы, которые мы создали, так что это все равно, что положить вещи в коробку и переместить коробку. Предметы не должны быть перемещены, только контейнер! Мы перемещаем его либо на 5 пикселей влево, либо на 5 пикселей влево на каждый кадр (эти 5 могут быть любыми, я просто выбрал 5, потому что он выглядел правильно). Это оставляет желать лучшего, но это первый шаг. У нас есть движущийся скроллер, и мы дали конечному пользователю возможность контролировать это движение!
Обратите внимание, что мы используем свойства сцены, чтобы найти размер сцены, даже если мы установили размер сцены раньше и точно знаем, какой это размер. Это потому, что это поможет коду быть автономным и переносимым. Если бы мы использовали фактические значения, нам пришлось бы помнить об их обновлении, если мы когда-либо изменяли размер скроллера или хотели использовать это в другом приложении. Скоро мы создадим больше переменных, которые позволят нам полностью настроить взаимодействие с прокруткой.
scroller.addEventListener (Event.ENTER_FRAME, moveScrollerThumbs); трассировка («завершение построения скроллера»); ... переменная скорость: число; function moveScrollerThumbs (e: Event): void { if (mouseX <stage.stageWidth / 2) {// левая половина этапа скорость = 5; } else {// правая половина этапа скорость = -5; } scroller.x + = скорость; }
Шаг 14: Лучшее движение — пределы мыши
Вы можете видеть выше, что у нас все еще есть способ управления прокруткой. Есть границы, которые нужно добавить к позициям мыши, которые вызывают прокрутку (мы хотели бы, чтобы она прокручивалась только тогда, когда вы находитесь на сцене и над скроллером), ограничения, которые мы хотели бы применить к скроллеру (чтобы он не t), и мы хотим, чтобы скорость прокрутки была динамичной.
Давайте начнем с добавления оператора, чтобы проверить, не перешли ли мы на скроллер. Для этого мы проверим положение mouseY, свойства scroller.y и scroller.height. Давайте также добавим немного больше к операторам mouseX, давайте удостоверимся, что это немного более точно и включает только значения x от 0 до центра сцены (stage.stageWidth / 2) и от центра до края.
function moveScrollerThumbs (e: Event): void { if (mouseY> scroller.y && mouseY <scroller.y + scroller.height) {// вертикально над скроллером if (mouseX <stage.stageWidth / 2 && mouseX> 0) {// явно левая половина этапа скорость = 5; } else if (mouseX> stage.stageWidth / 2 && mouseX <stage.stageWidth) {// явно правая половина этапа скорость = -5; } scroller.x + = скорость; } }
Шаг 15: Лучшее движение — пределы скроллера
Теперь мы хотим применить границы к самому скроллеру, чтобы он не прокручивался со страницы и оставил нас с пустым этапом и пользователем, который не знает и не помнит, как проходили изображения.
Нам нужно следить за положением скроллера x и, если он зайдет слишком далеко, сбросить его до нашего предела. Помните, что положение скроллера x находится у его левого края, поэтому, когда оно находится в положении 0 x, оно находится на одном уровне с левым краем сцены. Итак, во-первых, если позиция x скроллера больше 0 после того, как скорость рассчитана и применена, мы хотим вернуть ее к нашему пределу 0. Это будет препятствовать движению скроллера слишком далеко в сцену. Мы даже можем добавить некоторые отступы к сцене, и так как у нас есть заполнение между каждым элементом прокрутки по 20, давайте сделаем это согласованным. Вместо того, чтобы использовать 0 здесь, давайте сделаем то же самое значение 20.
Мы хотим, чтобы скроллер прекратил двигаться влево, когда его последний элемент полностью на сцене. Этот левый предел можно найти, найдя ширину скроллера и ширину ступени. Если скроллер смещен так далеко влево, что его позиция x меньше его собственной ширины (отрицательной), но с учетом ширины рабочей области (плюс stageWidth) мы должны держать ее прямо там. Чтобы добавить отступ на этом конце мы вычтем 20.
function moveScrollerThumbs (e: Event): void { if (mouseY> scroller.y && mouseY <scroller.y + scroller.height) {// вертикально над скроллером if (mouseX <stage.stageWidth / 2 && mouseX> 0) {// явно слева от сцены скорость = 5; } else if (mouseX> stage.stageWidth / 2 && mouseX <stage.stageWidth) {// явно справа от сцены скорость = -5; } scroller.x + = скорость; // пределы скроллера if (scroller.x <-scroller.width + stage.stageWidth - 20) {// если скроллер слишком далеко ушел scroller.x = -scroller.width + stage.stageWidth - 20; } else if (scroller.x> 20) {// if прокрутка вправо scroller.x = 20; } } }
Шаг 16: Динамическое движение
Чтобы сделать движение более плавным и динамичным, нам нужно всего лишь обновить две строки кода. Как вы уже догадались, две линии, которые задают скорость, необходимо отрегулировать, чтобы определить скорость по расстоянию mouseX от центра сцены, а не по плоскому значению 5. Мы находим расстояние, на котором мышь расположена горизонтально от центральной оси этапа (stage.stageWidth / 2), и мы хотим, чтобы скроллер переместился вправо, если мы находимся на левой стороне, и наоборот. В обоих случаях мы находим отрицательную разницу между ними. Затем мы должны уменьшить его, разделив его на, давайте попробуем 8, потому что если мы этого не сделаем, скроллер будет слишком быстрым (продолжайте, попробуйте).
function moveScrollerThumbs (e: Event): void { if (mouseY> scroller.y && mouseY <scroller.y + scroller.height) {// вертикально над скроллером if (mouseX <stage.stageWidth / 2 && mouseX> 0) {// явно слева от сцены скорость = - (mouseX - stage.stageWidth / 2) / 8; } else if (mouseX> stage.stageWidth / 2 && mouseX <stage.stageWidth) {// явно справа от сцены скорость = - (mouseX - stage.stageWidth / 2) / 8; } scroller.x + = скорость; // пределы скроллера if (scroller.x <-scroller.width + stage.stageWidth - 20) {// если прокрутить слишком далеко влево scroller.x = -scroller.width + stage.stageWidth - 20; } else if (scroller.x> 20) {// если прокрутить в крайнее правое положение scroller.x = 20; } } }
Шаг 17: Дружественное движение
Теперь проверьте это и подумайте о своем конечном пользователе. Вы будете смотреть на этот скроллер изображений и, возможно, захотите посмотреть поближе или сфокусироваться на изображении, которое бросается в глаза. Вы хотите, чтобы этот скроллер прекратил движение (если я переместился в центр сцены, он все еще перемещается в одну сторону от другой), и я больше сосредоточился на борьбе со скроллером, чем на изображении, на которое я хочу посмотреть.
Это пример непрозрачного пользовательского элемента управления. Мы хотим, чтобы пользователь мог интуитивно использовать этот скроллер до такой степени, что он даже не задумывается об этом. Если пользователь должен думать об этом или, что еще хуже, бороться с вашим приложением, чтобы заставить его что-то делать, вы проиграете, и они будут искать в другом месте свой контент. Так что давайте избегать борьбы и предоставим скроллеру мертвую зону в центре сцены. Затем они могут спокойно отдыхать, двигаясь к центру скроллера, чтобы что-то осмотреть или остановить укачивание. Это действительно легко сделать и имеет большую отдачу, облегчая использование скроллера. Вместо того, чтобы использовать центр сцены для всех наших расчетов, мы добавим немного отступов.
function moveScrollerThumbs (e: Event): void { if (mouseY> scroller.y && mouseY <scroller.y + scroller.height) {// вертикально над скроллером if (mouseX <stage.stageWidth / 2 - 40 && mouseX> 0) {// явно слева от сцены скорость = - (mouseX - (stage.stageWidth / 2 - 40)) / 8; } else if (mouseX> stage.stageWidth / 2 + 40 && mouseX <stage.stageWidth) {// явно справа от сцены скорость = - (mouseX - (stage.stageWidth / 2 + 40)) / 8; } еще { скорость = 0; // если в центральной области, очистить скорость до 0, чтобы у нас не было эффекта переворачивания с последнего кадра. } scroller.x + = скорость; // пределы скроллера if (scroller.x <-scroller.width + stage.stageWidth - 20) {// если прокрутить слишком далеко влево scroller.x = -scroller.width + stage.stageWidth - 20; } else if (scroller.x> 20) {// если прокрутить в крайнее правое положение scroller.x = 20; } } }
Шаг 18: Абстрагирование движения Подробнее
Давайте немного отвлечемся от этого. У нас есть несколько мест, где мы добавляем отступы к значениям или измерениям. Лучше всего создать переменную, которая будет содержать наше значение отступа, и легко применять одно и то же значение, применяя переменную каждый раз, когда мы хотим заполнение. Это помогло бы нам обновиться, если клиент позже скажет: «Мне это нравится, но можем ли мы его распространить?» или страшные … «Что-то не так в этом …», тогда мы просто обновим переменную, и она будет готова к работе. Я всегда стараюсь создавать элементы управления для себя, программиста, чтобы упростить настройку проекта.
Я создал переменную с именем «padding» и применяю ее везде, где это имеет смысл. Заметьте, что в нескольких местах я умножаю его на 2, используйте ваше собственное суждение здесь — если вы хотите, чтобы больше отступов давало больше, конечно, мы могли бы пойти дальше и иметь переменную «padding_small» и другую переменную «padding_large», но одну сделает справедливость для целей этого урока. Вы поняли идею. Это на самом деле не меняет конечный файл, но может помочь сделать вашу жизнь намного проще, а ваш код проще, понятнее или читабельнее.
импорт caurina.transitions. *; // загрузить xml var xmlLoader: URLLoader = new URLLoader (); var xmlData: XML = new XML (); xmlLoader.addEventListener (Event.COMPLETE, LoadXML); var xmlPath: String = "image-scroller.xml"; xmlLoader.load (новый URLRequest (xmlPath)); trace ("загрузка xml из:" + xmlPath); функция LoadXML (e: Event): void { трассировка («загрузка xml завершена»); xmlData = новый XML (e.target.data); //trace(xmlData.image); buildScroller (xmlData.image); } var scroller: MovieClip = new MovieClip (); переменная скорость: число; var padding: Number = 20; this.addChild (скроллер); scroller.y = scroller.x = заполнение; // построить скроллер из xml Функция buildScroller (imageList: XMLList): void { трассировка («сборка скроллера»); for (var item: uint = 0; item <imageList.length (); item ++) { var thisOne: MovieClip = new MovieClip (); //контур var blackBox: Sprite = новый Sprite (); blackBox.graphics.beginFill (0xFFFFFF); blackBox.graphics.drawRect (-1, -1, 142, 107); thisOne.addChild (BlackBox); thisOne.x = (140 + padding) * item; thisOne.itemNum = item; thisOne.title = imageList [item] .attribute ("title"); thisOne.link = imageList [item] .attribute ("url"); thisOne.src = imageList [item] .attribute ("src"); // контейнер изображения var thisThumb: Sprite = new Sprite (); // добавить изображение var ldr: Loader = новый Loader (); var urlReq: URLRequest = новый URLRequest (thisOne.src); trace («загрузка эскиза» + item + «в Scroller:« + thisOne.src); ldr.load (urlReq); // назначаем прослушиватели событий для Loader ldr.contentLoaderInfo.addEventListener (Event.COMPLETE, completeHandler); ldr.contentLoaderInfo.addEventListener (IOErrorEvent.IO_ERROR, errorHandler); thisThumb.addChild (LDR); thisOne.addChild (thisThumb); // создаем слушателей для этого большого пальца thisOne.buttonMode = true; thisOne.addEventListener (MouseEvent.MOUSE_OVER, overScrollerItem); thisOne.addEventListener (MouseEvent.MOUSE_OUT, outScrollerItem); thisOne.addEventListener (MouseEvent.CLICK, clickScrollerItem); //Добавьте предмет scroller.addChild (thisOne); } scroller.addEventListener (Event.ENTER_FRAME, moveScrollerThumbs); трассировка («завершение построения скроллера»); } function overScrollerItem (e: MouseEvent): void { trace ("over" + e.currentTarget.name); } function outScrollerItem (e: MouseEvent): void { trace ("out" + e.currentTarget.name); } function clickScrollerItem (e: MouseEvent): void { trace («нажатый элемент» + e.currentTarget.itemNum + »- URL-адрес посещения:« + e.currentTarget.link); } function completeHandler (e: Event): void { // trace ("thumbnail complete" + e.target.loader.parent.parent.name); // размер изображения в скроллере resizeMe (e.target.loader.parent, 140, 105, true, true, false); Tweener.addTween (e.target.loader.parent.parent, {alpha: 1, time: .5}); } function errorHandler (e: IOErrorEvent): void { trace ("thumbnail error =" + e); } // Функция изменения размера // параметры // требуется: mc = мувиклип для изменения размера // required: maxW = либо размер поля для изменения размера, либо просто максимальная желаемая ширина // необязательно: maxH = при желании область изменения размера не квадрат, а максимальная желаемая высота. по умолчанию соответствует maxW (поэтому, если вы хотите изменить размер до 200x200, просто отправьте 200 раз) // необязательно: constrainProportions = boolean, чтобы определить, хотите ли вы ограничить пропорции или наклонить изображение. по умолчанию true. Функция resizeMe (mc: DisplayObject, maxW: Number, maxH: Number = 0, constrainProportions: Boolean = true, centerHor: Boolean = true, centerVert: Boolean = true): void { maxH = maxH == 0? maxW: maxH; mc.width = maxW; mc.height = maxH; if (constrainProportions) { mc.scaleX <mc.scaleY? mc.scaleY = mc.scaleX: mc.scaleX = mc.scaleY; } if (centerHor) { mc.x = (maxW - mc.width) / 2; } if (centerVert) { mc.y = (maxH - mc.height) / 2; } } function moveScrollerThumbs (e: Event): void { if (mouseY> scroller.y && mouseY <scroller.y + scroller.height) {// вертикально над скроллером if (mouseX <stage.stageWidth / 2 - padding * 2 && mouseX> 0) {// явно слева от сцены скорость = - (mouseX - (stage.stageWidth / 2 - отступ * 2)) / 8; } else if (mouseX> stage.stageWidth / 2 + padding * 2 && mouseX <stage.stageWidth) {// явно справа от сцены speed = - (mouseX - (stage.stageWidth / 2 + padding * 2)) / 8; } еще { скорость = 0; } scroller.x + = скорость; // пределы скроллера if (scroller.x <-scroller.width + stage.stageWidth - padding) {// если прокручивается слишком далеко влево scroller.x = -scroller.width + stage.stageWidth - заполнение; } else if (scroller.x> padding) {// если прокрутить в крайнее правое положение scroller.x = padding; } } }
Шаг 19: Добавление масштабных анимаций
С этой идеей использования переменных для настройки нашего файла давайте добавим немного связки с библиотекой Tweener, которую мы уже добавили. Замечательно вызывать элемент в скроллере, который переворачивает пользователь, поэтому давайте сделаем его немного больше, чтобы выделиться. Вот тут-то и кроется красота Tweening. Всего одна строка кода, несколько переменных, и мы можем сказать ей, что нужно изменить значения scaleX и scaleY элемента прокрутки. Если мы масштабируем элемент, мы также хотим немного перевести его координаты, чтобы элемент был по центру, это выглядит как сложная математика, но на самом деле все довольно просто.
Во-первых, мы добавляем переменную к каждому объекту для хранения его начальной позиции x, мы можем просто назвать ее myx и поместить ее в ту же строку, где мы вычисляем x (мы делаем это, чтобы мы могли надежно переместить элемент обратно в его правильное место когда нам нужно). Нам нужно переместить его так, чтобы элемент был по центру, поэтому мы находим его текущую ширину и делим его на половину применяемого масштаба. Мы делаем это для х и у. Затем нам нужно вернуть его к его начальному размеру и координатам в обработчике события мыши.
thisOne.x = thisOne.myx = (140 + заполнение) * item; ... var thumbSmall: Number = 1; var thumbLarge: Number = 1.1; function overScrollerItem (e: MouseEvent): void { // trace ("over" + e.currentTarget.name); Tweener.addTween (e.currentTarget, {scaleX: thumbLarge, scaleY: thumbLarge, x: e.currentTarget.myx - e.currentTarget.width * Math.abs (thumbSmall - thumbLarge) / 2, y: -e.currentTarget.width * Math.abs (thumbSmall - thumbLarge) / 2, время: 1}); } function outScrollerItem (e: MouseEvent): void { // trace ("out" + e.currentTarget.name); Tweener.addTween (e.currentTarget, {scaleX: thumbSmall, scaleY: thumbSmall, x: e.currentTarget.myx, y: 0, время: 1}); }
Шаг 20: Добавление пограничных анимаций
Давайте выделим их еще больше, потушив белый «черный ящик» вокруг миниатюр (просто осознав, что я назвал белый ящик черным =)). Этот проще, чем предыдущий шаг. Просто добавьте пару переменных для значений постепенного появления (альфа) и добавьте Tweens в функцию обработчика событий прослушивания over и out. Нам также необходимо убедиться, что мы можем обращаться к спрайту blackBox, поэтому, когда мы его инициализируем, давайте явно назовем его. Пока мы работаем над этим, мы можем установить начальную альфа-версию блока равной переменной thumbFadeOut.
//контур var thumbFadeOut: Number = .2; var thumbFadeIn: Number = 1; var thumbSmall: Number = 1; var thumbLarge: Number = 1.1; ... var blackBox: Sprite = новый Sprite (); blackBox.graphics.beginFill (0xFFFFFF); blackBox.graphics.drawRect (-1, -1, 142, 107); blackBox.alpha = thumbFadeOut; thisOne.addChild (BlackBox); thisOne.blackBox = blackBox; ... function overScrollerItem (e: MouseEvent): void { // trace ("over" + e.currentTarget.name); Tweener.addTween (e.currentTarget, {scaleX: thumbLarge, scaleY: thumbLarge, x: e.currentTarget.myx - e.currentTarget.width * Math.abs (thumbSmall - thumbLarge) / 2, y: -e.currentTarget.width * Math.abs (thumbSmall - thumbLarge) / 2, время: 1}); Tweener.addTween (e.currentTarget.blackBox, {alpha: thumbFadeIn, time: 1}); } function outScrollerItem (e: MouseEvent): void { // trace ("out" + e.currentTarget.name); Tweener.addTween (e.currentTarget, {scaleX: thumbSmall, scaleY: thumbSmall, x: e.currentTarget.myx, y: 0, время: 1}); Tweener.addTween (e.currentTarget.blackBox, {alpha: thumbFadeOut, time: 1}); }
Шаг 21: Добавление ссылки по клику
Говоря о всех слушателях событий, мы еще не закончили кодировать событие click. Мы хотим, чтобы клик был в основном щелчком ссылки и связывал пользователя с URL, указанным в xml. Для этого мы просто передаем значение ссылки из цели события, которую мы отслеживаем в настоящее время, в объект URLRequest и пытаемся перейти к нему с помощью нашего друга navigateToURL. Там у нас это есть.
function clickScrollerItem (e: MouseEvent): void { // trace ("clicked item" + e.currentTarget.itemNum + "- url посещения:" + e.currentTarget.link); var urlRequest: URLRequest = новый URLRequest (e.currentTarget.link); пытаться { navigateToURL (URLRequest); } catch (e: Error) { // обработать ошибку здесь проследить (е); } }
Вывод
Я надеюсь, вам понравился этот урок, и вы чему-то научились. Теперь вы должны хорошо разбираться в AS3 и xml, загружать и изменять размеры изображений, легко анимировать с помощью анимации, прослушивания событий мыши, прокрутки и удобного интерактивного дизайна!
Легко ли было следовать? Я обычно делаю учебные пособия в примерах с открытым исходным кодом, поэтому я не знаю, слишком ли я тут заговорил … Не стесняйтесь, дайте мне знать в комментариях. Это руководство предназначено для того, чтобы стать источником идей; есть множество других вещей, которые мы могли бы использовать с этим файлом и получить много других эффектов, но это должно помочь вам начать!