Adobe flash полоса прокрутки

Обновлено: 05.07.2024

Продублирую, пожалуй, сюда эту свою "статейку" с хабра. Может кому-то пригодится. А может найдутся недочеты и исправления.
=====================
Совсем не думал, что решая такой простой (как мне казалось) вопрос, придется здорово потрудиться и пораскинуть мозгами. Но в итоге получилась полноценная библиотека, которая адекватно работает со всеми видами flash - плагинов на странице (включая Pepper flash в Chrome, о котором позже).

Но обо всем по порядку.

Проблема одновременной прокрутки флеш контента и браузера существует давно, поэтому я был уверен, что есть готовое решение "из коробки".
Немного погуглив получаем желаемый результат - MouseWheelTrap. Библиотека отслеживает положение курсора, и если он находится над flash-контентом, отключает прокрутку в браузере, оставляя flash право единолично использованть ролик мыши. Скачиваем, подключаем, все работает.
Просто?
Отнюдь.
Первым неработоспособность блокировки заметил коллега - спросил, почему не работает скролл мышкой. Решил проверить на других машинах - проблема оказалась серьезней чем я думал сначала - на большинстве скролл так же не работал, причем только в Chrome.
Chrome в этом плане здорово переплюнул IE8, поскольку IE с задачей справлялся на ура

Виной всему оказался плагин Pepper flash, который включается в сборку браузера Chrome начиная с версии 11.3. У Pepper flash своя API и "повышенная безопасность". Видимо как раз эта "безопасность" и стала корнем проблемы. Продолжив поиски решения, нашел большое количество упоминаний словосочетаний "Buggy pepper flash" и прочих не очень лестных замечаний в адрес этого флеш плагина. И очень удивило, что на Stackoverflow не было ни одного полноценного ответа по этой теме:
вопрос 1
вопрос 2
.
Это меня здорово вдохновило на поиск и написание собственного решения.

Первым что пришло в голову было следующее: не блокировать стандартную прокрутку браузера с помощью стандартной

а отслеживать передвижение колесика мыши и прокручивать браузер в противоположном направлении.
Идея, конечно, костыль с гвоздями, но как то начинать решение проблемы надо.
Оказалось что вызывать функции прокрутки страницы ни из обработчика события перемещения ролика мыши, ни из flash с помощью ExternalInterface нельзя.
Оно и к лучшему, решение в любом случае было далеко от изящного и оригинального.

Но немного разобрав ту самую библиотеку, удалось ее здорово улучшить. Основная её проблема была в том, что после каждого движения мыши она отправляла на выполнение довольно здоровый кусок кода на javascript, что в данном случае не имело совершенно никакого смысла:

JAVASCRIPT - это "строка" кода, которая в развернутом состоянии занимает 41 строчку. Немного расточительно при каждом движении курсора мыши отправлять код с определением функций на страницу.
Пришлось перенести его в инициализацию библиотеки и в последствии там же и оставить.

После этого я решил проверить, каким именно образом отключается стандартная прокрутка в Chrome и чем это действие отличается от аналогичного в других браузерах.

Оказалось что Pepper flash (читай flash в Chrome) просто не получает событий передвижения колесика, если мы отключаем стандартную прокрутку с помощью

  • Ловим событие прокрутки колесика мыши
  • Отправляем детали события (дельта прокрутки) во Flash
  • Блокируем прокрутку браузера
  • Собираем событие прокрутки в flash с нуля
  • Диспетчиризуем событие на сцену

Если мы имеем дело с Chrome, то уведомляем флешку о том, что произошла прокрутка и передаем значение перемещения.

Теперь то, что находится внутри flash (код обработчиков перемещения мыши и ухода курсора со сцены в данном случае особой значимости не несет и может быть опущен):


Таким образом мы получаем и обрабатываем событие прокрутки до того, как вызываем

. Флеш теперь не чувствует себя обделенным и исправно обрабатывает свои же события.

Чуть позже оказалось, что на Mac OS-x присутствует та же проблема. При этом уже не в Chrome а во всех браузерах по умолчанию. Тут уже не получилось бы отделаться простой проверкой на тип браузера.
На помощь пришла стандартная функция .os из библиотеки
flash.system.Capabilities
Определяем, сидит ли пользователь с OS-X (AS3):

Немного поправляем функцию регистрации слушателей, заставляем принимать булеву переменную isMac в качестве параметра (JS):

И добавляем дополнительное условие для диспетчиризации собственного события:


В итоге, если немного отполировать код(добавить весь JS код в AS3 в виде строковой величины и вызывать с помощью

, и добавить входной параметр - flashID для большей гибкости) , получим работоспособную библиотеку, полноценного аналога которой я почему-то не смог найти на просторах интернета

Ссылка на репозиторий GitHub

