ActionScript 3.0 Getting Size/Coordinates From Loader Content - actionscript-3

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();
}
}

Related

Remove sprite from stage in as3

I have this code for a message to appear on stage when player finishes drag and drop. I would like this sprite to be removed when a button is clicked for the next frame. Can someone help me with the code?
stage.addEventListener(Event.ENTER_FRAME, EntFrame);
function EntFrame (e:Event):void
{
if (CntP1+CntP2+CntP3+CntP4+CntP5+CntP6+CntP7+CntP8 == 40)
{
var w:int = 400, h:int = 200;
var win:Sprite = new Sprite();
win.name = "Mywin";
addChild(win);
// draw rounded rect with subtle vertical linear gradient fill and blue stroke
win.graphics.lineStyle(4,0x0077ff);
var mat:Matrix = new Matrix();
mat.createGradientBox(w, h, 90 * (Math.PI / 180));
win.graphics.beginGradientFill(GradientType.LINEAR,[0xffffff,0xeeeeee],[1.00,1.00],[0,255],mat);
win.graphics.drawRoundRect(0,0,w,h,15,15);
// show center "YOU WIN!" text
var tf:TextField = new TextField();
tf.autoSize = TextFieldAutoSize.LEFT;
tf.antiAliasType = AntiAliasType.ADVANCED;
tf.defaultTextFormat = new TextFormat("Arial, Verdana",36,0x454545,true);
tf.text = "Κέρδισες!";
tf.selectable = false;
win.addChild(tf);
tf.x = w/2 - tf.width/2;
tf.y = h/2 - tf.height/2;
// add a drop shadow
var dropShadow:DropShadowFilter = new DropShadowFilter(3,45,0,.35,8,8,1,3);
win.filters = [dropShadow];
// center the graphic
win.x = stage.stageWidth/2 - win.width/2;
win.y = stage.stageHeight/2 - win.height/2;
}
}
Your code isn't written well and needs rewriting to ensure reuse or scalability of your project, but here's a quick way out.
make a holder Sprite, something like
var messageHolder:Sprite = new Sprite();
addChild(messageHolder);
add all the messages to that holder in any fashion you like. When you need to erase the contents of that holder, call following method:
function clearHolderContents(holder:DisplayObjectContainer):void
{
if (holder.numChildren < 1)
return; // no need to continue this method if the target is empty
for (var i:int = holder.numChildren - 1; i >= 0; i--)
removeChild(holder.getChildAt(i));
}
This method can clear contents of any DisplayObjectContainer => use it for your messageHolder:
clearHolderContents(messageHolder);
Hope that helps!

as3 getting object coordinates

