Skip to content
July 24, 2008 / Shrikant Patil

Flex Image Repeating Canvas Container

As per HTML designer, there is no need to put the whole strip of image which is linear, similar from top – bottom or left – right. The trick HTML designer uses is, he takes a 1px of image that strip and set that image as a background for a table(or row or cell) and set it to repeat.
When it comes to Flex, if we want to put a background image which has the similar linear from its directions. Then we can set the whole strip of image as background for containers.which makes a heavy embedding of image,. So i thought to create a similar kind of container which provides to set a repeating background image and should allow to repeat the image in both horizontal and vertical directions.

So here i come up with a solution, i created a custom Container which extends Canvas container. It accepts the Embedded image (1Px) class reference as well as repeat direction. The custom container works on the Graphics API using beginBitMapFill methods.
So check it out and drop a comment.

here is how to use it steps:
First embed the image(1 px) in your application and create ImageRepeatCanvas and assign the properties;


<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" xmlns:flexscript="com.*">
<mx:Script>
	<!&#91;CDATA&#91;
		&#91;Bindable&#93;
		&#91;Embed(source='com/bg.png')&#93;
		private var img:Class;
	&#93;&#93;>
</mx:Script>
<flexscript:ImageRepeatCanvas repeatDirection="horizantal"
 height="150" repeatImage="{img}" width="587" x="31.5" y="49">
	<mx:Button label="Button1" x="10" y="86"/>
	<mx:Button label="Button1" x="257.5" y="86"/>
	<mx:Button label="Button1" x="170" y="86"/>
	<mx:Button label="Button1" x="90" y="86"/>
</flexscript:ImageRepeatCanvas>
</mx:Application>

Next,….

create a directory name as “com” into your directory and put this container class into that directory;

(The class is well documented, you are free to alter, modify etc :))


/*
	The ImageRepeatCanvas provides a container in which
	embeded images can be repeated
	as designers do in html tables.
*/

package com
{
	import flash.display.Bitmap;
	import flash.display.Graphics;
	import mx.containers.Canvas;

	/**
	 *  The ImageRepeatCanvas container gives a way of creating
	 * one image that repeat
	 *  across either directions.
	 *
	 *  @mxml
	 *
	 *
<pre>
	 *  <namespace:ImageRepeatCanvas
	 *       repeatImage="{EmbededImage Class Reference}"
	 *       repeatDirection="horizantal|horizantal"
	 *    />
	 *</pre>
*/

	public class ImageRepeatCanvas extends Canvas
	{
		//-------------------------------------------------------------
	    //  Variables
	    //-------------------------------------------------------------
		private var bgImg:Bitmap = new Bitmap();
		private var direction:String;
		public var repeatImage:Class;

		//--------------------------------------------------------------
	    //  Constants
	    //--------------------------------------------------------------
		public static var REPEAT_HORIZANAL:String = "horizantal";
		public static var REPEAT_VERTICAL:String = "vertical";

	    //---------------------------------------------------------------
	    //  Constructor
	    //---------------------------------------------------------------
		public function ImageRepeatCanvas()
		{
			super();

		}

		/**
	     *  A setter method to set the direction for repeation of image
	     */
		[Inspectable(category="General", enumeration="horizantal,vertical", defaultValue="horizantal")]
		public function set repeatDirection(val:String):void{
			direction = val;
		}

		/**
	     *  @private
	     */
		override protected function updateDisplayList(w:Number, h:Number):void{
			super.updateDisplayList(w,h);
			bgImg.bitmapData = new repeatImage().bitmapData;
			if(bgImg){
				switch(direction){
					case ImageRepeatCanvas.REPEAT_HORIZANAL:
									h = bgImg.height;
									break;
					case ImageRepeatCanvas.REPEAT_VERTICAL:
									w = bgImg.width;
									break;
				}
				var Grpx:Graphics = graphics;
				Grpx.clear();

				Grpx.beginBitmapFill(new repeatImage().bitmapData);
				drawRoundRect(0,0,w,h);
				Grpx.endFill();
			}
		}
	}
}

Waiting for your comments 🙂

Advertisements

26 Comments

