Опубликован: 07.11.2006 | Доступ: свободный | Студентов: 3400 / 338 | Оценка: 3.94 / 3.71 | Длительность: 37:11:00
Лекция 3:

Форматирование текста

Дополнительные текстовые эффекты

До сих пор мы рассматривали текстовые эффекты внутри текстового поля. Несмотря на то, что они могут быть полезны, на них накладывается ряд ограничений Flash MX позволяет создавать более содержательные текстовые эффекты. При создании текстового эффекта мы, как правило, будем располагать каждую букву в фильме и затем динамически позиционировать (или перемещать) ее на определенное местоположение. Во Flash 5 нельзя было динамически получать ширину текста и, как следствие, позиционировать отдельные символы. Для достижения таких эффектов во Flash 5 приходилось использовать дополнительное средство - строку с калькулятором из www.swfx.org.

Flash MX предоставляет два способа вычисления ширины строки так, что мы можем выяснить, в каком месте должен располагаться каждый символ. Сначала используется textFormat.getTextExtent (str). С помощью этого метода можно передавать ему строку, и он будет возвращать объект, содержащий ширину и высоту данного фрагмента текста, как если бы все они располагались в одной строке. Это очень удобно, но данный подход имеет несколько особенностей, которые мы сейчас рассмотрим. Второй способ получения ширины строки заключается в том, что строка помещается в текстовое поле (с необходимым форматированием), и затем используется параметр textWidth текстового поля. Несмотря на то, что этот метод более громоздкий (так как здесь приходится создавать текстовое поле, чтобы задействовать его), он более точен по сравнению с использованием getTextExtent при работе со встроенными шрифтами. Продемонстрируем теперь работу этого метода.

Вычисление ширины строки

  1. Откройте новый фильм Flash и разместите на рабочем месте поле DynamicText, причем сделайте так, чтобы его длина занимала большую часть рабочего места. Мы будем использовать шрифт Verdana.
  2. В Property inspector дайте инстансу имя tf_txt. Затем создайте слой scripts и введите следующий код.
    myTForm = new TextFormat();
    myTForm.size = 24;
    myTForm.font = "Verdana";
    str = "a piece of test text to check widths";
    tf_txt.text = str;
    tf_txt.setTextFormat(myTForm);
    // retrieve width with getTextExtent
    a = myTForm.getTextExtent(str).width;
    // retrieve width with textWidth
    b = tf_txt.textWidth;
    trace(a+" : "+b);
  3. Запустите ваш файл и посмотрите на результат в окне Output. Окно будет отображать 407 : 416. 407 представляет собой ширину getTextExtent, и 416 - это textWidth.

Мы нарисовали две линии на рабочем месте, чтобы вы могли сравнить их. Имя файла - textWidthTest.fla.


Присутствующая здесь проблема типична для установки интервалов между знаками: если мы располагаем текст с помощью getTextExtent, символы отображаются один за другим, и между ними нет никакого интервала. Другими словами, textWidth - это наилучший способ аккуратного размещения текста.

Определение местоположения символов

Теперь мы решили, что нам потребуется использовать TextField.textWidth для определения местоположения символа, и нам нужно написать функцию для вычисления этого параметра для любого данного нам объекта textFormat (например, для определенного размера текста и шрифта). Это намного проще сделать с использованием textFormat.getTextExtent, так как нам не нужно создавать текстовое поле для вычисления ширины. Остановимся на этом подходе, как на более аккуратном.

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

Нам нужно иметь возможность передавать функции объект textFormat и строку, что можно реализовать следующим образом.

function charPositions(tFormat, str, depth) {
  . . . 
  }

Мы также включим параметр depth, чтобы можно было указывать его извне, предотвращая запись поверх любых других объектов.

