Auto size text field with Actionscript 3 - actionscript-3

I am not sure if this is possible, so, please, help me out a little bit over here:
I have an image loaded into the stage:
var miC:Loader = new Loader();
miC.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
miC.load(new URLRequest("coverph.jpg"));
function onComplete(e:Event):void {
miC.width = stage.stageWidth;
miC.height = stage.stageHeight;
miC.x = 0;
miC.y = 0;
addChild(miC);
trace(miC.width, miC.height);
}
And this way the image auto size itself to perfectly match the screen resolution (I have tried it with: (all in landscape)
960dp x 720dp
640dp x 480dp
470dp x 320dp
426dp x 320dp
1196dp x 720dp
and 720dp x 720dp
They all worked fine (it won´t go over 735)
Now, my question is... let´s say that for the 1196 x 720 I have a textField, a textFormat and a legend that appears on the top of the screen (as a title):
var fmat:TextFormat = new TextFormat();
fmat.font = "Times New Roman";
fmat.size = 105;
fmat.color = "0xFF0000";
var titulo:TextField = new TextField();
titulo.x = 145;
titulo.y = 30;
titulo.width = 1290;
titulo.height = 122,10;
titulo.defaultTextFormat = fmat;
titulo.antiAliasType = AntiAliasType.ADVANCED;
titulo.text = "THE TITLE OF WHAT IM DOING";
addChild(titulo);
How do I (if possible) auto size the textField and format to keep the same proportion according to the screen resolution?

Try something like this..
titulo.autoSize = "left";
titulo.text = "THE TITLE OF WHAT IM DOING";
var txt_holder:Sprite = new Sprite();
txt_holder.addChild(titulo);
stage.addChild(txt_holder);
stage.addEventListener(Event.RESIZE, onStageResize);
function onStageResize(e:Event):void {
txt_holder.width = stage.stageWidth * 0.8; // 80% width relative to stage
txt_holder.scaleY = txt_holder.scaleX; // To keep aspectratio
txt_holder.x = stage.stageWidth / 2;
txt_holder.y = 10;
}

With a few extra settings in your app you could calculate what the scaling factors should be for the x-axis and y-axis based on what the resolution is and then set the scalex and scaley properties of the TextField.
Reference: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/text/TextField.html#propertySummary

Related

Flash: get absolute position of e.currentTarget

Okay, wasn't sure about the title.
But here's what I am trying to achieve:
Basically i am trying to do something like a quiz, where you can drag and drop the answers into a field. And if they are correkt it should snap the answer field position.
It should be something like
if(myobject.hitTestObject(targetField) && isCorrectAnswer()) {
myobject.x = targetField.x;
myobject.y = targetField.y;
}
But it's not really working.
So here is what I have:
/**
* Generating dragable answer fields based on an array.
**/
function generateAnswer():void {
// creating text format
var myFormat:TextFormat = new TextFormat();
myFormat.color = 0x0066FF;
myFormat.size = 24;
myFormat.align = TextFormatAlign.CENTER
// reference array to store all textfields
var referenceArray:Array = new Array();
// iterate through all answers in vocabListItems and generate textfields
var i:int;
for (i = 0; i < vocabListItems.length; i++) {
var answerField:TextField = new TextField();
// Setting text to current answer
answerField.text = vocabListItems[i];
answerField.width = 140;
answerField.height = 40;
answerField.x = 60+ i*150;
answerField.y = 410;
answerField.background = true;
answerField.backgroundColor = 0xffffff;
answerField.setTextFormat(myFormat);
answerField.selectable = false;
answerField.type = TextFieldType.DYNAMIC
// store the textfield in a container so drag and drop
// will work
var textContainer:Sprite = new Sprite();
textContainer.addChild(answerField);
addChild(textContainer);
referenceArray.push(textContainer);
}
for each (var item in referenceArray) {
item.addEventListener(MouseEvent.MOUSE_DOWN, startDragging);
item.addEventListener(MouseEvent.MOUSE_UP, stopDragging);
}
}
And then I start my drag
var start_x:Number;
var start_y:Number;
function startDragging(e: MouseEvent):void {
var object = e.currentTarget;
start_x = e.currentTarget.x;
start_y = e.currentTarget.y;
object.startDrag();
}
And my stop dragging
function stopDragging(e:MouseEvent):void {
e.currentTarget.stopDrag();
if (e.currentTarget.hitTestObject(targetField)) {
e.currentTarget.x = targetField.x;
e.currentTarget.y = targetField.y;
} else {
e.currentTarget.x = start_x;
e.currentTarget.y = start_y;
}
}
So the problem however is, that e.currentTarget.x is starting from 0. And not from the absolute position on the screen. Its always a relative value, so if i drag it to the targetField its x and y is something like -100, -40
If I set it to the targetField x and y it disappears somewhere in the nirvana of the screen.
targetField is in this case just a rectangle drawn on the stage with a x and y of 160
How can I position it to the absolute x and y?
Here's a screenshot
So the top field is the targetField which is only a rectangle with x 161 and y 191.
The field on the bottom are the dragable fields which are the e.currentTarget. But currentTarget.x is always 0.
EDIT
Your e.currentTarget is going to be the textContainer, which you haven't set an x/y on so it will naturally be 0.
It would seem to make more sense to move the container, and not the actual text field when you create it, like so:
for (i = 0; i < vocabListItems.length; i++) {
var answerField:TextField = new TextField();
// Setting text to current answer
answerField.text = vocabListItems[i];
answerField.width = 140;
answerField.height = 40;
//answerField.x = 60+ i*150; //don't move the text field, move the container later
//answerField.y = 410;
answerField.background = true;
answerField.backgroundColor = 0xffffff;
answerField.setTextFormat(myFormat);
answerField.selectable = false;
answerField.type = TextFieldType.DYNAMIC
// store the textfield in a container so drag and drop
// will work
var textContainer:Sprite = new Sprite();
textContainer.x = 60+ i*150;
textContainer.y = 410;
textContainer.addChild(answerField);
addChild(textContainer);
referenceArray.push(textContainer);
//Also, as an aside, there is no reason to loop through the array after this, just add the listeners here
textContainer.addEventListener(MouseEvent.MOUSE_DOWN, startDragging);
textContainer.addEventListener(MouseEvent.MOUSE_UP, stopDragging);
}
End Edit
To translate the coordinates from one object to another, you can use the localToGlobal and globalToLocal methods of a display object.
Something like this:
var globalPoint:Point = targetField.localToGlobal(new Point());
var destinationLocalPoint:Point = e.currentTarget.parent.globalToLocal(globalPoint);
e.currentTarget.x = destinationLocalPoint.x;
e.currentTarget.y = destinationLocalPoint.y;
What I'm doing here, is first, getting the global coordinates of the targetField. So it's taking a point (at 0,0) relative to targetField and translating that relative to the stage.
Then I'm making a new Point object that takes that global coordnate set, and translate that to the parent of e.currentTarget.

AS3 Why does editing a Textfield inside of a MovieClip throw all the sizes off?

I'm pretty frustrated with AS3 right now. It seems like there must be serious issues with how things scale inside of movieclips. From the stage everything seems to work fine.
On one of my projects I try to set a textfield.width equal to its container(movieclip)
tf.width = mc.width; Of course it says everything is even but when I look at the border of the textfield it's nowhere near the size of the movie clip it's contained within.
While trying to make a much smaller sample to share with you guys for help, that part worked, but trying to resize text did something completely different. Can anyone help me make sense of all this? The code below seemingly randomly starts changing the size of everything.
Also, I was trying to follow this code from here but just kept getting an error when trying to change the format size in a while loop: Autosize text to fit the width of a button
var square:MovieClip = new MovieClip();
addChild(square);
square.graphics.lineStyle(3,0x00ff00);
square.graphics.beginFill(0x0000FF);
square.graphics.drawRect(0,0,100,100);
square.graphics.endFill();
square.x = 0;
square.y = 0;
square.width = 200;
square.height = 200;
var tffSize = 400;
var tffOr:TextFormat = new TextFormat();
tffOr.size = tffSize;
tffOr.align = TextFormatAlign.CENTER;
var tf:TextField = new TextField();
square.addChild(tf);
tf.defaultTextFormat = tffOr;
tf.text = "Hello";
tf.border = true;
tf.width = square.width;
tf.height = square.height;
trace(tf.textWidth);
trace(square.width);
while (tf.textWidth > square.width || tf.textHeight > square.height)
{
trace("too Big");
newTFF();
trace(tf.textWidth + " vs " + square.width);
square.width = 200;
trace(tf.textWidth + " vs " + square.width);
}
function newTFF()
{
tffSize = tffSize - 1;
var tff:TextFormat = new TextFormat();
tff.size = tffSize;
tff.align = TextFormatAlign.CENTER;
//tf.defaultTextFormat = tff;
tf.setTextFormat(tff);
tf.autoSize = "left";
}

How to center textfield inside MovieClip (AS3)

I'm having strange problems with positioning of
1) a MovieClip() I've created with AS
2) a textfield inside this MovieClip().
Problem with 1): When I set MC.x = 0; MC.y = 0 the movieClip doesn't appear in the top left corner.
Problem with 2): The text isn't centered vertically nor horizontally.
My AS3 code:
var button:ButtonMC = new ButtonMC();
button.y = 100;
button.x = 100;
button.width = 260;
button.height = 50;
button.buttonMode = true;
button.useHandCursor = true;
button.mouseChildren = false;
var tf:TextFormat = new TextFormat();
tf.size = 70;
tf.bold = true;
tf.font = "Arial"
tf.color = 0xFFFFFF;
var myText:TextField = new TextField();
myText.defaultTextFormat = tf;
myText.autoSize = TextFieldAutoSize.CENTER;
button.addChild(myText);
myText.text = 'ThisIsATestText1234';
myText.y = button.height * 0.5 - myText.textHeight * 0.5;
addChild(button);
Since myText is already added to the button at the point where you try to get the height of the button it might screw up the calculation. Try to align the textfield first and the add it to the button.
You are also changing the width and height of the Button which changes the scale and therefor also affects how the textfield inside looks like and behaves (since it will become a child of the button)
Best way to tackle both problems at once is to create a background-clip within the button and give that the proper size. Then create the textfield and adjust it's scale according to the background. This way the button remains it original scale and won't mess up the stuff that's inside it.
Hope this helps.
PS: useHandCursor = true is not needed when you set buttonMode = true ;)
remove those lines:
button.width = 260;
button.height = 50;
and you will have easier to position text - also the buttons height is affected by added textfield so better use fixed value e.g.
myText.y = 25 - (myText.height * 0.5);

