kolnedra . com | Tags | Posts tagged with 'external interface'

Posts tagged with 'external interface'

Flash and DOM resizing

Date: 16 June 2010

A few people mailed me how I created this flash blog, and especially how I managed to "blend" it with the HTML scrollbar.
My first attempt had an easier solution, just to resize the HTML <object> element to it's boundaries. The only big problem with this approach is that the maximum height of an HTML flash <object> is around 4,000 pixels. Anything higher will cut of the content of the flash element. So I came up with a solution that simulates a very large flash object.
Don't have any idea what I'mt talking about? Check this example

Setting up HTML & CSS

I could copy paste the HTML code here, but it's best just to check out the source over here
The following CSS lines are enough :
html,body { margin:0; padding:0; height:100%;  }
#flashPlaceholder { width:100%; height:100%; }
#flashContainer { width:100%; height:100%; position:fixed; /* important */ }

Setting up Flash

I wrote a small package that handles page resizes and HTML scroll events.
In short: Once the boundaries of the flash object (internally) change, the external interface will call a javascript function telling the DOM that it should resize it's placeholder.
And on the other side javascript tells flash to move it's main container once the scrollbar is used.
package {
	import flash.display.DisplayObjectContainer;
	import flash.events.Event;
	import flash.external.ExternalInterface;
	import flash.geom.Rectangle;
	
	public class HTMLDomResizer
	{
		// Super privates
		private static var __self:DisplayObjectContainer;
		
		// Normal private variables
		private static var _containerInfo:Object = { w: 0, h: 0 };			
		
		/**
		 * Psuedo constructor
		 * 
		 * @param $self	The MainTimeline object
		 */
		public static function init($self:DisplayObjectContainer):void {
			__self = $self;
			
			__self.root.stage.align = 'TL';
			__self.root.stage.scaleMode = 'noScale';			
			
			_initExternalInterface();
		}
		
		/**
		 * Set up the external interface
		 * 
		 * @return void
		 */
		private static function _initExternalInterface():void {
			if (!ExternalInterface.available) { throw new Error('ExternalInterface unavailable'); }
			
			// Listen for incoming javascript calls
			ExternalInterface.addCallback("flashScroll", function(... $args):void {				   
				__self.x = -$args[0];
				__self.y = -$args[1];
			});		
			
			// Check if the dimensions of this flash content is changed
			__self.addEventListener(Event.ENTER_FRAME, function ($e:Event):void {
				var bounds:Rectangle = __self.parent.getBounds(__self);
				
				
				// Only call the resize function if the content is actually changed, else flash will keep fireing useless js calls
				if (bounds.x + bounds.width != _containerInfo.w || bounds.y + bounds.height != _containerInfo.h) {
					_containerInfo.w = bounds.x + bounds.width;
					_containerInfo.h = bounds.y + bounds.height;	
					_resizeFlashContent();
				}
			});
		}
		
		/**
		 * Call a javascript function to tell the DOM to resize the placeholder DIV
		 * 
		 * @return void
		 */		
		private static function _resizeFlashContent():void {
			ExternalInterface.call("resizeFlashHandler", Math.ceil(__self.width), Math.ceil(__self.height));  
		}
		
		/**
		 * Scroll the HTML DOM to a specific position through javascript
		 * @param	int	$x
		 * @param	int	$y
		 */
		public static function scrollTo($x:int, $y:int):void {
			if (__self === null) { throw new Error('Not initialized yet'); }
			if (!ExternalInterface.available) { throw new Error('ExternalInterface unavailable'); }		
			
			ExternalInterface.call("window.scrollTo", $x, $y);
		}
	}
	
}


Setting up Javascript

One of the most important steps is javascript. In order for flash to manipulate any DOM elements.
Just check out the source of the javascript file.
The most important function (ofcourse they're all important), is resizeFlashHandler():
This function resizes the placeholder to so it always fits the total screen or it will resize the placeholder giving the DOM a scrollbar.
You can also change the "minimumWidth" variable, so your flash element can be wider (or smaller)
/**
 * Function is called from the external interface in flash
 * It passes on the width and height of the flash element internally 
 * 
 * @param {int} width
 * @param {int} height
 */
function resizeFlashHandler(w, h) {
	lastResizeHandler = [w, h];
	var viewPortSize = getViewportDimensions(),
		container = document.getElementById('flashPlaceholder');
        
	if (w && h) {
		if (h < viewPortSize[1]) {
			container.style.height = "100%";	
		} else { 						
			container.style.height = h + "px";
		}
	}
	if (viewPortSize[0] < minimumWidth) {		
		container.style.width = minimumWidth + "px";
	} else {
		container.style.width = "100%";		
	}
	scrollHandler();
}

Finally

If you put all those things together, you'll get the site you're currently looking at.
You can download the example files here or check out a small example