word alignment in actionscript - actionscript-3

I have a sentence as string.
internal var sentence:string = "Lorem Ipsum is simply dummy text of the printing and typesetting industry.";
Then I was separated every word and stored in an array named wordArray and apply to text field and added to stage using addChild.
for(var i:uint =0;x i< sentence.split(" ").length; i++){
wordArray.push(sentence.split(" ")[i]);
txt = new TextField();
addChild(txt);
txt.text = wordArray[i];
}
Alignement
if(i==0) { txt.x = wordArray[i].x;}
else{ txt.x = wordArray[i -1].width + wordArray[i-1].x+2};
This will align first line perfectly. I want to do with multiline with particular width like TextField.(If word exceeds the boundary limit it has to come to the next line like textField)
?

Firstly, I'll fix you mistakes.
internal var sentence:string
var sentence:String
The default access modifier is internal. You don't need to write internal here.
There is no string class/object in AS3. For strings use String.
for (var i:uint = 0;x i< sentence.split(" ").length; i++){
What is x before i <? Remove it.
In your code the sentence splits multiple times. To avoid this split your sentence once.
var splittedSentence:Array = sentence.split(" ");
for (var i: uint = 0; i < splittedSentence.length; i++)
Next.
wordArray.push(sentence.split(" ")[i]);
txt = new TextField();
addChild(txt);
txt.text = wordArray[i];
You don't need to store a substring in the wordArray. But you should store all TextFields.
txt = new TextField();
addChild(txt);
txt.text = sentence.split(" ")[i];
wordArray.push(txt);
Define variable line which stores current line of the text (from 0).
var line:int = 0;
Set autoSize property to the TextField:
txt.autoSize = TextFieldAutoSize.LEFT;
So the width and the height of the TextField will be resized after the text will be added to the TextField.
if (txt.x + txt.width > stage.stageWidth)
{
txt.x = 0;
line++;
}
If the current TextField is out of bounds, it will be moved to the next line.
Finally, set up y property of the TextField:
txt.y = txt.height * line;
Full code:
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
var sentence: String = "Lorem Ipsum is simply dummy text of the printing and typesetting industry.";
var wordArray: Array = [];
var txt: TextField;
var line:int = 0;
var splittedSentence:Array = sentence.split(" ");
for (var i: uint = 0; i < splittedSentence.length; i++)
{
txt = new TextField();
txt.autoSize = TextFieldAutoSize.LEFT;
addChild(txt);
txt.text = splittedSentence[i];
wordArray.push(txt);
if (i == 0)
txt.x = wordArray[i].x;
else
txt.x = wordArray[i - 1].width + wordArray[i - 1].x + 2;
if (txt.x + txt.width > stage.stageWidth)
{
txt.x = 0;
line++;
}
txt.y = txt.height * line;
}
The result:

I'd say use a multilined TextField with a center-aligned format.
var sentence:String="Lorem Ipsum is simply dummy text of the printing and typesetting industry.";
var altered:String=sentence.split(" ").join("\n");
var ta:TextField=new TextField();
ta.multiline=true; // makes a text area out of a text field, necessary
var tf:TextFormat=new TextFormat("Arial",12); // whatever
tf.align=TextFormatAlign.CENTER; // necessary
ta.defaultTextFormat=tf;
ta.text=altered;
addChild(ta);
// now we can get proper text height and actually do whatever we wish.
And if you are missing word wrap functionality, you should not use altered but use original sentence, and set ta.wordWrap=true;.

Related

Generate random password using Google app script

I am using below function to generate random string. But if i run this twice, it will give the string as new string=old string+oldstring
But i need a unique string of same size. How can i do this??
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!##$%&<>*-";
for(var j=2;j<=data.length;j++){
for(var i=0;i<length;i++){
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
ss.getRange(j,2).setValue(text);
Logger.log(text);
}
The variable text needs to be reset on every loop:
function generateRandom() {
var data = "ldk";
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!##$%&<>*-";
for(var j=2;j<=data.length;j++){
text = ""; //Reset text to empty string
for(var i=0;i<possible.length;i++){
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
//ss.getRange(j,2).setValue(text);
Logger.log(text);
}
}

myTextField.text does not return any value

I'm trying to make a numberline with boxes pointing at different values. Inside each box is a TextField where the user is supposed to wright down the value the box is pointing at. When all the boxes are filled out, the answere in the boxes should be compared to the correct answeres.
The problem is that when I try to acsess the text in the textField, 1-2 of them randomly won't return any values. The TextFields that don't respond are also impossible to edit and navigate inside after a number is filled out.
This is the code where I construct the textField:
var textFields:Array = [];
var box:Sprite = new Sprite();
var tfor:TextFormat = new TextFormat();
for (var i:int = 0; i<3; i++)
{
tfor.size = 30;
var tfb:TextField = new TextField();
tfb.defaultTextFormat = tfor;
tfb.width = boxWidth;
tfb.height = boxWidth;
tfb.maxChars = 3;
tfb.text = "";
tfb.restrict = "0-9.";
tfb.multiline = false;
tfb.x = bx;
tfb.y = by;
tfb.selectable = true;
tfb.type = TextFieldType.INPUT;
box.addChild(tfb);
textFields.push(tfb);
}
And this is where I check the answere:
public function checkBoxAnswere(numbs:Array) {
var points:Number = 0;
for(var i:int = 0; i<textFields.length; i++) {
trace("numb:"+numbs[i]+"arrowText "+textFields[i].text+" .");
//begDes is a function whitch round a value mutch like the .toFixed(number) but returns a number insted of a string
if(begDes(numbs[i], 2)==begDes(Number(textFields[i].text), 2)) {
points+= 0.5;
}
}
return points;
}
It is the textField.text that wont be read. There is no error massenges.

Change Text Size and Keep Text Vertically Centered

How can I change the textSize of a dynamic text field and keep the text resting on the baseline? When I call this function and it affects the size of the text, the text gradually rises upwards within the text field as the text size decreases.
function autoFormatSize(myTextField)
{
if (! textFormat && ! textSize)
{
var textFormat:TextFormat = new TextFormat();
var textSize:int = new int();
}
textFormat.size = 50;
textSize = 50;
for (var i=0; myTextField.textWidth>myTextField.width-10; i++)
{
textSize--;
textFormat.size = textSize;
myTextField.setTextFormat(textFormat);
}
}
UPDATE
Here's a visual illustration of what I'm trying to do:
Use textHeight to get the height of the text. Here is how you'd position a textfield over an mc of a line:
var tfMain: TextFormat = new TextFormat();
tfMain.size = 100;
tMain.setTextFormat(tfMain);
trace(tMain.textHeight);
tMain.y = Math.ceil(mcUnderline.y - tMain.textHeight);
Use ceil to make sure it's on the x.
Create a Sprite and added it to stage, then align your TexField based on the Sprite. As coded below
with(bg.graphics) {
clear();
beginFill(0xeeeeee, 1);
lineStyle(1, 0x999999);
drawRect(0, 0, 200, 30);
endFill();
}
txt.x = bg.x + bg.width/2 - txt.width/2;
txt.y = bg.y + bg.height/2 - txt.height/2;
Considering your comment, have you thought about using autoSize instead? Something like:
var tf:TextField = yourTextField; //on timeline
tf.autoSize = TextFieldAutoSize.LEFT;
var textFormat:TextFormat = new TextFormat();
textFormat.size = 14;
var oldY:Number = tf.y + tf.height;
tf.setTextFormat(textFormat);
tf.y = oldY - tf.height;
To adjust your text to your text field, you have to consider a 2px gutter for each side of the text, so your function can be like this :
function autoFormatSize(myTextField)
{
var gutter:int = 2 * 2; // 4px
var textSize:int = 50;
var textFormat:TextFormat = new TextFormat();
textFormat.size = textSize;
for (var i:int = 0; myTextField.textWidth > myTextField.width - gutter; i++)
{
textSize --;
textFormat.size = textSize;
myTextField.setTextFormat(textFormat);
}
myTextField.height = myTextField.textHeight + gutter;
}
Hope that can help.

Showing randomly sorted array over multiple text fields

I have a randomly sorted array of, say, 3 items. Instead of displaying all 3 items in one dynamic text box (see code below), I'd like to display each item across 3 different text boxes. How might I go about doing this?
var Questions:Array = new Array;
Questions[0] = "<b><p>Where Were You Born?</p><br/>";
Questions[1] = "<b><p>What is Your Name?</p><br/>";
Questions[2] = "<b><p>When is Your Birthday?</p><br/>";
function randomize (a:*, b:*): int {
return (Math.random() > .5) ? 1: -1;
}
questions_txtbox.htmlText = Questions.toString() && Questions.join("");
The following code accomplishes what you were asking for, although the shuffling function is crude, it gets the job done. I also dynamically generated the three Text Fields as opposed to creating them on the stage and giving them unique instance names, so you will need to adjust the x/y coordinates for these new textfields as you see fit. I tested this on Flash CC 2014 and it worked properly.
import flash.text.TextField;
var Questions:Array = new Array();
Questions[0] = "<b><p>Where Were You Born?</p><br/>";
Questions[1] = "<b><p>What is Your Name?</p><br/>";
Questions[2] = "<b><p>When is Your Birthday?</p><br/>";
var shuffleAttempts:int = 10 * Questions.length;
var questionTextFields:Array = new Array(3);
function randomize (a:*, b:*): int {
return (Math.random() > .5) ? 1: -1;
}
function shuffleQuestions(arr:Array):void {
var temp:String;
for(var i:int = 0; i < shuffleAttempts; i++ ) {
var randIndex1:int = Math.floor(Math.random() * Questions.length);
var randIndex2:int = Math.floor(Math.random() * Questions.length);
if( randIndex1 != randIndex2 ) {
temp = Questions[randIndex1];
Questions[randIndex1] = Questions[randIndex2];
Questions[randIndex2] = temp;
}
}
}
shuffleQuestions(Questions); // shuffle question list
for( var questionIndex:int = 0; questionIndex < 3; questionIndex++ ) {
if( questionIndex < Questions.length ) {
var questionField = new TextField(); // create new text field
questionField.htmlText = Questions[questionIndex]; // take a question from the questions list and set the text fields text property
questionField.y = questionIndex * 20; // move the text field so that it does not overlap another text field
questionField.autoSize = "left"; // autosize the text field to ensure all the text is readable
questionTextFields[questionIndex] = questionField; // store reference to question textfield instance in array for later use.
addChild(questionField); // add textfield to stage
}
}

Character boundaries of text field based on parent

I have a text field inside a container. I'm wondering is it possible to find the boundaries of each character based on the container and not the text field.
Here is a sample screen shot:
And normal state would be like this:
With this I can find the bounds of each character based on text field, But I need it based on the container:
var rect:Rectangle = new Rectangle();
for (var i:int = 0; i < textField.length; i++){
rect = textField.getCharBoundaries(i);
}
Is there anybody whom has an experience on this?
I believe you have to make use of Point conversions.
var rect:Rectangle = new Rectangle();
for (var i:int = 0; i < textField.length; i++){
rect = textField.getCharBoundaries(i);
var globalTopLeft:Point = textField.localToGlobal(rect.topLeft);
var globalBottomRight:Point = textField.localToGlobal(rect.bottomRight);
var containerTopLeft:Point = container.globalToLocal(globalTopLeft);
var containerBottomRight:Point = container.globalToLocal(globalBottomRight);
rect = new Rectangle(containerTopLeft.x,containerTopLeft.y,containerBottomRight.x-containerTopLeft.x,containerBottomRight.y-containerTopLeft.y)
}
If the TextField is a child of the container and the TextField is not scaled, you can just do:
rect = textField.getCharBoundaries(i);
rect.x += textField.parent.x;
rect.y += textField.parent.y;