Комментарии

Нет, во время разработки все что было перепробовал (эти примеры в частности) - часть не работают в Chrome, часть в MacOS, какие то в IE

Там еще был вариант, китайцы сделали как-то через LocalConnection и передачу каких-то байтовых массивов, но работало только на MacOS. Пришлось даже качать с какого то китайского репозитория, где ни слова на английском не было (наугад нажимал все подряд, но библиотека в итоге скачалась). Но даже эта библиотека не давала 100% работоспособности

У меня все три работают в хроме. Первая не работает в IE 9, не отпускает фокус с флешки. Не могу проверить какие не работают в MacOS. Можете ли вы сказать какие?

Скорее всего вы проверяете работоспособность с дебаг плагином - в нем все работает, да. По этой причине я и не предполагал что на самом деле, с обычным пеппер флеш плагином, такие косяки.

Первая точно не работает в MacOS, так же точно не работает та, которую я привел в статье, насчет остальных не скажу с точностью

В хроме я тестировал на указанных вами основаниях.


Что помешало проверить на MacOS два других решения, приведенных мною в первом посте?

Я ж написал что только с пеппер флеш такой косяк. Поэтому и не было возможности отследить проблему изначально, у меня то тоже дебаг версия стояла.

Проверить помешало отсутствие Мак машины дома) На рабочем месте проверю)
Проверил на маке - по двум последним ссылкам вроде работает (проверил в сафари и опере)

Прошу прощения, я немного запутался. Скриншот говорит о том, что я использую papper. При нем отлично работают два последних примера. Какие проблемы с papper вы имеете ввиду?

Вы утверждаете, что проверили в том числе решения, ссылки на которые перечислены мною в первом комментарии на адекватность некоторому ожидаемому вами поведению. Проверили и поняли, что ожидание не соответствует действительности и эти решения не подходят. Вы начинаете писать свой велосипед. Теперь я проверяю эти решения на такую же адекватность, я соблюдаю все условия в которых проверяли вы. Я нахожу по крайней мере два решения, соответствующих условиям задачи. В чем я виноват, что заставляю вас оправдываться?

Скорее всего потому что не встретил эти два решения в своих долгих поисках по просторам интернета)

Проблема боком стояла, попробовал 4-5 библиотек и ни одна до конца не работала. Кстати, по сопутствующим статьям можно сделать вывод, что с wmode=direct они не тестились (знаю что про wmode в моей "статье" ни слова, но в нашем приложении из-за использования старлинга приходится использовать именно direct) и может быть в этом и есть корень проблемы.

Надо будет попробовать прикрутить к тому проекту ради интереса.

Вопрос изначально не стоял - "сделать свою либу", я честно и долго искал готовое решение, но сроки поджимали а решения так и не было. Очень странно, что не наткнулся на два предложенных вами источника, искал довольно долго и всевозможные вариации

В общем я не был бы так категоричен. Я делал это не из-за жажды наживы или легких денег)

Тем не менее, я рад, что вы двинулись в этом направлении.

Встроил в обычный демо проект - либа по второй ссылке требует настройки политики безопасности для локального тестирования, выдает ошибку нарушения изолированной среды. При работе с удаленного сервера на MacOS есть очень неприятная особенность создавать "инерцию" прокрутки (в стандартном Feathers листе). То есть делаем прокрутку, перестаем прокручивать, выводим курсор за рамки флешки - страница прокручивается по "инерции" - видимо в этой либе идут от противного - передают в браузер информацию о прокрутке из флеш, а не наоборот. Плюс не всегда схватывает саму прокрутку (у меня в обычном дебаг плеере в фаерфоксе на винде бывает проскакивает так, что не схватывается) (ссылка)

Либа по третьей ссылке вообще работает как автономная библиотека для ембединга флеш объекта на страницу, альтернатива SWFObject. Я, пожалуй, не буду отказыватся от более проверенного способа ембединга, я думаю тут вы тоже поймете.

Я пытаюсь поместить вертикальную полосу прокрутки на динамический TextField в Flash CS4. Когда я делаю это в сцене 1, все работает просто отлично. Однако если я перемещаю полосу прокрутки TextField+в сцену 2, она ломается. Ошибки, которые я получаю при запуске кода, указывают на то, что Flash сразу загружает полосу прокрутки, а затем пытается найти связанный TextField. Проблема в том, что, поскольку TextField не загружается, пока вы не доберетесь до сцены 2, Flash выдает ошибку.

Я много чего перепробовал, чтобы решить эту проблему. В основном все сводилось к тому, что мне нужно было создать TextField и полосу прокрутки в actionscript (а не из библиотеки компонентов), чтобы я мог контролировать, когда каждый из них был создан. Чтобы создать TextField, я набрал:

и чтобы создать полосу прокрутки, я затем набрал:

