A Flash Developer Resource Site

Page 1 of 2 12 LastLast
Results 1 to 20 of 24

Thread: Links and thumbnails - how do I target these?

  1. #1
    Junior Member
    Join Date
    Apr 2011
    Posts
    14

    Links and thumbnails - how do I target these?

    So I'm working on this "Links" page on my site, and I've run into some trouble that I haven't been able to get past for a few weeks (due to lack of time working on it!).

    I want the page function to be such that when you mouseover a link a thumbnail will show up in the box to the right, like in the picture. When the mouse then moves outside the link the thumbnail should fade out again. This I thought was supposed to be a simple task

    I am using AS3, Flash CS5 and I have loaded the link texts and thumbnails from an XML file. In order to get the hand cursor when hovering over the links I put them inside a sprite, which causes the same problem I am having with the thumbnails, which is this;

    I have no idea of how to target the thumbnails or fetch the links in my mouseevents since I dont know their instance names, and when I trace the "e.target.name" attribute I just get like "instance 225", which is useless. So how can I name the thumbs and links so that I can target them from my "mouseOVER" and "mouseCLICK" functions? The "my_thumb" variable is inside a function so I cant call it from my eventlistener, and even if I move that variable outside the function, it still only affects the last thumbnail created by the function... Do I need to go via a public class or something, because I was trying something like that before too, but couldn't get my head around how to make it work.

    I also tried making a loop for naming the variables in order, but I couldn't get it to work, and I still need to find a way to target the from another function.



    I'm in serious need of help, on so many levels
    Hope I made sense in trying to explain my problem, if not; ask and I'll try harder!

    Here's my code:

    Code:
    import flash.display.MovieClip;
    import flash.display.Loader;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFormat;
    import flash.events.MouseEvent;
    import globalvars;
    
    import gs.*;
    import gs.easing.*;
    import flash.display.Sprite;
    
    var format1:TextFormat = new TextFormat();
    format1.size = 18;
    format1.font = "Eras Medium ITC"
    format1.color = 0x000000;
    
    var thumb_width:Number;
    var thumb_height:Number;
    var my_links:XMLList;
    var my_total:Number;
    var container_mc:MovieClip;
    var counter:Number;
    
    
    
    var myXML:XML;
    var myLoader:URLLoader = new URLLoader();
    myLoader.load(new URLRequest("../links/links.xml"));
    myLoader.addEventListener(Event.COMPLETE, processXML);
    
    function processXML(e:Event):void {
    	myXML = new XML(e.target.data);
    	//trace(myXML.*.length());
    	my_links = myXML.site;
    	trace(my_links);
    	my_total = my_links.length(); 
    	//trace(my_total);
    	createContainer();
    		
    }
    
    
    function createContainer():void{
    	container_mc = new MovieClip();
    	container_mc.x = 50;
    	container_mc.y = 200;
    	addChild(container_mc);
    	callLinks();
    	
    	container_mc.addEventListener(MouseEvent.MOUSE_OVER, mouseOVER);
    	container_mc.addEventListener(MouseEvent.MOUSE_OUT, mouseOUT);
    	container_mc.addEventListener(MouseEvent.CLICK, mouseCLICK);
    	
    	
    }
    
    
    function callLinks():void{
    	for (var i:Number = 0; i < my_total; i++){
    		var linktext = my_links[i].@linkName;
    		var linkthumb = my_links[i].@linkThumb;
    		var linkLabel:TextField = new TextField();
    		linkLabel.defaultTextFormat = format1;
    		linkLabel.autoSize = TextFieldAutoSize.LEFT;
    		linkLabel.selectable = false;
    		linkLabel.text = linktext;
    		
    		
    		var linkButton:Sprite = new Sprite();
    		linkButton.x = linkLabel.x
    		linkButton.y = linkLabel.y
    		linkButton.buttonMode = true;
    		linkButton.mouseChildren = false;
    		linkButton.useHandCursor = true;
    		linkButton.addChild(linkLabel);
    		
    		container_mc.addChild(linkButton);
    		
    		linkLabel.x = 50;
    		linkLabel.y = 30;
    		//linkLabel.name = ""+[i];
    		//trace("linkLabel = "+linkLabel.name);
    		
    		
    		if(i != 0){
    			linkLabel.y = 30+i*25;
    		}
    		
    		
    				
    		var thumb_loader = new Loader();
    		thumb_loader.load(new URLRequest(linkthumb));
    		thumb_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, thumbLoaded);
    		thumb_loader.alpha = 0.3;
    		globalvars.counter = i;
    		trace("globalvars "+globalvars.counter);
    						
    	}
    }
    
    
    					function thumbLoaded(e:Event):void{
    						
    							var my_thumb:Loader = Loader(e.target.loader);
    							container_mc.addChild(my_thumb);
    							my_thumb.alpha = 1;
    							my_thumb.x = 468;
    							my_thumb.y = 30;
    						
    						
    					}
    
    function mouseOVER(e:MouseEvent):void{
    	//var active_link = my_links[e.target.name].@linkName;
    	globalvars.active_link = my_links[e.target.name].@linkThumb;
    	trace(e.target.name);
    	TweenLite.to((e.target), 0.2, {tint:0xFFFFFF}); 
    }
    
    
    function mouseOUT(e:MouseEvent):void{
    	TweenLite.to((e.target), 0.2, {tint:0x000000}); 
    }
    
    
    
    function mouseCLICK(e:MouseEvent):void{
    	var active_link:String = my_links[e.target.name].@linkAddress;
    	trace(active_link);
    	var request:URLRequest = new URLRequest(active_link);
        try {
            navigateToURL(request, '_blank');
        } catch (e:Error) {
            trace("An error occurred!");
        }
    	
    }

  2. #2
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    You're right. Names are useless. Stop trying to make them mean something.

    I think what you've said boils down to the fact that you need a way of associating your link button to your link address.

    Since you made your linkButton a Sprite, it is not dynamic and you can't just add a property to it. I'd suggest either creating a class which extends Sprite and has a property for the link address, or you could associate them through a Dictionary with the linkButton as the key.

  3. #3
    Junior Member
    Join Date
    Apr 2011
    Posts
    14
    Quote Originally Posted by 5TonsOfFlax View Post
    You're right. Names are useless. Stop trying to make them mean something.

    I think what you've said boils down to the fact that you need a way of associating your link button to your link address.

    Since you made your linkButton a Sprite, it is not dynamic and you can't just add a property to it. I'd suggest either creating a class which extends Sprite and has a property for the link address, or you could associate them through a Dictionary with the linkButton as the key.

    Yeah I figured the names didn't really help me at all.

    And you understood me right, I want the link button associated with the link address, this actually worked before I put the text field in a sprite, but then I couldnt get the hand cursor to appear when hovering over the links.

    I'm very grateful for your help, but I'm very new at AS3 coding (haves some c++ experience only), and extending a class or using a dictionary is completely foreign to me... Hmm, is there a tutorial/article you recommend or can I read up on this anywhere?

    About the thumbnails, do you know how I can find a way to target those?

  4. #4
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    Make a class to hold your linkButton, linkThumb, and the linkAddress.

    Code:
    public class Link extends Sprite{
    
      public linkButton:TextField;
      public linkThumb:Loader;
      public linkAddress:String;
    
    
      public function Link(label:String, thmb:String, address:String){
        var format1:TextFormat = // define it here.
    
        linkButton = new TextField();
        linkButton.defaultTextFormat = format1;
        linkButton.autoSize = TextFieldAutoSize.LEFT;
        linkButton.selectable = false;
        linkButton.text = label;
        addChild(linkButton);
    
        linkThumb = new Loader();
        linkThumb.load(new URLRequest(thmb));
        addChild(linkThumb);
    
        linkAddress = address;
      }
    
    }
    Your positioning code is all over the place. I couldn't tell what your actual intent was. Each instance of the code above acts as a container for a link and thumb, but you had all the links and thumbs in one big container, and it looks like you had all the thumbs on top of each other. I'm sure you can figure out how to alter it if necessary.

    Basically, once you have the Link, you can get to the thumb of linkAddress easily because they are properties of the Link.

  5. #5
    Junior Member
    Join Date
    Apr 2011
    Posts
    14
    Thanks, I will definitely try that out tomorrow! The code is really easy to understand when I look at it, but to come up with it when you dont know the coding language that well is so much harder.

    Sorry about the chaos in my code, I've been trying out so many different things with it that its starting to implode. The thing with the thumbnails is that, as you said, they are placed on top of each other. My idea was to load the thumbnails and place them on the page with alpha = 0, then when hovering over a link the corresponding thumbnail would fade in to alpha 1 like shown in the picture in my earlier post.

    Again, thank you so much for your help, I'll be sure to try it out and hopefully I will get it to work, otherwise I suppose I'll have to ask for more pointers

  6. #6
    Junior Member
    Join Date
    Apr 2011
    Posts
    14
    Okay, I've been trying this out for a while now, and it seems to work well for the most part. I've managed to create the link objects and put them on the page, there are however a few issues I'm having:

    • The text formatting doesn't work
    • Thumbnails dont show up?
    • How do I retrieve the link address from my mouseCLICK function?


    The class currently looks like this, I've only done minor modifications this far as to not screw it all up:

    Code:
    package {
    	
    public class Link extends Sprite{
    
      public linkButton:TextField;
      public linkThumb:Loader;
      public linkAddress:String;
    
    
      public function Link(label:String, thmb:String, address:String){
        var format1:TextFormat = new TextFormat();
    	format1.size = 18;
    	format1.font = "Eras Medium ITC"
    	format1.color = 0x000000;
    
        linkButton = new TextField();
        linkButton.defaultTextFormat = format1;
        linkButton.autoSize = TextFieldAutoSize.LEFT;
        linkButton.selectable = false;
        linkButton.text = label;
        addChild(linkButton);
    
        linkThumb = new Loader();
        linkThumb.load(new URLRequest(thmb));
        addChild(linkThumb);
    	
    	linkThumb.x = 468;
    	linkThumb.y = 30;
    
        linkAddress = address;
      }
    
    }
    
    }

    And here is the function that creates the links on the page:

    Code:
    function callLinks():void{
    	for (var i:Number = 0; i < my_total; i++){
    		
    		var myLink:Link = new Link(my_links[i].@linkName, my_links[i].@linkThumb, my_links[i].@linkAddress);
    		
    				
    		myLink.x = 50;
    		myLink.y = 30;
    				
    		if(i != 0){
    			myLink.y = 30+i*25;
    			
    		}
    		
    		
    		container_mc.addChild(myLink);
    				
    	
    						
    	}
    }
    And finally the mouseCLICK function that should retrieve the URL for the link from the Link object being clicked:

    Code:
    function mouseCLICK(e:MouseEvent):void{
    	
    	trace(e.target.linkAddress);
    
    /*var request:URLRequest = new URLRequest(active_link);
        try {
            navigateToURL(request, '_blank');
        } catch (e:Error) {
            trace("An error occurred!");
        }*/
    	
    }
    As you can see I've only been tracing the values from the object to try and find the right code for it. Google doesnt give me any hints when I search for "flash as3 retrieve property from object" or similar

    How come the thumbnails dont show up as they should? As far as I understand they should be part of the Link object and show up just the same as the text fields? Also for some reason the text formatting isn't working though the code looks just the same as before when it worked, only now its placed in the Link function.

    As always, help and hints greatly appreciated

  7. #7
    Junior Member
    Join Date
    Apr 2011
    Posts
    14
    I've been working a bit more on this and I found out I was importing the wrong class file as I seemed to have made a test class called "Link" earlier

    So having fixed that I now have this code in the Link.as class that I'm importing:

    Code:
    import flash.display.Sprite;
    
    package{
    public class Link extends Sprite{
    
      public var linkButton:TextField;
      public var linkThumb:Loader;
      public var linkAddress:String;
    
    
      public function Link(label:String, thmb:String, address:String){
        var format1:TextFormat = // define it here.
    
        linkButton = new TextField();
        linkButton.defaultTextFormat = format1;
        linkButton.autoSize = TextFieldAutoSize.LEFT;
        linkButton.selectable = false;
        linkButton.text = label;
        addChild(linkButton);
    
        linkThumb = new Loader();
        linkThumb.load(new URLRequest(thmb));
        addChild(linkThumb);
    
        linkAddress = address;
      }
    
    }
    }
    Which gives me an error "Package is unexpected", and if I delete the package tags I get "The public attribute can only be used inside a package". Why does it give the "Package is unexpected" error since it seems like I need the package tags.

    If I put the import link inside the package tag it gives a bunch of different error messages. What should I do?

  8. #8
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    place the import inside the package tag, then fix the other errors.

  9. #9
    Junior Member
    Join Date
    Apr 2011
    Posts
    14
    Quote Originally Posted by 5TonsOfFlax View Post
    place the import inside the package tag, then fix the other errors.
    All righty! Progress!

    Now I have all the links and thumbnails in place, but I still dont have the hand cursor when hovering over the links though?

    Also now I really need to figure out how to target the thumbnails so that I can manipulate their alpha values based on hovering over the links, and also how to retrieve the URL when I click a link.

    I've found that using something like "e.target.linkAddress" doesnt work for fetching it...

    This is a much better way to organize this than the way I was headed, huge props to you!

  10. #10
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    If your target is your Link object, then you should be able to get the thumbnail from it. You'll probably have to cast the target to Link:
    Code:
    var link:Link = Link(e.target);
    But if the target is something inside the link like the button, then you'll have to get the link from that then go get the other link properties. You may want to set the link's useHandCursor and mouseChildren properties to true and false respectively to get the click behavior as you want it.

  11. #11
    Junior Member
    Join Date
    Apr 2011
    Posts
    14
    I tried changing my code into this:

    Code:
    function callLinks():void{
    	for (var i:Number = 0; i < my_total; i++){
    		var myLink = new Link(my_links[i].@linkName, my_links[i].@linkThumb, my_links[i].@linkAddress, i);
    				
    		myLink.useHandCursor = true;
    		myLink.mouseChildren = false;
    			
    		container_mc.addChild(myLink);
    		
    		
    	
    	}
    }
    But the cursor still stays as the arrow when hovering over the links..?

    I do have some good new too though, using e.target.linkAddress actually does retrieve the link URL in my mouseCLICK function now that I got the class set up properly, so clicking the links works now Now to try the same thing with the thumbnails

  12. #12
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    Set buttonMode to true as well. According to the livedocs:
    useHandCursor : Boolean
    A Boolean value that indicates whether the pointing hand (hand cursor) appears when the pointer rolls over a sprite in which the buttonMode property is set to true.

  13. #13
    Junior Member
    Join Date
    Apr 2011
    Posts
    14
    Yep, thats it, now it works

    I have pretty much all the functionality now for the page. One thing remains though: when I move the cursor outside the link button/text, the thumbnail fades to alpha = 0. But when I move the cursor over the invisible thumbnail my eventlistener reacts and fades it back in. Is there a way to disable this behavior for the thumbnail only? I dont want the mouse to react to the thumbnail at all, only to the link button.

    I.e. can I put an eventlistener on the linkbutton only? Currently the listener is on the whole container mc.
    Or can I modify the hitbox for a link?
    Last edited by IceDiver; 04-25-2011 at 01:30 PM.

  14. #14
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    Well, the way it's set up now a Link is treated as a monolithic thing. You could skip the part where you add the thumbnail to the link as a child, but do set the property. Then later you can take that Loader in the thumbnail property and add it as a child to a different container. Then the Link still has a reference to it, but it won't count as part of the Link when you click on it.

  15. #15
    Junior Member
    Join Date
    Apr 2011
    Posts
    14
    Quote Originally Posted by 5TonsOfFlax View Post
    Well, the way it's set up now a Link is treated as a monolithic thing. You could skip the part where you add the thumbnail to the link as a child, but do set the property. Then later you can take that Loader in the thumbnail property and add it as a child to a different container. Then the Link still has a reference to it, but it won't count as part of the Link when you click on it.
    Awesome! I got it to work right off the bat

    The links page works perfectly now, but I noticed that when navigating to another page (changing to another frame), the links remain on the stage. This is the first page that I've made with AS3, the rest I've done manually in flash cs5, so I dont know how to fade all of the frame contents out when changing frames?

    Do I somehow link the frame contents to the frame or something?

  16. #16
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    A frame isn't really a container. You'll have to remove any children you want to disappear using removeChild. If you had a single sprite you used as a container for that frame, you could just remove that sprite.

  17. #17
    Junior Member
    Join Date
    Apr 2011
    Posts
    14
    I have two containers in the frame now, one for the main links content and one extra for the thumbnails. How can I register the event that tells a function to remove all children? Do I make a function that has some kind of "if(frame != 13) {remove all children}, or how do you usually do it?

  18. #18
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    I don't use frames.

    The thing that triggers the frame change is the same thing that should tell your code to remove the children.

  19. #19
    Junior Member
    Join Date
    Apr 2011
    Posts
    14
    My structure is such that when I click a link in my menu it triggers a function via a mouseevent like this:

    Code:
    home_btn.addEventListener(MouseEvent.CLICK, goHome);
    
    function goHome (e:MouseEvent):void{
    	gotoAndStop("Home");
    }
    I tried modifying all of my menu link functions into this:

    Code:
    function goHome (e:MouseEvent):void{
    	removeChild(container_mc);
    	removeChild(container_thumbs);
    	gotoAndStop("Home");
    }
    But this gives me an error whenever the Links page is not the page that was last visited before the function is called, since then container_mc and container_thumbs are null and cant be removed.

    Is there a way of saying "IF the last frame was "Links": do remove children"?
    I dont know how to target frames or get such properties to functions.

    How do you build your sites since you dont use frames?

  20. #20
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    You can use the currentFrame property to determine which frame you are currently on. But if many or all of your states require specific cleanup functions, then you could define a cleanup variable of type Function that points to the specific function for cleaning the last state. Or you could define, dispatch, and listen for your own custom event.

    I build sites in html, javascript and css. I build back ends in java (mostly). I build games and rich webapp interfaces in as3.
    Frames are for animation. They were never intended to be states, but people use them that way because they are afraid to handle the states themselves.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center