Просмотр полной версии : Динамическое разделение текстового поля на символы.
Lobotomy
28.05.2009, 12:58
Доброго дня, товарищи.
Цель такая: есть текстовое поле, созданное динамически, или вручную. Необходимо разбить его на отдельные символы и каждый символ поместить в отдельный клип, чтобы их можно было двигать независимо друг от друга.
Скажем, для создания эффекта текста, собирающегося из букв, летящих с разных сторон.
Моё решение:
Я разбиваю текст на отдельные символы, динамически создаю для них текстовые поля с автосайзом а в качестве шага расстояния по горизонтали для этих символов задаю их ширину.
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++;
}
Столкнулся со следующей проблемой:
очень хотелось бы сохранить родное, шрифтовое расстояние между буквами. В моём примере оно не сохраняется, понятное дело.
Пытался дать дополнительный множитель на ширину буквы:
__x+=chars[chars.length-1]._width/1.46;
Результат получается более правдоподобный, возможно, приемлимый, но не достаточно точный. И, по-видимому для каждого шрифта придётся подбирать свой множитель, что не удобно.
Можете чем-то помочь.?
Или я зря паникую и это эстетический выпендрёж.?
Juice_Green
28.05.2009, 13:14
а почему бы в конце всей сборки не вывести оригинал (текстовую фразу), а изначально ее скрыть?
А обязательно нужны текстовые поля? нельзя например заюзать BitmapData?
Lobotomy
28.05.2009, 14:31
а почему бы в конце всей сборки не вывести оригинал (текстовую фразу), а изначально ее скрыть?
да, думал об этом. Надо будет попробовать, хотя, костыль на самом деле.
Если бы можно было задавать прозрачность отдельным буквам текста, то есть делать видимым часть текстового блока, это был бы выход: можно было бы отображать только символы, которые уже пришли на своё место.
В случае, когда символы приходят на своё место не единовременно, а потом скрываются и отображается текстовый блок, будет единовременный заметный "рывок" всех символов. Хотя, на небольших текстах/больших скоростях, наверно, это приемлемо.
это выход в том случае, если нет более гибкого варианта.
спасибо)
А обязательно нужны текстовые поля? нельзя например заюзать BitmapData?Желательно именно текстовые поля, чтобы код был гибким и текст легко редактируемый, в т.ч. динамически.
Но даже если битмап, то чем это спасёт ситуацию.?
Stargazer
28.05.2009, 15:36
Желательно именно текстовые поля, чтобы код был гибким и текст легко редактируемый, в т.ч. динамически.
Код будет гибким и редактируемым, потому что битмапдату вы будете снимать с текстового поля. А вот дальше (что хотел предложить Nirth) мне тоже интересно. Снять можно. А как резать?
nOobCrafter
29.05.2009, 10:44
имхо сначала режем, а потмо в битмапу) я попробовал так.
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;
только ембед фонтс юзаните
З.Ы. вопрос, как можно прикрутить допустим фильтр глоу изменяющийся тем же твином к каждому клипу-букве что бы он работал корректно? Поясню, просто прикрутить я и сам могу, проблема в том что при анимации он ведет себя не корректно и "пикселизован", кароч выглядит не как обычно и очень неадекватно. Пробую делать так:
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
Отличный код, здорово работает.) Спасибо,
Но он не решает собственно проблемы (возможно, я не ясно объяснил её в первом посте):
Каждый шрифт имеет свои межбуквенные интервалы (кернинг (http://ru.wikipedia.org/wiki/%D0%9A%D0%B5%D1%80%D0%BD%D0%B8%D0%BD%D0%B3)). И мне хотелось бы эти интервалы сохранить при динамическом разбивании текста на отдельные символы.
Пришла в голову идея, что-то типа того:
создание текстового блока с заданным текстом => пошаговое удаление и замена последнего символа. В этом случае можно задавать _х в зависимости от ширины оставшегося блока.
Посмотрю, как работает - напишу.
Mnilionic
30.05.2009, 21:34
Не костыль, а подготовительные работы :) :
Создаём тестовое текстовое поле с текстом нужным шрифтом
замерёем ширину.
Разбиваем на символы и выставляем их (так, как вы и делали раньше)
замеряем общую ширину получившихся символов.
А теперь, испльзуя разницу между широтами и считаем ваш множитель для данного шрифта.
в голове родилось, на практике не пробовал.
Работает на vBulletin ® версия 3.7.3. Copyright ©2000-2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Copyright © 1999-2008 Flasher.ru. All rights reserved.