Опубликован: 07.11.2006 | Уровень: специалист | Доступ: платный
Лекция 3:

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

Использование позиций символов

Сейчас мы создадим простой текстовый эффект с использованием полученных только что позиций. Самое сложное уже позади: основной объем работы заключался в вычислении позиций, на которых должны оказаться все символы. Теперь мы просто выберем способ, с помощью которого можно расположить символы на нужных местах.

Наш эффект будет заключаться в плавном последовательном появлении символов. Первая проблема - массив позиций содержит все символы в одной строке, а их принято отображать в нескольких строках . Этот вопрос можно решить, разделив заранее текст на две строки. Мы можем разделить строки либо вручную, либо с использованием string.split() со специальным разделителем или просто символом новой строки в качестве места, в котором строки должны быть разделены.

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

Прежде всего, получим позиции символов. Далее определим высоту каждой строки с помощью getTextExtent (точность здесь не очень важна). Затем мы создадим переменную currentLine для записи того, в какой строке находимся, и массив finalPositions со всеми конечными координатами.

Использование данных о символах для плавного появления текста

  1. Добавьте следующий ActionScript под функцией charPositions в файле
    obtainCharPos.fla.
    function setUpText(str, forma, lineLength) {
      var positions = charPositions(forma, str, 1000);
      var currentLine;
      var lineHeight = forma.getTextExtent(str).height;
      var finalPositions = [];
    }

    Далее мы добавим цикл для обработки каждой записи в массиве позиций. Этот цикл будет проверять, является ли позиция X большей, чем lineLength. Если это так, она будет сбрасываться на ноль и к переменной currentLine будет прибавляться единица для обновления позиции Y. Мы будем учитывать расстояние, на которое необходимо возвращать символы, так как все последующие символы также будут перемещены назад на то же расстояние. Это значение мы будем хранить в переменной с именем substracta.

  2. Если у нас есть символ на позиции 510, а значение lineLength равно 500, необходимо вернуть его и все последующие символы назад на 510. Если позиция X символа больше, чем 510 плюс длина строки, мы сбрасываем ее на ноль и прибавляем число позиций, которое было сброшено, в переменную substractа, для учета этого значения в сумме нарастающим итогом. Добавьте следующий выделенный код в функцию setUpText.
    function setUpText(str, forma, lineLength) {
      var positions = charPositions(forma, str, 1000);
      var currentLine;
      var subtracta;
      var lineHeight = forma.getTextExtent(str).height;
      var finalPositions = [] ;
      for (var i = 0; i<positions.length; i++) {
      // if the current position is off the right edge
        if (positions[i]>(lineLength+subtracta)) {
          subtracta = positions[i];
          currentLine++;
        }
        var x = positions[i]-subtracta;
        var у = lineHeight*currentLine;
        finalPositions[i] = {char:str.charAt(i), x:x, y:y};
      }
      return finalPositions;
    }

    Здесь мы добавили две следующие функциональности. Первая заключается в том, что мы вычисляем позицию Y, умножая значение currentLine на lineHeight ; мы передвигаем вниз страницу на высоту текста для каждой добавленной строки текста. Мы также записали наши значения символов и позиции в массив в виде объекта. Таким образом, при возвращении массива у нас будет возможность использовать его без знания строки; теперь это просто список символов.

  3. Далее мы создадим небольшую функцию инициализации для вызова функции setUpText.
    function init(str, tForm, lineLength) {
      // retrieve character positions
      charPos = setUpText(str, tForm, lineLength);
      this.count = 0;
      // set drawNext to be called every frame
      this.onEnterFrame = drawNext;
    }

    Мы будем передавать ей все соответствующие данные, и функция будет получать позиции символов для строки. По завершении ее работы мы настраиваем функцию enterFrame для _root, drawNext. Это нужно для поочередного прорисовывания каждой буквы с использованием переменной count для протоколирования.

  4. После этого мы добавляем функцию drawNext. В каждом кадре при ее вызове она будет искать следующий символ в массиве и получать его позицию. Затем она будет создавать дубликат фильма на этой позиции, а в нем текстовое поле с соответствующим символом с корректным форматированием. Затем функция устанавливает параметр интенсивности alpha на значение 30 и применяет к нему функцию onEnterFrame для постепенного увеличения интенсивности. Это все должно быть вам понятно, если вы разбирали весь рассмотренный до данного момента код. Добавьте в фильм следующий код.
    function drawNext() {
      var noo = this .createEmptyMovieClip ("lett"+count, count) ;
      var nextObj = charPos[this.count];
      // a reference to the object in the array
      noo._x = nextObj.x;
      noo._y = nextObj.y;
      noo.createTextField("tex", 1, 0, 0, 100, 100);
      noo.tex.text = nextObj.char;
      noo.tex.embedFonts = true;
      noo.tex.selectable = false;
      noo.tex.setTextFormat(mt);
      noo._alpha = 30;
      noo.onEnterFrame = function() {
        // increase alpha until 100 is reached
        this._alpha += 5;
        if (this._alpha>=100) {
          delete this.onEnterFrame;
        }
      };
      count++;
      if (count>charPos.length) {
        delete this.onEnterFrame;
      }
    }
  5. Настраиваем текстовые форматы и добавляем вызов функции init.
    mt = new TextFormat();
    mt.font = "Arial";
    mt.size = 24 ;
    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.";
    init(str, mt, 530);
  6. Сохраните файл под именем useCharPos.fla и запустите его. Помните, для его правильной работы необходимо иметь текстовое поле вне рабочего места, настроенное на используемый вами шрифт, в данном случае - Arial. Результатом вашей работы будет постепенное появление букв и плавное усиление их яркости.

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

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

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

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

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

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

Тамара Ионова
Тамара Ионова
Россия, Нижний Новгород, НГПУ, 2009
Магомед Алисултанов
Магомед Алисултанов
Россия, Волгоград, лицей 2