creating dynamic rectangle - actionscript-3

I'm wondering how I can create a dynamic rectangle which has some text in it, the text is dynamic so the rectangle has to adapt to the length of the text. Any ideas on how to approach this?

here is a basic one for single line text:
import flash.display.Sprite;
import flash.text.TextField;
var rectClip:Sprite = new Sprite();
var rect:Sprite = new Sprite;
rect.graphics.beginFill(0xff0000, 1);
rect.graphics.drawRect(0, 0, 100, 100);
rect.graphics.endFill();
var tf:TextField = new TextField();
tf.autoSize = "left";
tf.text = "Lorem ipsum dolor sit amet...";
addChild(rectClip);
rectClip.addChild(rect);
rectClip.addChild(tf);
rect.width = tf.textWidth + 12;
rect.height = tf.textHeight + 12;
tf.x = Math.round(rect.width/2 - tf.width/2);
tf.y = Math.round(rect.height/2 - tf.height/2);
Rob

Another way if you want to draw your rectangle in Flash instead of actionscript (although the above way might be more useful).
Create a layer with a rectangle.
Make the rectangle some sort of graphic or sprite and set it to 9-slice scaling. This way the rectangle will scale properly with the textbox (good if it's a rounded rectangle)
Also choose Linkage for the rectangle and give it a class name (say, "Background")
public var textBackground:Background; // can make public or private depending if you leave it on the stage or generate it
private var myTextField:TextField;
Then have two functions:
private function createTextField():void
{
// create your textfield here using actionscript
myTextField = new TextField();
// customize your textfield
}
private function createTextBackground():void
{
textBackground = new Background;
textBackground.height = myTextField.height + 20;
}
Then:
createTextField();
createTextBackground();
addChild(textBackground);
addChild(myTextField);
I usually change the height depending on the text and set the width to a fixed width and set my positioning how I like.

If the TextField is multiline, you will need to set a fixed width , you can then determine the TextField height after it's been formatted.
private var format:TextFormat = new TextFormat();
private var textWidth:int = 300;
private var hPadding:int = 10;
private var vPadding:int = 10;
private var boxColor:uint = 0x990000;
private function init():void
{
var tf:TextField = getTextField("Your text..........etc...");
tf.x = hPadding;
tf.y = vPadding;
var rectWidth:int = textWidth + ( hPadding * 2);
var rectHeight:int = tf.textHeight + ( vPadding * 2);
var container:Sprite = getTextContainer( rectWidth , rectHeight );
container.addChild( tf );
}
private function getTextField( text:String ):TextField
{
var tf:TextField = new TextField();
tf.defaultTextFormat = format;
tf.autoSize = TextFieldAutoSize.LEFT;
tf.multiline = true;
tf.width = textWidth;
tf.text = text;
// etc...
return tf;
}
private function getTextContainer(width:int , height:int ):Sprite
{
var sp:Sprite = new Sprite();
with( sp.graphics )
{
beginFill( boxColor );
drawRect( 0 , 0 , width , height );
endFill();
}
return sp;
}

Related

distortion in textField

I have a bitmap data which draw a text field. after scaling, text are distortion.
I using following code:
// tf is text Field and bm is bitmap.
var tf:TextField = new TextField();
tf.text = "Hello world";
var bd:BitmapData = new BitmapData(200, 200, true, 0x00ff00);
bd.draw(tf);
var bm:Bitmap = new Bitmap(bd);
addChild(bm);
bm.scaleX = 2;
bm.scaleY = 2;
Please guide me.
You should use transform matrix to draw an upscaled text field (or any other vector graphics object) onto a BitmapData.
var mat:Matrix=new Matrix();
mat.scale(2.0,2.0);
bd.draw(tf,mat);
First, increase the font size and then convert and scale as bitmap like so,
//---- Text format ----
var textFormat:TextFormat = new TextFormat();
textFormat.font = "Arial";
//textFormat.bold = true;
textFormat.size = 40;
//---------------------------------------------
//
var tf:TextField = new TextField();
tf.text = "Hello world";
/*tf.antiAliasType = AntiAliasType.ADVANCED;
tf.gridFitType = GridFitType.PIXEL;
tf.thickness = 0;
tf.sharpness = 0;*/
tf.setTextFormat(textFormat);
//
//
var bd:BitmapData = new BitmapData(200,200,true,0x00ff00);
bd.draw(tf);
var bm:Bitmap = new Bitmap(bd);
bm.smoothing = true;
addChild(bm);
bm.scaleX = 2;
bm.scaleY = 2;
Best luck.

AS3 bitmapdata.draw without adding to display list/ Stage

I want to be able to cahce HTML text as bitmap, for use in AlivePDF. My testing works well with TextArea or if the component is on the Stage or visible. But I want to be able to crunch text blocks that dont necessarily sit on screen. Does anyone know how to do this?
What I have failing so far
public static function rasterizeText( text:String, width:int = 100, height:int = 100, x:int = 0, y:int = 0 ):BitmapData {
var textRenderer:TextArea = new TextArea();
textRenderer.width = width;
textRenderer.height = height;
textRenderer.htmlText = text;
var bitdata:BitmapData = new BitmapData(width, height, true, 0xFF000000)
bitdata.draw( textRenderer );
return bitdata;
}
Your code should work fine. There is no need to add textRenderer to the stage in order to draw it into the BitmapData. You are drawing your textRenderer onto a solid black background. Maybe your text is also black and that is why you can not see it?
Try changing 0xFF000000 to e.g. 0xFFFF0000 and see if the text will show up.
No it wasn't a color issue. Also I had the color set to FF000000 which at least should have been showing up black. TextArea didn't seem to play nice with bitmaps, although TextField works perfectly fine.
Edit: I'm guessing TextArea wasn't working as spark or mx because they're a FlexSprite thingy, which act differently to normal AS3 Sprites. They'll defer rendering until they're added to the display list.
Working function:
public function rasterizeText( text:String,
width:int = 100, height:int = 100 ):BitmapData {
var tf:TextField = new TextField();
tf.multiline = true;
tf.wordWrap = true;
tf.width = width;
tf.height = height;
tf.htmlText = text;
var bd:BitmapData = new BitmapData(width, height, true,0x00000000);
bd.draw(tf);
return bd;
}
This was not working (I tried mx & spark textarea components):
public function rasterizeText( text:String,
width:int = 100, height:int = 100 ):BitmapData {
var textRenderer:TextArea = new TextArea();
textRenderer.width = width;
textRenderer.height = height;
textRenderer.textFlow = TextConverter.importToFlow( text, TextConverter.TEXT_FIELD_HTML_FORMAT );
var bitdata:BitmapData = new BitmapData( width, height, false, 0xFF000000 )
bitdata.draw( textRenderer );
return bitdata;
}
However it would work when drawing from the Stage:
public function rasterizeText( text:String,
width:int = 100, height:int = 100 ):BitmapData {
var textRenderer:TextArea = new TextArea();
textRenderer.width = width;
textRenderer.height = height;
textRenderer.textFlow = TextConverter.importToFlow( text, TextConverter.TEXT_FIELD_HTML_FORMAT );
canvas.addElement( textRenderer );
var bitdata:BitmapData = new BitmapData( width, height, false, 0xFF000000 )
bitdata.draw( canvas );
return bitdata;
}

Detect Line Break in AS3 Input TextField

I want to be able to write a paragraph in a textfield, and then click and hold, or do some similar gesture, and have the entire paragraph selected. I'm then going to drag it (using bitmapdata or whatever) to another textfield.
In order to do this, I need to be able to detect where a given paragraph ends. So I'm trying to do that with the following code, which searches for "\n" in the text. It isn't finding it. Can anyone see why (or suggest another technique for doing this)?
TIA,
David
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.text.TextFieldType;
import view.controls.CustomButton;
public class Main extends Sprite
{
private var bt:CustomButton;
private var tf:TextField;
public function Main()
{
tf = new TextField();
tf.name = "tfield";
tf.type = TextFieldType.INPUT;
tf.width = 400;
tf.height = 200;
tf.x = 100;
tf.y = 100;
tf.selectable = true;
tf.border = true;
tf.background = true;
tf.backgroundColor = 0xFFFFFF;
tf.multiline = true;
tf.text = "Like most of the things I get excited about and share with you, this technique really doesn’t have much to it, but I love its elegance, how it works in the background and gets out of your way. While it’s really simple I think this one is a real gem, ’cause when you look at a class that uses it, it looks like magic!\n\nOkay, so you know how when you’re writing a site or app that’s of a small to medium scale, you default to storing data in XML, and you map that XML to model classes, usually pretty directly? Or, maybe you use a configuration file for your site to load in some constants or something, and XML is a pretty easy choice for this. With E4X you can really parse through that XML quickly.";
tf.wordWrap = true;
addChild(tf);
bt = new CustomButton("Detect", 0xFFFFFF, 0x000000,50,20);
bt.x = 250;
bt.y = 350;
addChild(bt);
addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event):void
{
bt.addEventListener(MouseEvent.CLICK, clickHandler);
}
private function clickHandler(e:MouseEvent):void
{
var lineBreak:int = tf.text.indexOf("\n");
trace(lineBreak);
}
}
}
//custom button class
package view.controls
{
import flash.display.GradientType;
import flash.display.SimpleButton;
import flash.display.Sprite;
import flash.display.Stage;
import flash.events.Event;
import flash.geom.Matrix;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
public class CustomButton extends Sprite
{
private var textColor:uint = 0x000000;
private var myColor:uint = 0xFEEE9E9;
private var btnWidth:Number;
private var btnHeight:Number;
public function CustomButton(buttonText:String, gradientColor:uint, borderColor:uint, myBtnWidth:Number, myBtnHeight:Number)
{
var colors:Array = new Array();
var alphas:Array = new Array(1, 1);
var ratios:Array = new Array(0, 255);
var gradientMatrix:Matrix = new Matrix();
var lineThickness:Number = 1;
//var myColor:uint = 0xFF0000;
gradientMatrix.createGradientBox(myBtnWidth, myBtnHeight, Math.PI/2, 0, 0);
this.btnWidth = myBtnWidth;
this.btnHeight = myBtnHeight;
var ellipseSize:int = 20;
var btnUpState:Sprite = new Sprite();
colors = [0xFFFFFF, myColor];
//btnUpState.graphics.lineStyle(1, brightencolor(myColor, -500));
btnUpState.graphics.lineStyle(lineThickness, borderColor);
btnUpState.graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, gradientMatrix);
btnUpState.graphics.drawRoundRect(0, 0, myBtnWidth, myBtnHeight, ellipseSize, ellipseSize);
btnUpState.addChild(createButtonTextField(buttonText, textColor));
//
var btnOverState:Sprite = new Sprite();
colors = [0xFFFFFF, brightencolor(myColor, 50)];
//btnOverState.graphics.lineStyle(1, brightencolor(myColor, -50));
btnOverState.graphics.lineStyle(lineThickness, borderColor);
btnOverState.graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, gradientMatrix);
btnOverState.graphics.drawRoundRect(0, 0, myBtnWidth, myBtnHeight, ellipseSize, ellipseSize);
btnOverState.addChild(createButtonTextField(buttonText, textColor))
//
var btnDownState:Sprite = new Sprite();
//colors = [brightencolor(myColor, -15), brightencolor(myColor, 50)];
btnDownState.graphics.lineStyle(lineThickness, borderColor);
btnDownState.graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, gradientMatrix);
btnDownState.graphics.drawRoundRect(0, 0, myBtnWidth, myBtnHeight, ellipseSize, ellipseSize);
btnDownState.addChild(createButtonTextField(buttonText, textColor))
//
this.btnWidth = myBtnWidth;
this.btnHeight = myBtnHeight;
var myButton:SimpleButton = new SimpleButton(btnUpState, btnOverState, btnDownState, btnOverState);
myButton.name = buttonText;
addChild(myButton);
}
private function createButtonTextField(Text:String, textcolor:uint):TextField {
var myTextField:TextField = new TextField();
myTextField.textColor = textcolor;
myTextField.selectable = false;
myTextField.width = btnWidth;
myTextField.height = btnHeight;
var myTextFormat:TextFormat = new TextFormat();
myTextFormat.align = TextFormatAlign.CENTER;
myTextFormat.font = "Arial";
myTextFormat.size = 12;
myTextField.defaultTextFormat = myTextFormat;
myTextField.text = Text;
myTextField.x = (btnWidth/2)-(myTextField.width/2);
myTextField.y = 1;
return myTextField;
}
private function brightencolor(color:int, modifier:int):int {
var hex:Array = hexToRGB(color);
var red:int = keepInBounds(hex[0]+modifier);
var green:int = keepInBounds(hex[1]+modifier);
var blue:int = keepInBounds(hex[2]+modifier);
return RGBToHex(red, green, blue);
}
private function hexToRGB (hex:uint):Array {
var colors:Array = new Array();
colors.push(hex >> 16);
var temp:uint = hex ^ colors[0] << 16;
colors.push(temp >> 8);
colors.push(temp ^ colors[1] << 8);
return colors;
}
private function keepInBounds(number:int):int {
if (number < 0) number = 0;
if (number > 255) number = 255;
return number;
}
private function RGBToHex(uR:int, uG:int, uB:int):int {
var uColor:uint;
uColor = (uR & 255) << 16;
uColor += (uG & 255) << 8;
uColor += (uB & 255);
return uColor;
}
}
}
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.display.Sprite;
import flash.events.MouseEvent;
var tf:TextField = new TextField();
tf.type = TextFieldType.INPUT;
tf.width = 400;
tf.height = 200;
tf.x = stage.stageWidth / 2 - tf.width / 2;
tf.y = stage.stageHeight / 2 - tf.height / 2;
tf.selectable = true;
tf.border = true;
tf.background = true;
tf.backgroundColor = 0xCCCCCC;
tf.multiline = true;
tf.wordWrap = true;
tf.text = "Enter text here, hit enter to create new paragraphs."
stage.addChild(tf);
var pushme:Sprite = new Sprite();
pushme.graphics.beginFill(0xCCCCCC, 1);
pushme.graphics.drawRect(0, 0, 100, 25);
pushme.graphics.endFill();
pushme.buttonMode = true;
pushme.addEventListener(MouseEvent.CLICK, pushedme);
pushme.x = tf.x + tf.width - pushme.width;
pushme.y = tf.y + tf.height + 15;
stage.addChild(pushme);
function pushedme(e:MouseEvent):void {
var paragraphCounter:int = 1;
var curParagraphOffset:int = -1;
for (var i:int = 0; i < tf.numLines; i++) {
if (tf.getFirstCharInParagraph(tf.getLineOffset(i)) == tf.getLineOffset(i) && tf.getFirstCharInParagraph(tf.getLineOffset(i)) > curParagraphOffset) {
trace("Paragraph " + paragraphCounter + " text: \n" + tf.text.substr(tf.getFirstCharInParagraph(tf.getLineOffset(i)), tf.getParagraphLength(tf.getFirstCharInParagraph(tf.getLineOffset(i)))));
paragraphCounter++;
curParagraphOffset = tf.getFirstCharInParagraph(tf.getLineOffset(i));
}
}
}
Paragraph Detection
Step by step
You can probably take it from here and ignore the empty paragraphs, but to explain:
Setup textfield, input more text manually (as shown)
Create the button to check for paragraphs
Set paragraph counter to 1 so it outputs properly for the first detected paragraph
Paragraph offset needs to be -1 for the if statement to be satisfied for the first iteration as the first paragraph should be at character 0
If the first character in the paragraph is also the first character on this line and we're not part of the previous paragraph, we have a new paragraph on this line.
Output the paragraph text based on the first character and the length of the paragraph by taking a substring of the tf.text property.
Increment paragraphCounter and set the curParagraphOffset to the new first character index.
If you want to be able to click and hold on a given paragraph, all you need to do is call:
tf.getCharIndexAtPoint(x, y)
on click of your text field. You can then find the first character in that paragraph, grab the substring based on the paragraph length, and go from there.
Hope this helps!

