Статьи

Совет: изменение размера SWF-файлов с помощью BrowserCanvas

Вам когда-нибудь нужно было изменять размер встроенного SWF-файла в зависимости от взаимодействия с пользователем / ввода, например, как Newgrounds позволяет изменять размеры некоторых Flash-игр в соответствии с размером экрана? Это можно сделать с помощью JavaScript и класса ExternalInterface в ActionScript. Но что, если вы вообще не знаете JavaScript ?

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


Прежде всего нам нужен редактор кода. Я буду использовать FlashDevelop для этого урока, потому что мы будем писать как ActionScript, так и HTML, и это хороший редактор кода для обоих. Это не обязательно, поэтому вы можете использовать любое программное обеспечение, которое вам нравится. Если вы хотите использовать его, но не знаете как, ознакомьтесь с руководством для начинающих по FlashDevelop .

Затем вам понадобится класс BrowserCanvas перейдите сюда, загрузите его и прочитайте более подробный обзор.

Также вам понадобится изображение, которое будет представлять контент (я использовал логотип Activetuts +) и изображение, которое представляет обработчик изменения размера. Я включил оба в источник загрузки, так что у вас все будет хорошо.

Теперь, когда мы готовы, давайте начнем!

Примечание. В первых шести шагах я объяснил, как осуществляется подготовка и как создать пользовательский интерфейс, не ссылаясь на реальный класс BrowserCanvas . Если вы не хотите следовать им, вы можете сразу перейти к шагу 7 и продолжить использовать проект, который я предоставил в пакете загрузки. Вы можете найти его в исходной папке и в папке SWFResize — milestone .


Откройте FlashDevelop и создайте новый проект, выбрав « Проект»> «Новый проект …» . Дайте ему имя и нажмите ОК .

Также скопируйте папку com из загруженного файла в исходный каталог вашего проекта.


Поместите изображения active.png и arrows.png из загруженного пакета в папку ресурсов в каталоге bin вашего проекта.

Затем откройте файл Main.as и поместите в него четыре выделенные строки (остальные уже будут автоматически созданы FlashDevelop):

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package
{
    import flash.display.Sprite;
    import flash.events.Event;
     
    public class Main extends Sprite
    {
        [Embed(source = ‘../bin/assets/active.png’)]
        public var logo:Class;
        [Embed(source = ‘../bin/assets/arrows.png’)]
        public var arrows:Class;
         
        public function Main():void
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
         
        private function init(e:Event = null):void
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
        }
         
    }
     
}

Это объединит два ресурса, чтобы мы могли использовать их во время выполнения.


Прямо сейчас сцена имеет свои настройки по умолчанию: она будет иметь белый цвет фона, частоту кадров 24 кадра в секунду и размер 800 на 600 пикселей, что слишком велико, чтобы мы могли продемонстрировать этот эффект.

Добавьте выделенную строку непосредственно перед объявлением класса:

1
2
[SWF(width = «400», height = «300», backgroundColor = «0x313131″, frameRate=»60»)]
public class Main extends Sprite

Мы также хотим установить масштабный режим и выравнивание сцены. Для этого мы добавим метод setStage() в наш класс и вызовем его из метода init() .

01
02
03
04
05
06
07
08
09
10
11
private function setStage():void
{
    stage.align = «TL»;
    stage.scaleMode = «noScale»;
    stage.addEventListener(Event.RESIZE, onStageResize);
}
 
private function onStageResize(e:Event):void
{
     
}

Как вы можете видеть, я также добавил слушатель события на сцену для события Event.RESIZE вместе с соответствующей функцией-обработчиком onStageResize() .


Ладно. Теперь у нас настроена сцена, и мы продолжим добавление контента.

Сначала добавьте эти две переменные в наш класс:

1
2
private var _logo:Bitmap;
private var _arrows:Sprite;

Теперь добавьте метод createObjects() и вызовите его из метода init() :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
private function init(e:Event = null):void
{
    removeEventListener(Event.ADDED_TO_STAGE, init);
    setStage();
    createObjects();
}
 
private function createObjects():void
{
    _logo = new logo() as Bitmap;
    addChild(_logo);
 
    _arrows = new Sprite();
    _arrows.buttonMode = true;
    _arrows.addChild(new arrows() as Bitmap);
    addChild(_arrows);
}

Это создаст экземпляры наших объектов и добавит их в список отображения.

Если вы скомпилируете код сейчас, вы увидите, что эти два перекрываются, поэтому давайте разместим их.


Давайте рассмотрим, что нам нужно, чтобы наш контент всегда оставался в центре сцены, а обработчик изменения размера — в правом нижнем углу сцены. Мы будем использовать следующие два метода, чтобы сделать это.

positionLogo() будет центрировать контент на сцене …

