PDA

Просмотр полной версии : htmlText <img>


1uka
24.02.2009, 11:21
здраствуйте, пытаюсь вывести в текстовое поле несколько строк с внедренным в них изображением, но изображение вставляется не внутри а в начале строки, причем его вертикальное положение не соответствует положению текста этой же строки, код:


for(i=0;i<length;i++){
Text.htmlText="<div>text1<img src='symb' />text2</div>"
}


подскажите как это лечиться, где то читал статью - там описан метод где нужно вычислять длинну текста до картинки и относительно этого задавать координаты рисунка и тп, может есть какойто более простой способ ?

Fatality
24.02.2009, 11:36
Такой способ загрузки изображений, нерационален, мало того, он устарел !
Используйте класс MovieClipLoader для правильной загрузки и позиционирование изображения:
var mc_ldr:MovieClipLoader = new MovieClipLoader();
this.createEmptyMovieClip("img_mc", this.getNextHighestDepth());
function onLoadInit(mc:MovieClip)
{
mc._x = 100; //Тут координаты загружаемой картинки
mc._y = 100;
}
mc_ldr.loadClip("image.jpg", "img_mc");
mc_ldr.addListener(this);

P.S to __etc: Извиняюсь, торопился.

etc
24.02.2009, 11:39
Fatality, у вас уже 120 постов, а код оформлять вы не научились?

1uka
24.02.2009, 16:15
спасибо за ответ, но только помоему не в ту сторону пошли: мне нужно чтобы в текст можно было вставить картинки, напримар как в чате вставляются смайлы, а если мне через MovieClipLoader вставлять, это мне надо вычислять длинну части текущей строки до вставляемой картинки чтобы вычислить _x, причем еще разбивать текст на строки, тк фиг его знает как этот текст в поле перенесется ...потому и попробовал через хтмлТекст ...буду рад совету ...

KiL33
24.02.2009, 17:04
Тогда так

1uka
24.02.2009, 21:13
KiL33 - неа неподходит, я канеш согласен что я во флэш ламер, но вот хтмл\пхп\ксс писал немного, и соответственно Ваш код отличается от моего только тем, что у рисунка align=right, ну и как видно он справа от текста, а не слева как в моем примере, а мне то нужно чтоб внутри текста был ... эх, неужели нет простого решения такой задачи ? ...

KiL33
24.02.2009, 21:44
align=right, ну и как видно он справа от текста, а не слева как в моем примере

что мешает написать align=left :)

..хех, попробуй так ещё..с этим попроще будет разобраться

1uka
24.02.2009, 22:14
KiL33, ну нетоже - у тебя рисунок просто прилепает либо к правой части, либо к левой, а весь оставшийся текст просто его обтекает, а мне надо чтоб в любое место можно было воткнуть рисунок, как допустим в чате смайлы, они же там не все к краю прилепают, а куда вставил там и текст разрывают ....

KiL33
25.02.2009, 09:24
а..ну тогда почитай давным давно опубликованную статью от Aleksey Merlin. Там как раз создание чата, смайлы и всё прочее.
http://www.delphimaster.ru/articles/flash/index.html

1uka
25.02.2009, 13:11
подскажите как это лечиться, где то читал статью - там описан метод где нужно вычислять длинну текста до картинки и относительно этого задавать координаты рисунка и тп, может есть какойто более простой способ ?
- вот эта фраза из моего первого поста как раз была о этой статье :)

chingachgoog
25.02.2009, 13:34
Что поделать, аттрубут ALIGN во флеше имеет всего два значения и значит придется вычислять место, поверх которого будет отображаться смайлик.
Большой точности в координатах я добился так:
1) выделял уникальным цветом нужное место в текстовом поле (временно)
2) снимал скриншот текстового поля в битмапдату
3) с помощью getColorBoundsRect определял координаты уникального цвета в битмапдате

1uka
25.02.2009, 20:05
chingachgoog, ну ты оригинал !, мнеб такое в голову точноб не пришло :), ладно буду пытатся ченибудь придумать, если ниче не получится прийдется воспользоваться методом из статьи или твоим !, спасибо за идеи !