How to create a light effect inside a rectangle in Actionscript 3?

I have tried to do this here http://wonderfl.net/c/9Kdv but what I want is not this
alt text http://reboltutorial.com/images/flash-banner-trial.png
but rather the equivalent of this. As I'm flash newbie I don't see how:
(source: reboltutorial.com)
action script 3 code below:
package {
import flash.display.*;
import flash.text.*;
import flash.net.URLRequest;
import flash.filters.*;
import flash.geom.Rectangle;
public class FlashTest extends Sprite {
public function FlashTest() {
var mc:MovieClip = new MovieClip();
mc.graphics.beginFill(0x400000);
mc.graphics.drawRoundRect(0, 0, 278, 170,25,25);
mc.graphics.endFill();
mc.x = 80;
mc.y = 60;
addChild(mc);
//from tut http://blog.0tutor.com/post.aspx?id=116
var filt:GlowFilter = new GlowFilter();
var filt_shadow:DropShadowFilter = new DropShadowFilter();
//here we add some properties to the two filters, the glow filter we give a color.
filt.color = 0xFF0000;
//and how much it should blur.
filt.blurX = 7;
filt.blurY = 7;
//then the dropshadow filter, also how much it should blur on the object.
filt_shadow.blurX = 4;
filt_shadow.blurY = 4;
//and finally an alpha, the alpha goes from 1 to 0, 1 being fully visible and 0 is transparent, then of cause .5 is just in between.
filt_shadow.alpha = .4;
mc.filters = [filt,filt_shadow];
var theTextField:TextField = new TextField();
theTextField.border = false;
theTextField.x = 30;
theTextField.y = 50;
theTextField.autoSize = TextFieldAutoSize.LEFT;
theTextField.text = "Experiment";
var myformat:TextFormat = new TextFormat();
myformat.color = 0xFFFFFF;
myformat.size =24;
myformat.align="center";
myformat.font = "Impact";
theTextField.setTextFormat(myformat);
mc.addChild(theTextField);
var url:String = "//www.rebol.com/graphics/reb-logo.gif";
var urlReq:URLRequest = new URLRequest(url);
var ldr:Loader = new Loader();
ldr.load(urlReq);
ldr.x=30;
ldr.y=88;
mc.addChild(ldr);
}
}
}
Instead of this line:
mc.graphics.beginFill(0x400000);
you can use beginGradientFill with the fillType set to GradientType.RADIAL. You would just need to adjust the focalPointRatio to make it offcenter. Check out the example in the docs for how to do this.