Получение других данных о символах

  1. Создайте временное текстовое поле Dynamic Text в месте, отличном от вашего рабочего места. Установите для этого текстового поля шрифт Arial.
  2. Добавьте новый слой scripts и введите в нем следующий код.
    function charPositions(tFormat, str, depth) {
      _root.createTextField("temp", depth, 0, -300, 100, 400);
      temp.embedFonts = true;
      temp.autoSize = true;
      temp.setNewTextFormat(tFormat);
      temp.text = str;
    }

    Мы установили autoSize на значение True, поэтому поле будет изменять размер, чтобы вмещать любой помещаемый в него текст. Мы также установили параметр embedFonts на значение True, и textFormat на значение tFormat. Кроме этого, нам нужно присвоить переменную str параметру text текстового поля.

    При установке параметра embedFonts текстового поля на значение True помните, что шрифт, используемый в фильме, необходимо экспортировать. Для этого и понадобилось временное поле Dynamic Text в каком-либо другом месте. Также необходимо убедиться в том, что отмечена опция Embed Font Outlines For All Characters в диалоговом окне Character Options:


  3. Чтобы открыть диалоговое окно Character Options, просто нажмите кнопку Character: при настройке атрибутов текста в Property inspector. Для форматирования жирным или наклонным шрифтом вам понадобится другое текстовое поле, настроенное на жирный или наклонный шрифт. Вы можете сделать то же самое с помощью символа шрифта.
  4. Далее мы создадим временный массив для записи значений позиций, и тогда все будет готово для работы цикла и определения ширины строки.
    function charPositions(tFormat, str, depth) {
      _root.createTextField("temp", depth, 0, -300, 100, 400);
      temp.embedFonts = true;
      temp.autoSize = true;
      temp.setNewTextFormat(tFormat);
      temp.text = str;
      var arr = [] ;
    }
  5. Для определения позиции каждого символа надо сначала выяснять ширину всей строки, а затем местоположение каждого символа, которое будет вычисляться вычитанием ширины строки, начинающейся с данной точки, из ширины всей строки. Например, если нашей строкой является "In the manufacture", то позиция символа "m" в слове "manufacture" равна ширине "In the manufacture" минус ширина "manufacture". Добавим в цикл следующий код.
    function charPositions(tFormat, str, depth) {
      _root.createTextField("temp", depth, 0, -300, 100, 400);
      temp.embedFonts = true;
      temp.autoSize = true;
      temp. setNewTextFormat (tFormat);
      temp, text = str;
      var arr = [] ;
      //the total width of the text
      var totalWidth = temp.textWidth;
      
      for (var i = 0; i<str.length; i++) {
        temp.text = str.substr(i);
        // calculate the difference between the width to this point
        // and the total width
         arr[i] = totalWidth-temp. textWidth;
      }
    }

    В каждой итерации цикла мы перемещаемся на один символ вперед в строке и записываем строковое значение из этого символа в наше временное текстовое поле str.substr(i). Затем мы вычисляем ширину, вычитаем ее из полной ширины и записываем результат в наш массив.

  6. Далее нужно удалить созданное текстовое поле и возвратить массив:
    function charPositions(tFormat, str, depth) {
      _root.createTextField("temp", depth, 0, -300, 100, 400);
      temp.erabedFonts = true;
      temp.autoSize = true;
      temp.setNewTextFormat(tFormat);
      temp.text = str;
      var arr = [];
      var totalWidth = temp.textWidth;
      for (var i = 0; i<str.length; i++) {
        temp.text = str.substr(i);
        arr[i] = totalWidth-temp.textWidth;
      }  
      temp.removeTextField();
      return arr;
    }
  7. Наконец, вызываем функцию:
    mt = new TextFormat();
    mt.font = "Arial";
    mt.size = 45;
    
    str = "In the manufacture of safety matches, 
     softwood logs are peeled into 
       a thin continuous shaving, 
    or veneer, about one tenth of an inch thick. 
    The ribbon of wood is then cut up into splints at 
    a rate of about two million per hour. 
    These splints are soaked in a bath of sodium silicate, 
    ammonium phosphate 
       or sodium phosphate and then dried. 
    This impregnation prevents afterglow.";
    posArray = charPositions(mt, str, 1);

Сохраните фильм в файле obtainCharPos.fla и запустите его. Если вы выберете команду меню Debug > List Variables, то увидите, что массив posArray содержит значение для каждой буквы в нашей строке.

Теперь у нас есть большой список позиций по X. Далее нам нужно каким-то образом использовать эту информацию.


Игорь Хан
Игорь Хан

у меня аналогичная ситуация. Однако, если взять пример из приложения (ball_motion_04_click for trial.fla) то след остается. при этом заметил, что в моем проекте в поле "One item in library" виден кружок, в то время как в приложенном примере такого кружка нет.

Вопрос знатокам, что не так?

Александр Коргапольцев
Александр Коргапольцев

объект созданый мной упорно не желает оставлять след(единственное что добился, так это то что шарик резво гоняется за курсором) функция duplicateMovieClip остаётся не активной, т.е. следа от объекта не остаётся, но если я тоже самый код вбиваю в учебный файл всё работает, не могу понять где я ошибаюсь и почему в документе созданном заново, не работает код начиная от функции duplicateMovieClip?