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

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

  1. Теперь создадим кнопки.
    function createButtons(imageArr,tF){
      _root.createEmptyMovieClip("buttonHolder",++this.depth)
      buttonHolder._x=leftPos+10;
      buttonHolder._y=topPos+imageHeight+5;
      var currx;
      for(var i=0;i<images.length;i++){
        // attach empty movieclip for button to sit in
        var nooButton=buttonHolder.createEmptyMovieClip ("button"+i,i) ;
        // place button at currx
        nooButton._x=currx;
        nooButton.item=imageArr[i];
        nooButton.createTextField("texta",1,0,0,1,1);
        nooButton.texta.autoSize=true;
        var caption = i>9 ? i+1 :"0"+(i+1);
        nooButton.texta.text=caption;
        nooButton.texta.setTextFormat(tF);
        nooButton.onPress=function(){
          _root.centerPic(this.item)
        }
        currx+=nooButton.texta.textWidth+5
      }
    }

    Создадим другой пустой фильм "buttonHolder", который будет содержать все кнопки. Расположим этот фильм справа от левого края рисунков и значительно ниже нижнего края изображений (topPos+imageHeight).

    _root.createEmptyMovieClip("buttonHolder",++this.depth);
    buttonHolder._x=leftPos+10;
    buttonHolder._y=topPos+imageHeight+5;

    Далее мы повторно проходим массив с помощью цикла, добавляя кнопку для каждого его элемента, т.е. одну кнопку для каждого изображения. Внутри каждой кнопки создаем переменную "item", предназначенную для записи ссылки на элемент в массиве рисунков, к которому он относится. Это можно использовать для получения доступа к другой информации о картинке, например о фильме, который представляет данный рисунок. Далее добавляем textField в каждую переменную с помощью объекта textFormat, только что созданного нами. Мы используем значение i для установки текста в TextField. Если значение i меньше, чем один символ, добавляем 0 впереди него. Хотя в данный момент это не относится к делу (у нас только 8 картинок), в дальнейшем можно применить это следующим образом.

    var caption = i>9 ? i+1 :"0"+ (i+1);
    nooButton.texta.text=caption;

    Мы настраиваем функцию onPress для кнопки, чтобы вызывать функцию centerPic, передавая переменную "item", созданную нами ранее. Эта функция и будет перемещать изображения.

    nooButton.onPress=function(){
      _root.centerPic(this.item)
    }

    Теперь обеспечим правильное позиционирование, увеличивая значение текущей позиции по оси X на сумму ширины TextField и небольшого дополнительного места для уверенности.

  2. Теперь нам нужно реализовать движение. Мы будем использовать для этого созданную ранее функцию slideTo.
    MovieClip.prototype.slideTo=
      function(x,y,speed,callbackObj, callbackFunc) {
      if(this.slideControl){
        var noo=this.slideControl
      }else{
        var noo=this.createEmptyMovieClip ("slideControl",++this.depth)
      }
      noo.tx=x;
      noo.ty=y;
      noo.speed=speed;
      noo.callBackObj =callBackObj;
      noo.callBackFunc=callBackFunc;
      noo.onEnterFrame=function(){
        this._parent._x+=(this.tx-this._parent._x)/this.speed;
        this._parent._y+=(this.ty-this._parent._y)/this.speed;
        if(Math.abs(this.tx-this._parent._x)<0.2 
         && Math.abs(this.ty-this._parent._y)<0.2){
          this._parent._x=this.tx;
          this._parent._y=this.ty;
          this.callBackObj[this.callBackFunc](this._parent)
          this.removeMovieClip ()
        }
      }
    }
  3. Далее добавляем функцию для инициализации процесса - centerPic.
    function centerPic(item){
      // if the picture is not already centered
      if(item!=_root.currentPicture){
        _root. currentPicture =item,-
        var mov=item.mov;
        var x=leftPos-mov._x;
        var y=imageHolder._y;
        imageHolder.slideTo(x,y,speed,this,"triggerText");
        clearText();
      }
    }

    В этой функции нам необходимо проверять, выровнена ли картинка по центру. Результат этой проверки записывается в переменную _root.currentPicture. Если это не так, берем значение _root.currentPicture и начинаем перемещать объект. Мы извлекаем фильм из переданного элемента (это была запись в массиве изображений, поэтому используем параметр mov). Затем выясняем позицию, на которую должен переместиться imageHolder, как мы делали это ранее ( leftPos минус позиция фильма по оси X ) и вызываем функцию slideTo для перемещения на эту позицию. При вызове функции slideTo мы передаем ей функцию "triggerText", которая инициализирует текстовый эффект по достижении фильмом конечной точки. Наконец, нам нужно удалить любой уже присутствующий текст. Для этого в конце программы вызываем функцию clearText.

  4. Запустив код, вы увидите, что изображения позиционируются корректно. Далее нам необходимо создать маску для сокрытия рисунков, расположенных вокруг выбранной фотографии. Это можно сделать посредством рисования api, но сейчас мы будем использовать фильм из библиотеки. Создайте новый фильм, установите параметр связывания на значение "square" и внутри него нарисуйте квадрат 100x100 пикселей с точкой закрепления в левом верхнем углу.
  5. Затем добавьте следующий код.
    function createMask(targ,x,y,wid,high){
    // create init object containing values for scale and //position
      var obj={_x:x,_y:y,_xscale:wid,_yscale:high};
      _root. attachMovie ("square","maska",++depth,obj );
      targ.setMask(maska);
    }

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

  6. Теперь рассмотрим элемент текстового эффекта. Прежде всего, мы считаем символы и позиции символов из каждой картинки. Далее проходим циклом наш массив изображений и вызываем функцию charPositions для каждого элемента, сохраняя результаты в виде characterArr внутри каждого объекта изображения.
    function setCharPositions(imageArr,tF){
      for(var i in imageArr){
        imageArr[i].characterArr=
         charPositions (tf,imageArr[i].title,10000)
      }
    }
  7. Функция charPositions была значительно изменена с тех пор, как мы имели с ней дело ранее. Я выделил те ее части, которые были изменены. В ней есть два основных отличия от прежней версии. Во-первых, функция использует textWidth и textHeight объекта TextField для выяснения места расположения всего фрагмента текста. Оно добавляется к координатам X и Y в виде смещения. Во-вторых, теперь возвращаемый функцией массив содержит объекты, у каждого из которых есть параметры для координат X и Y, а также релевантный символ.
    function charPositions(tFormat,str,depth){
      _root.createTextField("temp",depth,0,-300,100,400);
      temp.autoSize=true;
      temp.embedFonts=true;
      temp.setNewTextFormat(tFormat);
      temp.text=str;
      var arr= [];
      var totalWidth= temp. textwidth;
      var leftEdge=(stageWidth-totalWidth)/2;
      var height=temp.textHeight;
      var topEdge=(stageHeight-height)/2;
      for(var i=0;i<str.length;i++){
        temp.text=str.substr(i);
        var xp=totalWidth-temp.textwidth;
        arr[i]={x:xp+leftEdge,y:topEdge,char:str.charAt(i)};
      }
      return arr;
    }
  8. Теперь у нас есть дополнительная запись для каждого изображения в нашем массиве изображений. Далее нам нужно создать функцию triggerText для позиционирования букв. Вам уже знакомо, как это делается, из прошлого материала. Случайным образом выбирается символ из заголовка и применяется плавное увеличение интенсивности отображения. В коде ниже выделены некоторые строки, на которые следует обратить внимание.
    function triggerText(){
      depth++
      latestText=_root.createEmptyMovieClip ("textHolder"+depth, depth) ;
      latestText.characters=currentPicture.characterArr.slice();
      latestText.movs=[];
      latestText.onEnterFrame=function(){
        this.count++;
        var next=Math.floor(Math.random()* this.characters.length);
        var nextObj=this.characters[next];
        this.characters.splice(next,1);
        var noo=this.createEmptyMovieClip ("lett"+this.count,this.count);
        noo._x=nextObj.x;
        noo._y=nextObj.y;
        noo._alpha=30;
        noo.onEnterFrame=function(){
          this._alpha+=5;
          if(this._alpha>=100){
            delete this.onEnterFrame
          }
        }
        noo.createTextField("tex",1,0,0,100,100);
        noo.tex.text=nextObj.char;
        noo.tex.embedFonts=true;
        noo.tex.selectable=false;
        noo.tex.setTextFormat(_root.captionTextFormat);
          this.movs.push(noo);
          if(this.characters.length==0){
            delete this.onEnterFrame;
            return;
          }
        }
        latestText.remove=function(){
          var next=Math.floor(Math.random()*this.movs.length);
          this.movs [next] .removeMovieClip();
          this.movs.splice(next, 1);
          if(this.movs.length==0){
          this.removeMovieClip();
        }
      }
    }
    Пример 2.2.

    Следует заметить, что мы создали отдельный фильм для текстового эффекта. Он выступает как в роли главного фильма, содержащего отдельные фильмы для букв внутри себя, так и в роли управляющего фильма, т.к. буквы сначала создаются, а затем опять удаляются при переключении фотографий. Последний фильм textHolder хранится в переменной latestText. При переключении фотографий текст в latestText будет удаляться. При создании основного фильма нужно знать, какими являются все символы и в каком месте они должны быть размещены. Для получения этой информации мы используем массив символов текущей картинки. Так как мы собираемся удалять элементы этого массива, мы создаем копию массива с помощью slice в фильме, не трогая оригинал. Метод slice используется, в основном, для возврата элементов из массива между двумя точками, так, например, arr.slice (2,5) возвратит копию элементов массива с 2 по 5. При вызове его без аргументов будет возвращена копия всего массива.

    latestText.characters=currentPicture.characterArr.slice ()
  9. Последняя часть функции определяет функцию "remove" как onEnterFrame для удаления всех букв из фильма и затем самой себя по окончании данной операции. Для этого мы добавляем функцию clearText, которая и будет обеспечивать эту возможность:
    function clearText(){
      _root.latestText.onEnterFrame=_root.latestText.remove
    }
  10. Добавим строки кода, вызывающие определенные нами функции, для размещения изображений на рабочем месте, создания кнопок, вычисления позиций символов, создания маски и выравнивания по центру первого изображения.
    populatelmages(images,imageWidth);
    createButtons(images,buttonTextFormat);
    setCharPositions(images,captionTextFormat);
    createMask(imageHolder,leftPos,topPos,imageWidth,imageHeight);
    centerPic(images[0]);

Мы завершили создание расширенного интерфейса изображений. Сохраните его и запустите - все должно работать безупречно.


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

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

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

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

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