actionscrip3 textfield sizeing end centering

I am trying to get some words from xml and put them an the stage side by side in the center of the stage. I achieved this by the code below. I auto resize textfield according to text inside. But this time there comes space between words. What I accomplish is to have autoresized and adjacent words without space between them. But I could not solve the problem.
Could you please help me to solve it.
Thanks in advance
var partsWidth=100;
var wordTf = new TextField();
wordTf.name =thispart;
wordTf.text =thispart;
wordTf.width=partsWidth;
xStartPoint=stage.stageWidth / 2 - (numberOfWords * partsWidth )/2;
wordTf.height=partsHeight;
wordTf.x= xStartPoint + (index * partsWidth) ;
wordTf.y=150;
wordTf.background=true;
wordTf.backgroundColor = 0xe3e3e3;
wordTf.border = true;
var myFormat:TextFormat = new TextFormat();
myFormat.size = 16;
myFormat.align = TextFormatAlign.CENTER;
wordTf.setTextFormat(myFormat);
wordTf.autoSize=TextFieldAutoSize.CENTER;
addChild(wordTf);
you are setting the width explicit with wordTf.width=partsWidth;. this will override the autosize option. I would use the following code.
var container:Sprite = new Sprite();
var myFormat:TextFormat = new TextFormat();
myFormat.size = 16;
myFormat.align = TextFormatAlign.CENTER;
for each( var thispart:String in parts )
{
var wordTf = new TextField();
wordTf.defaultTextFormat = myFormat;
wordTf.name = thispart;
wordTf.text = thispart;
wordTf.height=partsHeight;
wordTf.background=true;
wordTf.backgroundColor = 0xe3e3e3;
wordTf.border = true;
wordTf.width = wordTf.textWidth + 4;
wordTf.y=150;
wordTf.x = container.width;
container.addChild(wordTf);
}
container.x = (stage.stageWidth - container.width) / 2;
addChild(container);
add your words to a separate sprite, and after all words added, add this sprite to the stage and center it.
The line
wordTf.width = wordTf.textWidth + 4;
is the important one. After setting the text, flash can calculate the width of the text. now set this text width (+4 is a fixed padding around the text in a text field you can't modify) as width of your textfield.

TextField Antialiasing in Flash CS3 / FP10 causing text to flicker and "bloom"?

I have run into a small graphics glitch in Flash. It seems to be both in FP9 - Exported via Flash CS3, and FP10 - Exported via the Flex 4 beta SDK.
The glitch / problem manifests itself as embedded text at a small point size "blooming" under certian conditions. It basically looks like the antialiasing becomes fatter at some level of text brightness. I have made a small test case below. (Obviously) You will need to embed the Arial font in your compiled SWF for the below code to work.
var myText:TextField = new TextField();
myText.embedFonts = true;
myText.antiAliasType = AntiAliasType.ADVANCED;
myText.autoSize = TextFieldAutoSize.LEFT;
var myFormat:TextFormat = myText.getTextFormat();
myFormat.size = 8;
myFormat.font = 'Arial';
myFormat.color = 0x663300;
myText.defaultTextFormat = myFormat;
myText.text = 'Bloom Example';
addChild(myText);
var composit:ColorTransform = new ColorTransform();
var timestamp:Number = getTimer();
function enterFrame (event:Event):void{
var n:Number = (getTimer() - timestamp) / 1000.0;
composit.redMultiplier = 1-n;
composit.greenMultiplier = 1-n;
composit.blueMultiplier = 1-n;
composit.redOffset = 250 * n;
composit.greenOffset = 250 * n;
composit.blueOffset = 0;
myText.transform.colorTransform = composit;
if ( n >= 1 ) removeEventListener(Event.ENTER_FRAME, enterFrame);
};
addEventListener(Event.ENTER_FRAME, enterFrame);
You can see an example of the problem by rolling over the graphical element here: http://bandcamp.fieldsofnoise.org/dump/bloom.swf
It's not really an option to change to AntiAliasType.NORMAL as it makes the text way less readable at this point size.
Any help finding an appropriate resolution to this problem would be appreciated.
I think when you change the brightness then you're maxing out the values for all pixels the font is rendered with including the anti-aliasing pixels. Have you tried changing the color rather than increasing the brightness? Or even applying a simple tint?