20.10.12

"Fullscreen" for HTML

In my previous post I wrote about how I encountered a few issues implementing a very basic stage setup for my Haxe library and explained how I solved a particular type error. In this post I'm going to show how I made a "fullscreen" HTML application, using the normal compile process NME provides.

The NME compiler uses a *.nmml document for various target settings, including the window size of your applications. So my first guess to make my HTML programm fill the entire browser was to specify the width and height in the application.nmml to 100% like I would do in CSS/HTML.
<window width="600" height="480" if="flash" />
<window width="???" height="???" if="html5" /> <!-- how 100%? only INT allowed ... -->
But using the % character causes errors when compiling for HTML. Another way would be to simply change the generated index.html but although the index might not need to be generated, it will be every time you compile and replaces any change you might have made. Not so cool :|
<div id="haxe:jeash" 
     style="background-color: #FFFFFF; width: 100%; height: 100%" 
     data-framerate="60">
</div>
Maybe there is a way to prevent the compiler from replacing your index.html but ideally I would be able to change the dimesion at runtime anyway. 

Scaling at Runtime:
So the best case would be to directly change it within Haxe. It is possible to code a special HTML case and rescale the stage at runtime, using conditional compiling and platform specific magic .
public function someFunction():Void
{
 // ...
 
 #if js
  untyped __js__('document.getElementById("haxe:jeash").style.width="100%";');
  untyped __js__('document.getElementById("haxe:jeash").style.height="100%";');
  
  var innerW:Int = untyped __js__('window.innerWidth');
  var innerH:Int = untyped __js__('window.innerHeight');
  
  var jeashStage:jeash.display.Stage = cast( this.stage );
   jeashStage.jeashOnResize(innerW, innerH);
 #end
}
As you can see its pretty easy to access the native language of your target and exchange data between its environment and your application at runtime. But it is Haxe, so why not use it and make it typed?
js.Lib.document.getElementById("haxe:jeash").style.width = "100%";
js.Lib.document.getElementById("haxe:jeash").style.height = "100%";

var innerW:Int = js.Lib.window.innerWidth;
var innerH:Int = js.Lib.window.innerHeight;
I must admit it has cast a huge smile on my face when this worked without any problems until I kept implementing my library and encountered a problem with MouseEvents

MouseEvent Issue:
The problem was that events do not fire anywhere but within the initial dimensions of the application and the quick workaround is to add a DisplayObject in fullscreen size to the root. Although it took me quite a while to figure this out I still felt this is a bit ugly and wanted to understand why it is not working. So I took a closer look.

After a dive into the jeash source and a few looks into the compiled js I figured it must be related to the bottom most "Root_MovieClip". A canvas object which does not rescale on resize for some reason and is suspeciously commented in the jeash.Lib class saying: "This ensures that a canvas hitTest hits the root movieclip". I tried to scale it up in various ways but finally settled for just redrawing its graphic and added it into the rescale handler of the jeash.display.Stage class.

public function jeashOnResize(inW:Int, inH:Int) 
{
 jeashWindowWidth = inW;
 jeashWindowHeight = inH; 
 
 // redraw background for mouse events   
 var jeashBG:Graphics = jeash.Lib.current.graphics; 
  jeashBG.clear();
  jeashBG.beginFill( this.backgroundColor );
  jeashBG.drawRect(0, 0, inW, inH );
 
 var event = new jeash.events.Event( jeash.events.Event.RESIZE );
  event.target = this;
  
 jeashBroadcast(event);
}
The background color worked previously , because the scaled div (haxe:jeash) has it as a style. I can only guess that mouse events require actual content underneath the mouse pointer and the background color style does not count. Which is probably the reason why jeash has a "Root_MovieClip" in the first place and it just didn't work because it fails to rescale it.

Although I'm not really sure how mouse events work in JS I'm happy that it works for now and that I got some insight into the guts of jeash. The *Lib classes seem to be a good place to see how the language specifc translations are handled.

No comments:

Post a Comment