Leave a Comment
  1. Dane / Aug 9 2008 5:54 am

    Just wanted to say that this is awesome and exactly what I was looking for and it works perfectly.

  2. Josema / Sep 3 2008 6:53 pm

    Great example! 1000 thanks!

  3. ernest / Oct 2 2008 7:35 pm

    going to try this out – looks like just what i need.

    you do know that the word is ‘horizontal’ not ‘horizantal’ or ‘HORIZANAL’ as you use these in your code… someone might have a hard time setting things up with these Strings.

    cheers

  4. Shrikant Patil / Oct 3 2008 5:15 am

    Hi, ernest,.

    Thanks for your commitment. Yes that is a spell mistake i had done in the coding… i will update it soon.. thanks again.

  5. Kach / Nov 6 2008 2:13 am

    Thank you for your solution. It worked for my project’s needs.

    However, if I use a PNG image with transparency (for the image’s edge to fade into the application background’s color) as the image to repeat horizontally, the transparency does not come through. Any solution to this?

  6. Shrikant Patil / Nov 6 2008 5:01 am

    Hi,
    Thanks for you comment.
    If you see at the code, while it start to repeat the given image, it check the height and width of the image and starts repeating that image. so its totally on to you to create exact repeating image.

  7. joe joe / Jan 8 2009 11:40 pm

    Awesome! Thanks so much.

  8. Dylan / Jan 29 2009 6:56 am

    Thanks for the script, but… If I make the width=”100%”, the repeating image does not span or even show up. This may be due to my own naiveness, but do you know any way to work around this?

  9. Tom / Feb 13 2009 4:11 pm

    something I used to do all the time in Dreamweaver / HTML days and now running into this need with Flex…. and then I find this. Perfect!!!!

    Good work just what the doctor ordered.

  10. Andrew / Apr 20 2009 6:13 pm

    Thanks for this… looks great.

    But what about if we wanted to change the background image at runtime?

    • Shrikant Patil / Apr 21 2009 8:06 am

      all you need to do is the make public repeatingImage variable as bindable in class file. like;
      [Bindable]
      public var repeatingImage:Class…….

  11. Andrew / Apr 20 2009 6:15 pm

    Sorry, I should have taken a closer look – it seems like you can simply put a non-embeded image link for repeatImage?

  12. Almas Adilbek / May 14 2009 8:25 am

    🙂 I’m 40,001 visitor to this blog! 40,001 hits

  13. Stef / May 14 2009 10:03 am

    Wow, extra.
    But can you explain me how to do if I want to repeat horizontal & vertical ?
    Thanks a lot.

    • Shrikant Patil / May 15 2009 4:16 am

      check for the ‘repeatDirection’ property of the component where you can set the either – horizantal or vertical.

      • Stef / May 15 2009 8:23 am

        Thanks, but if I want horizontal AND vertical, not OR ?
        In this code, you can choose between, in css, repeat-x or repeat-y, but you can’t choose repeat.
        I’ve tried to modify it, but for sure, I’m not so strong for Flex at this time ^^

        Thanks a lot.

  14. Andrew / Jul 11 2009 1:06 pm

    …I still can’t figure out how to switch the background at runtime. Could you be more specific with your suggestion?

  15. Gabor / Jul 18 2009 11:53 am

    Thank you! …was very helpfull.

  16. Brian Vaughn / Jul 22 2009 2:41 pm

    Thanks a lot for taking the time to post this! 🙂

    Slight suggestion for a way you could improve compatibility (to include embedded UIMovieClip symbols, etc.). (Sorry in advance if my attempt at using a pre-tag in a comment fails.)

    override protected function updateDisplayList( w:Number, h:Number ):void {
      super.updateDisplayList( w, h );
      
      var imageInstance:* = new image();
      var bitmapData:BitmapData;
      
      if ( imageInstance is Bitmap ) {
        bitmapData = ( imageInstance as Bitmap ).bitmapData;
        
      } else if ( imageInstance is DisplayObject ) {
        bitmapData = new BitmapData( ( imageInstance as DisplayObject ).width, ( imageInstance as DisplayObject ).height );
        bitmapData.draw( imageInstance as DisplayObject );
        
      } else {
        return; // We can't work with this.
      }
      
      switch ( _direction ) {
        case HORIZANAL:
          h = bitmapData.height;
          break;
        case VERTICAL:
          w = bitmapData.width;
          break;
      }
      
      graphics.clear();
      graphics.beginBitmapFill( bitmapData );
      drawRoundRect( 0, 0, w, h );
      graphics.endFill();
    }
    • Shrikant Patil / Jul 23 2009 5:35 am

      Thanks Brian, that is useful code. Thanks lot.

  17. amit / Jan 29 2010 12:11 pm

    if i do’nt put set the “repeatImage” i get an exception .. however adding:

    if(bgImg.bitmapData == null) {
    return;
    }

    at line 66 worked as i wanted

    • Shrikant Patil / Feb 1 2010 6:53 am

      Yes, i didnt put property define checking in the code. Thanks for the solution.

  18. Marcus / Sep 22 2010 10:47 am

    Thanks heaps for this mate!

  19. chhabeg / Aug 23 2011 9:13 am

    Awesome!!!! Thank you so much.

  20. Ekonomiczna jazda samochodzem / Nov 18 2011 10:11 am

    Yes, that is what I need!

    Thanks!

  21. Sunny / Dec 7 2011 7:50 am

    Thanks ! this is a good solutions for repeating images. Please can u post the sample file.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: