Flash and DOM resizing
Date: 16 June 2010A 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 hereThe 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