ActionScript 3.0 Getting Size/Coordinates From Loader Content

i'm attempting to position a textfield to the bottom left of an image that is added to the display list from the Loader() class. i don't know how to access the width/height information of the image.
var dragSprite:Sprite = new Sprite();
this.addChild(dragSprite);
var imageLoader:Loader = new Loader();
imageLoader.load(new URLRequest("picture.jpg"));
imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, displayPic, false, 0, true);
function displayPic(evt:Event):void
{
dragSprite.addChild(evt.target.content);
evt.target.removeEventListener(Event.COMPLETE, displayPic);
}
var tf:TextField = new TextField();
tf.text = "Picture Title";
tf.width = 200;
tf.height = 14;
tf.x //same x coordinate of dragSprite
tf.y //same y coordinate of dragSprite, plus picture height, plus gap between picture and text
addChild(tf);
within the displayPic function, i could assign the evt.target.content.height and evt.target.content.width to variables that i could use to position the text field, but i assume there is a more appropriate and direct way?
There is no direct way since you have to wait the image to be loaded to access width, and height.
But you can place you text as soon as the complete is done if it`s fit your design. Store the value into some var so you can reuse it when moving the sprite.
//...
var tf:TextField = new TextField();
tf.text = "Picture Title";
tf.width = 200;
tf.height = 14;
addChild(tf);
var imageLoader:Loader = new Loader();
imageLoader.load(new URLRequest("picture.jpg"));
imageLoader.contentLoaderInfo.addEventListener(
Event.COMPLETE, displayPic, false, 0, true
);
var offsetX:Number=0;
var offsetY:Number=0;
function positionText():void {
tf.x=dragSprite.x + offsetX;
tf.y=dragSprite.y + offsetY;
}
function displayPic(evt:Event):void {
var li:LoaderInfo=evt.target as LoaderInfo;
if (li===null)
return;
li.removeEventListener(Event.COMPLETE, displayPic);
var dob:DisplayObject=li.content;
if (dob!==null) {
dragSprite.addChild(dob);
// set only once the offset depending on the loaded image
offsetX = ...//
offsetY = dob.height+gap //...
// position text using the offset setted
// so you can reuse the function when moving your sprite
positionText();
}
}