qazwsx
25.02.2009, 20:06
class Systems.Components.TextFieldSuite
{
private var tf:TextField;
private var smiles:Array = [];
private var str:Number = 0;

private var smilingArea:MovieClip;

private static var smile_str:Array = ['XD', ':)', ':(', ':*', '8)', ':/', ';)', ':O', ':D', '%)', ':[', ':P'];
private static var SPLIT_LINES_SYMBOL:String = String.fromCharCode('13');
private static var WORD_SPLITTER:String = ' ';
private static var SYMBOL_WIDTH:Number = 8;
private static var LINE_HEIGHT:Number = 18;
private static var SMILE_GABARITES:Number = 16.6;
private static var SMILE_Y_PADDING:Number = 0.9;
private static var SMILE_X_PADDING:Number = 5.8;

private var whitesLine:String = '';

public var active:Boolean = false;

public function TextFieldSuite(textField:TextField)
{
tf = textField;

whitesLine = generateWhitesLine();

calculateStringSize();
configuration();
}

public function get strSize():Number
{
return str;
}

public function _enabled(stat:Boolean):Void
{
smilingArea._visible = stat;
active = stat;
changeText();
}

private function configuration():Void
{
tf.onScroller = Delegate.create(this, onScroll);
}

private function onScroll():Void
{
changeText();
}

public function resizeWidth():Void
{
calculateStringSize();
changeText();
}

private function calculateStringSize():Void
{
var textField:TextField = _root.lineSplendor;
textField._width = tf._width;

var tfW:Number = textField.textWidth / 8;

str = tfW;
}

public function resizeHeight():Void
{
changeText();
}

public function htmlChanged():Void
{
var buf:String = tf.htmlText;
tf.htmlText = '';
tf.htmlText = buf;
changeText();
}

private function strRend(arg:String):Array
{

var lines:Array = []

var line:String = '';
var whitesCount:Number = 0;

var s:Array = arg.split(' ');

// //trace(s);
// //trace("ARG: " + arg);

var sLen:Number = s.length;

for (var i = 0; i < sLen; i++)
{
var word:String = s[i];
//var wLen:Number = word.length;

if (word.length > str)
{
lines.push(line + addWhites(whitesCount));
line = '';

var words:Array = strSplit(word, str);

var wordsLength:Number = words.length;

for (var j:Number = 0; j < wordsLength; j++)
{
var wrd:String = words[j];

if (wrd.length == str)
lines.push(wrd);
else
line = wrd;
}
}
else
{
if (word != '')
{
var bLine:String = line + addWhites(whitesCount) + word;
var compareLength:Number = bLine.length;

if (compareLength > str)
{
lines.push(line)
whitesCount = 0;
line = word;
}
else
{
line = bLine;
whitesCount = 0;
}
}

whitesCount++;
}
}

if (line.length != 0)
lines.push(line);

//trace("LINES: "+lines);

return lines;
}

private function addWhites(count:Number):String
{
return whitesLine.substr(0, count);
}

private function cuteText(txt:String, startLine:Number, endLine:Number):Array{

var lines:Array = [];

var spl:Array = txt.split(SPLIT_LINES_SYMBOL);

var splLen:Number = spl.length;
for (var i:Number = 0; i < splLen; i++)
{
var string:String = spl[i];

var wrapedString:Array = strRend(string);

if (wrapedString[0].length == 0 && wrapedString.length > 1)
wrapedString.shift();

//trace(wrapedString);

lines = lines.concat(wrapedString);
}

return lines.splice(startLine, endLine - startLine);
}

//qqqqqqqq rrrrrrrrrrrrrrr;E ttttttttttttttt:Q
private function addAddobTextFieldMagicFeatures(str:String):String
{

for (var i:Number = 0, condition:Boolean = true; condition; condition = str.charAt(i) == WORD_SPLITTER, i++)
{
}
//trace("STRINGI: "+str + ', \n' + str.substr(i -1 ));
return str.substr(i - 1);
}

private function strSplit(text:String, range:Number):Array
{
var ret:Array = [];

var sLen:Number = text.length;

for(;text.length != 0;)
{
var line:String = text.substr(0, range);
text = text.substr(range);

ret.push(line);
}

return ret;
}

private function changeText():Void
{
if (!active)
return;

var tStr:String = tStr = tf.text;

var sLength:Number = smiles.length;

smilingArea.removeMovieClip();
smilingArea = _root.createEmptyMovieClip('smilingArea_', 50);

var lines:Array = cuteText(tStr, tf.scroll - 1, tf.bottomScroll);

var lLen:Number = lines.length;

//trace(lines);

for (var i:Number = 0, c:Number = 0; i < lLen; i++)
{
var strings:Array = splitStr(lines[i]);

var strLen:Number = strings.length;

for (var j:Number = 0; j < strLen; j++, c++)
{
var s:String = strings[j].str;

var smile:String = strings[j].smile;

var x:Number = s.length * SYMBOL_WIDTH + tf._x + SMILE_X_PADDING;
var y:Number = i * LINE_HEIGHT + tf._y + SMILE_Y_PADDING;

var smile:MovieClip = smilingArea.attachMovie('smile_'+smile+'', 'smile'+c, 50+c, {_width:SMILE_GABARITES, _height:SMILE_GABARITES, _x:x, _y:y});

//trace("STR: "+s);
///trace("STRING LENGTH: "+sLength);
///trace("LINE: "+i);
//trace("LIN:O: "+lines[i]);

//smiles.push(smile);
}
}

}

private function splitStr(str:String):Array
{

var sLen:Number = smile_str.length;

var ret:Array = [];

for(var i:Number = 0; i<sLen; i++)
{
var smile:String = smile_str[i];

for (
var index:Number = str.indexOf(smile);
index != -1;
index = str.indexOf(smile, index + smile.length))
{
var s:String = str.substr(0, index);
ret.push({str:s, smile:smile});
}
}
return ret;
}

private function generateWhitesLine():String
{
var ret:String = ''
for (var i:Number = 0; i < 50; i++)
{
ret += ' ';
}
return ret;

}
}