Единственная проблема заключается в том, что этот код работает только в том случае, если я сделаю ScrollBar горизонтальным и выключу wordwrap. По какой-то причине вертикальная полоса прокрутки не будет работать с wordrap on (и без wordwrap, Flash думает, что нет необходимости в вертикальной полосе прокрутки, так как он видит только одну строку текста.

Получение текстового поля с полосой прокрутки должно быть простым процессом, но это действительно выходит из-под контроля. Есть идеи, как заставить ScrollBar работать, когда wordWrap включен?

2 ответа

Есть ли способ воспроизвести контент Youtube в фильме Flash без использования стороннего плагина? Я использую Flash CS4 и Actionscript 3.0.

В принципе, вы никогда не должны использовать сцены в Flash. С ними есть много известных проблем.

Использование сцен, как правило, является плохой практикой. Они являются устаревшей функцией, оставленной для обеспечения совместимости текущих версий flash с более ранними версиями. Если вы должны использовать IDE для размещения объектов на сцене, вы должны использовать отдельные кадры на основной временной шкале вместо сцен и размещать объекты, для анимации которых требуется временная шкала, в своих собственных фильмах. flash IDE фактически сводит все сцены к одной временной шкале во время компиляции любым способом, но со многими аномалиями, которые не присутствовали бы при ручном манипулировании временной шкалой.

Похожие вопросы:

Я ищу некоторую информацию об использовании SQLITE с AIR в Flash CS4, я не могу найти никаких хороших примеров, все они построены для Flex (который я не хочу использовать). Кто-нибудь может дать мне.

Вчера Adobe выпустил проектор, отладчик и плагин для Flash 10.1. на моем Mac я установил автономный плеер и отладчик в Adobe Flash CS4/Players/ и Adobe Flash CS4/Players/Debug соответственно. тем не.

Я отлаживаю как проект flash cs4, так и проект flash builder, на самом деле проект flash builder будет загружать проект flash cs4 через swfloader, но система может поддерживать только один отладчик.

Есть ли способ воспроизвести контент Youtube в фильме Flash без использования стороннего плагина? Я использую Flash CS4 и Actionscript 3.0.

Как я могу использовать библиотеку facebook as3 в flash cs4 для создания приложения air. Я не хочу использовать flex здесь. Cs4 может построить приложение air. Но я не могу использовать библиотеку в.

Я переименовал клип в Flash CS4. После переименования и обновления любых ссылок, которые у меня были на него, swf все равно будет играть нормально. Однако я больше не мог добраться ни до одного из.

Adobe Flash CS4 вообще не содержит документации; он просто перенаправляет на онлайн-документы. Поскольку у меня есть более старый Flash CS3, мне было интересно, могу ли я использовать более старые.

Мне нужно разработать куб, содержащий 10 маленьких кубиков, и манипулировать всеми, как object..Somebody есть какая-нибудь идея или какой-нибудь учебник для этого на PaperVision3d и Flash.

Я написал пользовательский класс кнопок flash cs4 в actionscript 3 с его уникальными look-and-feel и переходами вверх/вниз и т. д. Как я могу импортировать активы Flash и использовать его Flash.


Компонент UIScrollBar позволяет добавлять полосу прокрутки к текстовому полю. Полосу прокрутки можно добавить к текстовому полю в процессе разработки или во время выполнения с помощью ActionScript. Чтобы воспользоваться компонентом UIScrollBar, создайте текстовое поле в рабочей области, перетащите компонент UIScrollBar с панели «Компоненты» в любой квадрант ограничивающего прямоугольника текстового поля.

Если длина полосы прокрутки меньше общего размера стрелок прокрутки, компонент отображается неправильно. Одна кнопка со стрелкой скрывается под другой. Flash не выводит ошибки об этой проблеме. В таком случае лучше скрыть полосу прокрутки с помощью ActionScript. Если размера полосы прокрутки недостаточно для отображения ползунка, Flash скрывает его.

Компонент UIScrollBar выполняет те же функции, что и другие полосы прокрутки. Он содержит кнопки со стрелками по обоим концам, между которыми расположена полоса прокрутки и ползунок. Компонент можно расположить по любому краю текстового поля для прокручивания по вертикали и горизонтали.

Дополнительные сведения об объекте TextField см. в описании класса TextField в справочнике ActionScript® 3.0 для Adobe® Flash® Professional CS5.

Взаимодействие пользователей с компонентом UIScrollBar

В отличие от многих других компонентов, UIScrollBar может получать непрерывный ввод данных мыши, например, когда пользователь удерживает кнопку мыши, не требуя повторных щелчков.

Компонент UIScrollBar не поддерживает взаимодействие с клавиатурой.

Параметры компонента UIScrollBar

В Инспекторе свойств или Инспекторе компонентов можно задать следующие параметры разработки для каждого экземпляра компонента UIScrollBar: direction и scrollTargetName . Каждый из этих параметров имеет соответствующее свойство ActionScript с тем же именем.

Можно написать код ActionScript, чтобы задать дополнительные параметры для экземпляров UIScrollBar с использованием их методов, свойств и событий. Дополнительные сведения см. в описании класса·UIScrollBar в справочнике ActionScript® 3.0 для Adobe® Flash® Professional CS5.

Создание приложения с компонентом UIScrollBar

Ниже описывается процедура добавления компонента UIScrollBar в приложение в ходе разработки.

Создайте новый документ Flash (ActionScript 3.0).

Создайте динамическое текстовое поле, достаточно высокое для одной или двух строк текста, и присвойте ему имя экземпляра myText в Инспекторе свойств.

В Инспекторе свойств задайте для свойства LineType поля ввода текста значение Multiline или MultilineNoWrap, если планируется использовать горизонтальную полосу прокрутки.

Откройте панель «Действия», выберите «Кадр 1» на главной временной шкале и введите следующий код ActionScript для заполнения свойства text таким образом, чтобы пользователю потребовалась прокрутка для его просмотра.

Примечание. Убедитесь, что текстовое поле в рабочей области достаточно маленькое, чтобы весь текст нельзя было просмотреть без прокрутки. Если оно будет слишком большое, полоса прокрутки может не появиться или на ней не будет ползунка (для прокручивания содержимого).

Убедитесь, что включена привязка к объектам («Просмотр» > «Привязка»> «Привязка к объектам»).

Перетащите экземпляр UIScrollBar с панели «Компоненты» в текстовое поле ввода рядом с тем краем, у которого нужно разместить полосу прокрутки. Чтобы компонент правильно присоединился к текстовому полю, кнопку мыши нужно отпустить, когда он будет перекрывать поле. Присвойте компоненту имя экземпляра mySb.

Свойство scrollTargetName автоматически заполняется именем экземпляра TextField, которое задано в Инспекторах свойств и компонентов. Если его нет на вкладке «Параметры», значит при размещении компонент UIScrollBar не достаточно перекрывал текстовое поле.

Создание экземпляра компонента UIScrollBar с помощью ActionScript

Экземпляр UIScrollBar можно создать с помощью ActionScript и связать его с текстовым полем во время выполнения. В следующем примере создается горизонтальный экземпляр UIScrollBar и присоединяется к нижнему краю текстового поля myTxt, в которое загружается текст из URL. Кроме того, размер полосы прокрутки определяется по размеру текстового поля.

Создайте новый документ Flash (ActionScript 3.0).

Перетащите компонент ScrollBar на панель «Библиотека».

Откройте панель «Действия», выберите «Кадр 1» на главной временной шкале и введите следующий код ActionScript.


Если у вас есть экранный объект, который является слишком большим для области, в которой его требуется показать, можно воспользоваться свойством scrollRect для определения видимой области экранного объекта. Кроме того, путем изменения свойства scrollRect в ответ на данные, введенные пользователем, можно включить панорамирование содержимого влево или вправо, а также прокрутку вверх и вниз.

Свойство scrollRect является экземпляром класса Rectangle. В этом классе сочетаются значения, которые необходимы для определения прямоугольной области в качестве единичного объекта. Чтобы определить вначале видимую область экранного объекта, создайте новый экземпляр Rectangle и присвойте его свойству scrollRect экранного объекта. Впоследствии для панорамирования или прокрутки свойство scrollRect считывается и заносится в отдельную переменную Rectangle. Требуемое свойство изменяется (например, измените свойство x экземпляра Rectangle, чтобы выполнить панорамирование, или свойство y , чтобы выполнить прокрутку). Затем необходимо переназначить экземпляр Rectangle свойству scrollRect , чтобы сообщить объекту об изменении значения.

Например, следующий код определяет обозримую область для объекта TextField с именем bigText , который слишком высок, чтобы вместиться в границы SWF-файла. При нажатии двух кнопок ( up и down ) они вызывают функции, отвечающие за прокрутку содержимого объекта TextField вверх и вниз путем изменения свойства y экземпляра Rectangle scrollRect .

Как показано в этом примере, при работе со свойством scrollRect экранного объекта лучше всего указать, что Flash Player или AIR должны кэшировать содержимое объекта в качестве растрового изображения с помощью свойства cacheAsBitmap . При этом Flash Player и AIR не требуется повторно отрисовывать все содержимое экранного объекта после каждой прокрутки. Вместо этого можно использовать кэшированное растровое изображение, чтобы визуализировать необходимую часть напрямую на экран. Сведения см. в разделе «Кэширование экранных объектов».

Читайте также: