Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 1.0/2.0 (http://www.flasher.ru/forum/forumdisplay.php?f=93)
-   -   Динамическое разделение текстового поля на символы. (http://www.flasher.ru/forum/showthread.php?t=125608)

Lobotomy 28.05.2009 12:58

Динамическое разделение текстового поля на символы.
 
Доброго дня, товарищи.

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

Моё решение:
Я разбиваю текст на отдельные символы, динамически создаю для них текстовые поля с автосайзом а в качестве шага расстояния по горизонтали для этих символов задаю их ширину.
Код AS1/AS2:

var __x = 0;
 
while (string.length>0) {
        textField = _root.createTextField("txt_"+i, i, __x, 0, 0, 0);
        textField .autoSize = true;
        textField .text = string.charAt(0);
        string = string.slice(1);
        __x+=chars[chars.length-1]._width;
        i++;
}

Столкнулся со следующей проблемой:
очень хотелось бы сохранить родное, шрифтовое расстояние между буквами. В моём примере оно не сохраняется, понятное дело.
Пытался дать дополнительный множитель на ширину буквы:
Код AS1/AS2:

__x+=chars[chars.length-1]._width/1.46;

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

Можете чем-то помочь.?
Или я зря паникую и это эстетический выпендрёж.?

Juice_Green 28.05.2009 13:14

а почему бы в конце всей сборки не вывести оригинал (текстовую фразу), а изначально ее скрыть?

Nirth 28.05.2009 13:17

А обязательно нужны текстовые поля? нельзя например заюзать BitmapData?

Lobotomy 28.05.2009 14:31

Цитата:

а почему бы в конце всей сборки не вывести оригинал (текстовую фразу), а изначально ее скрыть?
да, думал об этом. Надо будет попробовать, хотя, костыль на самом деле.
Если бы можно было задавать прозрачность отдельным буквам текста, то есть делать видимым часть текстового блока, это был бы выход: можно было бы отображать только символы, которые уже пришли на своё место.
В случае, когда символы приходят на своё место не единовременно, а потом скрываются и отображается текстовый блок, будет единовременный заметный "рывок" всех символов. Хотя, на небольших текстах/больших скоростях, наверно, это приемлемо.
это выход в том случае, если нет более гибкого варианта.
спасибо)

Цитата:

А обязательно нужны текстовые поля? нельзя например заюзать BitmapData?
Желательно именно текстовые поля, чтобы код был гибким и текст легко редактируемый, в т.ч. динамически.
Но даже если битмап, то чем это спасёт ситуацию.?

Stargazer 28.05.2009 15:36

Цитата:

Сообщение от Lobotomy (Сообщение 823874)
Желательно именно текстовые поля, чтобы код был гибким и текст легко редактируемый, в т.ч. динамически.

Код будет гибким и редактируемым, потому что битмапдату вы будете снимать с текстового поля. А вот дальше (что хотел предложить Nirth) мне тоже интересно. Снять можно. А как резать?

nOobCrafter 29.05.2009 10:44

имхо сначала режем, а потмо в битмапу) я попробовал так.
Код AS1/AS2:

import mx.transitions.Tween;
import mx.transitions.easing.*;
import flash.filters.BlurFilter;
import flash.filters.GlowFilter;
//////////////-------------- Функция появления --------------//////////////
function mcAppear(mc:MovieClip, startPos:Number, endPos:Number, time:Number):Void
{
        var mcScaleX:Tween = new Tween(mc, "_xscale", Elastic.easeOut, startPos, endPos, time, true);
        var mcScaleY:Tween = new Tween(mc, "_yscale", Elastic.easeOut, startPos, endPos, time, true);
        //var mcAlpha:Tween = new Tween(mc, "_alpha", None.easeNone, 0, 100, time, true);
        var mcDispose:Tween = new Tween(mc, "_x", Regular.easeOut, mc._x - 50, mc.xx, time, true);
}
 
function mcDisAppear(mc:MovieClip, time:Number):Void
{
        var mcAlpha:Tween = new Tween(mc, "_alpha", None.easeNone, 100, 0, time, true);
        var mcDispose:Tween = new Tween(mc, "_x", Regular.easeOut, mc._x, mc.xx + 50, time, true);
}
//////////////-------------- Функция перерисовки в битмапу --------------//////////////
function copyBitmap(mc:MovieClip, name:String):MovieClip
{
    var bmp = new flash.display.BitmapData(mc._width, mc._height, true, 0);
            bmp.draw(mc);
    var clip:MovieClip = mc._parent.createEmptyMovieClip(name, mc._parent.getNextHighestDepth());
          var bmc:MovieClip = clip.createEmptyMovieClip('bmc', 0);
                bmc.attachBitmap(bmp, 0, "none", true);
                bmc._x = - bmc._width / 2;
                bmc._y = - bmc._height / 2;
    return clip;
}
//////////////-------------- Функция заполнения --------------//////////////
function fillClip(hmc:MovieClip, str:String):Void
{
        var strArr:Array = str.split('');
        var total:Number = strArr.length;
        var offset:Number = 0;
 
        for(var i:Number = 0; i < total; i++)
        {
                var mc:MovieClip = hmc.createEmptyMovieClip('mc' + i, hmc.getNextHighestDepth());
 
                var mcFTM:TextFormat = new TextFormat();
                        mcFTM.size = 16;
                        mcFTM.bold = true;
                        mcFTM.color = 0x999999;
                        mcFTM.font = "Trebuchet";          // это линкеджй встроенного шрифта
 
                var mcTF:TextField = mc.createTextField('mcTF', 0, 0, 0, 10, 10);
                        mcTF.selectable = false;
                        mcTF.text = strArr[i];
                        mcTF.autoSize = true;
                        mcTF.embedFonts = true;            // внимание, юзаю встроенный шрифт!
                        mcTF.setTextFormat(mcFTM);
 
                var bmc:MovieClip = copyBitmap(mc, 'bmc' + i);
                        bmc._x = bmc.xx = offset;
                offset += (bmc._width + 2);
                        bmc._xscale = bmc._yscale = 0;
                        mc.removeMovieClip();
 
                setTimeout(mcAppear, 100 * i, bmc, 500, 100, 2);
        }
}
var str:String = 'I know, what you were doing last summer...';
var hmc:MovieClip = this.createEmptyMovieClip('hmc', 0);
fillClip(hmc, str);
        hmc._x = (Stage.width - hmc._width) / 2;
        hmc._y = (Stage.height - hmc._height) / 2;

только ембед фонтс юзаните

З.Ы. вопрос, как можно прикрутить допустим фильтр глоу изменяющийся тем же твином к каждому клипу-букве что бы он работал корректно? Поясню, просто прикрутить я и сам могу, проблема в том что при анимации он ведет себя не корректно и "пикселизован", кароч выглядит не как обычно и очень неадекватно. Пробую делать так:
Код AS1/AS2:

        var mcGlow:Tween = new Tween(mc, "glow", Regular.easeOut, 10, 0, time, true); 
                mcGlow.onMotionChanged = function()
                {
                        mc.filters = [new GlowFilter(0xFFFFFF, 1, glow, glow, 2, 3, false, false)];
                }


Lobotomy 30.05.2009 17:32

2 nOobCrafter
Отличный код, здорово работает.) Спасибо,

Но он не решает собственно проблемы (возможно, я не ясно объяснил её в первом посте):
Каждый шрифт имеет свои межбуквенные интервалы (кернинг). И мне хотелось бы эти интервалы сохранить при динамическом разбивании текста на отдельные символы.

Пришла в голову идея, что-то типа того:
создание текстового блока с заданным текстом => пошаговое удаление и замена последнего символа. В этом случае можно задавать _х в зависимости от ширины оставшегося блока.

Посмотрю, как работает - напишу.

Mnilionic 30.05.2009 21:34

Не костыль, а подготовительные работы :) :
Создаём тестовое текстовое поле с текстом нужным шрифтом
замерёем ширину.
Разбиваем на символы и выставляем их (так, как вы и делали раньше)
замеряем общую ширину получившихся символов.

А теперь, испльзуя разницу между широтами и считаем ваш множитель для данного шрифта.

в голове родилось, на практике не пробовал.


Часовой пояс GMT +4, время: 16:52.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.