1
2
3
4
5
private function positionLogo():void
{
    _logo.x = stage.stageWidth * 0.5 — _logo.width * 0.5;
    _logo.y = stage.stageHeight * 0.5 — _logo.height * 0.5;
}

… и positionArrows() установит обработчик изменения размера в нижний правый угол сцены:

1
2
3
4
5
private function positionArrows():void
{
    _arrows.x = stage.stageWidth — _arrows.width — 30;
    _arrows.y = stage.stageHeight — _arrows.height — 30;
}

Наконец, давайте вызовем их из метода init() чтобы выполнить фактическое позиционирование.

1
2
3
4
5
6
7
8
private function init(e:Event = null):void
{
    removeEventListener(Event.ADDED_TO_STAGE, init);
    setStage();
    createObjects();
    positionLogo();
    positionArrows();
}

Кроме того, теперь пришло время изменить обработчик onStageResize() для размещения логотипа при каждом изменении размера сцены.

1
2
3
4
private function onStageResize(e:Event):void
{
    positionLogo();
}

Скомпилируйте код и проверьте результат. Выглядит хорошо, не так ли? 🙂


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

Добавьте эти два слушателя MouseEvent после последней строки в createObjects()

1
2
_arrows.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
_arrows.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);

Также добавьте соответствующие им функции-обработчики:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
private function onMouseDown(e:MouseEvent):void
{
    _arrows.startDrag();
    addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
 
private function onMouseUp(e:MouseEvent):void
{
    _arrows.stopDrag();
    _arrows.x = stage.stageWidth — _arrows.width — 30;
    _arrows.y = stage.stageHeight — _arrows.height — 30;
    removeEventListener(Event.ENTER_FRAME, onEnterFrame);
}
 
 
private function onEnterFrame(e:Event):void
{
     
}

Как вы можете видеть, обработчики событий MOUSE_DOWN и MOUSE_UP используются для обработчика изменения размера, а ENTER_FRAME событий ENTER_FRAME используется для запуска кода для изменения размера. Мы добавим соответствующий код в обработчик onEnterFrame() на следующих шагах.


До сих пор мы занимались только базовым программированием на AS3, не обсуждая саму идею этого учебника: изменение размера области, которую SWF занимает на веб-странице. Это не были необходимые шаги, но я сделал их для имитации упрощенного реального сценария.

Для начала добавим новую переменную с именем _canvas типа BrowserCanvas :

1
private var _canvas:BrowserCanvas;

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

После создания переменной создайте ее экземпляр в createObjects() .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
private function createObjects():void
{
    _canvas = new BrowserCanvas(stage);
     
    _logo = new logo() as Bitmap;
    addChild(_logo);
     
    _arrows = new Sprite();
    _arrows.buttonMode = true;
    _arrows.addChild(new arrows() as Bitmap);
    addChild(_arrows);
    _arrows.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
    _arrows.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
}

Как видите, класс BrowserCanvas принимает следующие три параметра:

  • stage — это ссылка на сцену. Это будет использоваться, чтобы гарантировать, что правильный фильм Flash нацелен
  • containerId — это ссылка на тег div или object, который содержит фильм и размер которого мы хотим изменить. Это на самом деле не нужно, если на одной странице нет нескольких экземпляров одного SWF
  • browserHacks — список хаков, которые будут применены. Вам на самом деле не нужно передавать это, поскольку по умолчанию применяется все хаки

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

Ошибка № 2067: ExternalInterface недоступен в этом контейнере. Для ExternalInterface требуется Internet Explorer ActiveX, Firefox, Mozilla 1.7.5 и выше или другие браузеры, поддерживающие NPRuntime.

Это потому, что SWF еще не встроен в контейнер HTML. Фильм в любом случае будет успешно скомпилирован, но если вы не хотите получать эту ошибку, вы можете добавить оператор if, чтобы проверить, находится ли фильм в нужном контейнере. Это легко сделать, проверив свойство ExternalInterface.available перед созданием объекта BrowserCanvas .

1
if (ExternalInterface.available) _canvas = new BrowserCanvas(stage);

Последнее, что нам нужно сделать во Flash, это добавить реальный код, который выполняет изменение размера. Этот код будет запускаться из обработчика события onEnterFrame() :

01
02
03
04
05
06
07
08
09
10
private function onEnterFrame(e:Event):void
{
if (_canvas)
    {
        var w:Number = _arrows.x + _arrows.width + 30;
        var h:Number = _arrows.y + _arrows.height + 30;
        _canvas.width = w.toString();
        _canvas.height = h.toString();
    }
}

Переменные w и h используются для вычисления подходящей ширины и высоты сцены, после чего мы устанавливаем свойства width и height объекта _canvas на соответствующие ширину и высоту. Эти два свойства должны быть заданы как строки.

Примечание: оператор if предназначен для проверки того, был ли создан _canvas объекта _canvas , потому что если мы скомпилируем код и используем обработчик изменения размера, мы получим ошибку. Это происходит из-за неподходящего контейнера снова. Поскольку фильм воспроизводится в автономном проигрывателе, контейнер HTML отсутствует, поэтому объект _canvas не был создан (см. Предыдущий шаг).

Скомпилируйте проект и перейдите к следующему шагу.


Теперь, когда часть Flash закончена, нам нужно немного поработать в HTML, поскольку для правильной работы необходимо предпринять некоторые шаги.

Если вы используете FlashDevelop, у вас должен быть файл HTML с именем index.html, сгенерированный автоматически в каталоге bin ; если нет, создайте его. Это должно выглядеть так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!DOCTYPE html PUBLIC «-//W3C//DTD XHTML 1.0 Transitional//EN» «http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd»>
<html>
<head>
    <title>SWFResize</title>
    <meta http-equiv=»Content-Type» content=»text/html; charset=utf-8″ />
    <script src=»https://activetuts.s3.amazonaws.com/tuts/286_resizingSWF/tutorial/js/swfobject.js» type=»text/javascript»></script>
    <script type=»text/javascript»>
        var flashvars = {
        };
        var params = {
            menu: «false»,
            scale: «noScale»,
            allowScriptAccess: «always»,
            wmode: «opaque»
        };
        var attributes = {
            id:»SWFResize»
        };
        swfobject.embedSWF(«SWFResize.swf», «altContent», «400», «300», «9.0.0», «expressInstall.swf», flashvars, params, attributes);
    </script>
</head>
<body>
    <div id=»altContent»>
        <p><a href=»http://www.adobe.com/go/getflashplayer»><img
            src=»https://activetuts.s3.amazonaws.com/tuts/286_resizingSWF/tutorial/http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif»
            alt=»Get Adobe Flash player» /></a></p>
    </div>
</body>
</html>

Это простой HTML-файл со SWF, встроенным с использованием SWFObject .

Примечание. Если у вас нет SWFObject вы можете получить его отсюда и поместить файл SWFObject.js в папку с именем js, которая находится в той же папке, что и ваши index.html и SWF-файлы.

Это также будет работать с базовым внедрением с использованием тегов <object> и <embed> .

Сохраните файл HTML и откройте его. Используйте обработчик двойной стрелки, чтобы изменить размер сцены.


При встраивании SWF-файла с использованием любого из этих методов необходимо allowScriptAccess для allowScriptAccess значение allowScriptAccess . Это строго необходимо, поскольку позволяет SWF-файлу выполнять вызовы JavaScript .

Также, если вы хотите, чтобы цвет сцены SWF был видимым, вы должны установить для параметра wmode значение opaque .

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

1
swfobject.embedSWF(«SWFResize.swf», «altContent», «400», «300», «9.0.0», «expressInstall.swf», flashvars, params, attributes);

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

Чтобы исправить это, класс BrowserCanvas поставляется с четырьмя полезными свойствами, которые помогут вам ограничить размер SWF.

  • minWidth — определяет минимум, с которым сцена может иметь
  • minHeight — определяет минимальную высоту сцены
  • maxWidth — определяет максимальную ширину сцены
  • maxHeight — определяет максимальную высоту сцены

Чтобы увидеть, как это работает, добавьте метод setMinMax() в класс AS, над которым мы работали.

1
2
3
4
5
6
private function setMinMax():void
{
    _canvas.minHeight = _canvas.minWidth = «300»;
    _canvas.maxHeight = «500»;
    _canvas.maxWidth = «800»;
}

И измените метод createObjects() следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
private function createObjects():void
{
    if (ExternalInterface.available) {
        _canvas = new BrowserCanvas(stage);
        setMinMax();
    }
     
     
    _logo = new logo() as Bitmap;
    addChild(_logo);
     
    _arrows = new Sprite();
    _arrows.buttonMode = true;
    _arrows.addChild(new arrows() as Bitmap);
    addChild(_arrows);
    _arrows.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
    _arrows.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
}

В основном это ограничивает размер SWF-файла минимумом 300 на 300 пикселей и максимумом 800 на 500 пикселей .

Чтобы увидеть результат, скомпилируйте код и перезагрузите файл HTML. Теперь вы не должны иметь возможность изменять размер SWF за пределами границ.


Надеюсь, вы найдете этот маленький класс таким же полезным, как и я. Обратите внимание, что он может работать не во всех браузерах, поскольку все они имеют разные способы интерпретации JavaScript.

Не стесняйтесь оставлять комментарии, если некоторые шаги неясны.

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