smile_str - Это айди смайлов в библиотеке.
SYMBOL_WIDTH - Ширина 1 символа(Не спрашивайте как я это получил... Методоп тыка щитал P.S Использовался FixedSys size 15, P.P.S Шрифт должен быть обязательно моноширийный).
LINE_HEIGHT - Высота 1 строки(опять тоже самое...)
SMILE_GABARITES - Габариты смайла
SMILE_Y_PADDING - Дельта смайла по Y опять же помойму методом тыка щитал... %).
SMILE_X_PADDING - Дельта смайла по X
htmlChanged - Должно вызыватся при изменении текста в текстовом поле.
resizeHeight, resizeWidth - Вызываются при изменении высоты и соответственно ширины текстового поля.

Пример использования:

import Systems.Components.TextFieldSuite;

var tf:TextField = createTextField('test', 1);
var suite:TextFieldSuite = new TextFieldSuite(tf);


Смайлы будут находится над текстом но текст под ними будет выделятся. 1 Смайл тут занимает место 2х символов текста

chingachgoog
25.02.2009, 20:42
chingachgoog, ну ты оригинал


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

qazwsx
25.02.2009, 21:56
Вот смотри все точно :D

1uka
26.02.2009, 13:04
есть textField с параметром multiline, в нем текст в несколько строк делиться - как вообще из этих строк массив сделать ?, чето у меня не получается, пробовал так:


var Arr:Array = textField.text.split("\n");

qazwsx
26.02.2009, 13:10
Ну вот же я код выложил... Смотри там щитаеш символы, пробелы(волшебные пробелы адоба), переводы строк... >_<.

1uka
26.02.2009, 18:23
а можно поподробней?, я так понимаю волшебство адоба тут описывается в строке

var SPLIT_LINES_SYMBOL:String = String.fromCharCode('13');

у себя в текстфилде проверил, чтото он там не находит таких символов, да и при вставке онного тоже как перенос не воспринимает, '\n' воспринимает, но тоже не находит .... или я чтото упустил ?

qazwsx
26.02.2009, 18:44
Нет тут просто перенос строки тоже самое что и \n. Если ты не делал переводов строки в текстфилде естественно он их ненайдет. То что строка в текстовом поле перешла на следуюшую это не значит что там есть перевод строки...

1uka
01.03.2009, 19:25
спасибо за советы, сделал через getColorBoundsRect как посоветовал chingachgoog, плюс понадобилось getTextExtent, скриншотю при поступлении строки столько раз сколько объектов в строке, загоняю графику каждой строки в отдельный мувик, и при скроле оперирую уже с этими клипами, помойму нагрузка таким методом меньше, чем перебирать все слова, опятьже и точность помойму выше ....
возник вопрос в ходе работы как лучше реализовать хранение инфы о графике, которая по мере поступления новых строк выходит за пределы техстФилда, я пока сделал что у меня просто _visible = false, когда клип в таком состоянии он много памяти жрет?, или лучше загнать все его параметры в массив, и при надобности из массива создавать заново ?

qazwsx
01.03.2009, 19:39
Производительность достатачная). Хотя там можно многое улучшить. Точность, в тексте смайлы встают точно на том месте где надо. Как тут может быть точность меньше если все размеры статичны?:) Да и какая там точность нужна пользоватили будут максимально зумить мувиклип и слупой разглядывать точно листоит кратинка :D. При _visible - false памяти как нестранно уходит столькоже сколько и при true просто он не перерисовывается. Лучше сделать такой список обьектов как строка и в каждой строке будут все смайлы описаны с коориданами пока они актуальны. И относительно отображаемого текста их можно доставать из списка.

1uka
02.03.2009, 08:34
с хранением в массиве все понятно - перегоню, а на счет точности - я не досканально смотрел приведенный код, но я так понимаю если это хтмлТекст, то прийдется каждый символ проверять на формат, если конешно шрифт по умолчанию не моноширный, опять же еще не пробовал применить разные семейства шрифтов в одном ТекстФилде, может он это и не держит ...

Akhmedov
22.03.2009, 21:17
Добрый вечер!
1uka я тоже искал подобное решение, может Вам поможет это:
Вот что пишет автор:
"Недавно я запустил небольшой эксперимент с использованием Flash Player 10 text engine (FTE). Замысел был в том, чтобы работать со статичными и анимированными смайлами в тексте. Вот SmileyRenderer class, который, выполнит это. Вы можете использовать это в чате, например или в любом приложении, где вам это понадобится."


В архиве я выложил "swf" из исходников. Все исходники прилагаются, на сайте автора.

Страничка проекта: http://www.bytearray.org/?p=521
Исходники: http://code.google.com/p/smileyrenderer/downloads/list