Hello everyone so i have a piece of code witch creates some circles, and after i move them with another function i want to get their center coordinates so i can draw lines from center to center of circles, but i don`t have any idea how to do it ... if you can suggest me 1 , here is the code witch creates the circle :
function new_sond(event:MouseEvent):void
{
if (i<9)
{
i++;
q=i;
var btn:Sprite = new Sprite();
btn.graphics.beginFill(0x0099FF, 1);
btn.graphics.drawCircle(400, 300, 15);
btn.graphics.endFill();
var s:String = String(q);
btn.name=s;
var textField = new TextField();
textField.mouseEnabled=false;
textField.text = i;
textField.width = 10;
textField.height = 17;
textField.x = 395; // center it horizontally
textField.y = 292; // center it vertically
btn.addChild(textField);
this.addChild(btn);
}
}
the code with is mooving them is :
this.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownH);
this.addEventListener(MouseEvent.MOUSE_UP, mouseUpH);
function mouseDownH(evt:MouseEvent):void {
var object = evt.target;
object.startDrag();
}
function mouseUpH(evt:MouseEvent):void {
var obj = evt.target;
obj.stopDrag();
}
And the code where i draw the lines between them :
function click1(e:MouseEvent):void{
e.currentTarget.removeEventListener(MouseEvent.CLICK, click1);
var i:int;
i=1;
if (e.target.name!=null){
trace(e.target.name);
sx=mouseX;
sy=mouseY;
stage.addEventListener(MouseEvent.CLICK,click2);
}
}
function click2(e:MouseEvent):void{
e.currentTarget.removeEventListener(MouseEvent.CLICK, click2);
fx=mouseX;
fy=mouseY;
var i:int;
i=2;
trace(e.target.name);
var line:Shape = new Shape();
line.graphics.lineStyle(1,0x0066FF,1);
line.graphics.moveTo(sx,sy);
line.graphics.lineTo(fx,fy);
this.addChild(line);
var inputField:TextField = new TextField();
inputField.border = true;
inputField.type = TextFieldType.INPUT;
str=inputField.text;
trace(str);
inputField.width = 23;
inputField.height = 18;
inputField.x = (sx+fx)/2;
inputField.y = (sy+fy)/2;
addChild(inputField);
}
The thing is i want to draw the line from center to center, but i get the mouseX and mouseY coordinates to draw, because i don`t know how to take the center coordinates of an object.... what i get is : http://gyazo.com/6003630d549209ec5e16ccfffe0ee689
But i want the lines to be drawn from center, if someone has any suggestions please help
Sorry for the long post, i just don`t know where i need to put the piece with will center them so i wanted to give the hole code where it can be placed.... I will appreciate very much any idea .
Well, if you drew the circle at 0,0 and moved the btn object .x and .y to 400,300 like this:
btn.graphics.drawCircle(0,0,15);
btn.x = 400;
btn.y = 300;
Then as you drag btn around the screen, btn.x , btn.x (or in the click handler, e.target.x and e.target.y) would always be the center of the circle.
Alternately, if you can't or don't want to do it that way, you can get the bounds of btn (with respect to this coordinate system, since that's where line is being drawn), and since it's a circle, then center of the bounds will be the center of the circle:
var btn:Sprite = e.target;
var bounds:Rectangle = btn.getBounds(this);
var center_x:Number = bounds.x + bounds.width/2;
var center_y:Number = bounds.y + bounds.height/2;

How can I access the width of a JPG loaded inside a movieclip in AS3?

i'm trying to reproduce the bookshelf similar the one in this site: http://www.callis.com.br/
The books are PNG files that comes in several different sizes.
What I'm trying to accomplish is, after loading in several different movieclips (book0, book1, book2, ...) read their widths, calculate the gap necessary to push it, and then arrange the x value of each book.
Every time I try to access the width value, it says it's 0.
Here's a portion of my code, that's trying to do the trick.
Thanks in advance.
for (j=0; j < dados.livro.length(); j++){
if(j<8){
targetLivro = MovieClip(MovieClip(root).livros.getChildByName("livro"+(j)));
}else{
targetLivro = MovieClip(MovieClip(root).getChildByName("livro"+(j)));
}
preparaLivro(targetLivro,dados.livro[j].imagem.text(),dados.livro[j].link.text());
//larguraTotalLivrosSup += targetLivro.width;
//trace(larguraTotalLivrosSup);
trace("livro"+j+": ");
trace("título:"+dados.livro[j].titulo.text());
trace("imagem:"+dados.livro[j].imagem.text());
trace("link:"+dados.livro[j].link.text());
}
//organiza a primeira estante
//
/*
for (i=0; i<largurasArray.length; i++){
trace(largurasArray[i]);
}*/
var offset:Number = 20;
for (j=0; j<livros.numChildren; j++){
//targetLivro = MovieClip(livros).getChildByName("livro"+(j));
trace(livros.getChildAt(j).width);
}
function preparaLivro(livro:MovieClip, capa:String, url:String){
var capaLoader:Loader = new Loader();
var capaImageRequest:URLRequest = new URLRequest(capa);
var capaBitmapData:BitmapData;
var capaBitmap:Bitmap;
var capaLargura:Number = 0;
capaLoader.load(capaImageRequest);
capaLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, function(e:Event):void{
capaBitmapData = new BitmapData(e.target.content.width, e.target.content.height);
capaBitmapData.draw(capaLoader);
capaBitmap = new Bitmap;
capaBitmap.bitmapData = capaBitmapData;
livro.y -= e.target.content.height;
trace(e.target.content.width, e.target.content.height);
livro.buttonMode = true;
livro.addChild(capaBitmap);
livro.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void{
navigateToURL(new URLRequest(url), "_blank");
});
//trace(e.target.content.width);
});
}
Instantiate bitmap from LoaderInfo(event.target).content like:
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
loader.load(new URLRequest("http://www.google.com/images/srpr/logo4w.png"));
function onComplete(event:Event):void
{
var bitmapData:BitmapData =
Bitmap(LoaderInfo(event.target).content).bitmapData;
}
Tracing bitmapData.width and bitmapData.height outputs:
width: 550, height: 190
Otherwise, if you want width / height from the loader, access loader's contentLoaderInfo:
var width:Number = loader.contentLoaderInfo.width;
var height:Number = loader.contentLoaderInfo.height;

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.

creating dynamic rectangle

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;
}