Stage align and scale mode

#1

Is there any way to set

stage.align

and

stage.scaleMode

?

0 Likes

#2

OpenFL currently ignores stage.align and stage.scaleMode. It follows two modes:

  1. When the window parameters include “resizable” as true (default) OpenFL will scale content to match the target window area and allow black borders. This is similar to StageScaleMode.SHOW_ALL in ActionScript
  2. When “resizable” is false the window will be the size specified and will not resize or align. This is similar to StageScaleMode.NO_SCALE I believe

I’d like to see this properly supported if we can decide how to handle backward compatibility – I think the default stage align and scale mode could be set based upon the window parameters (assuming it’s a match with the current behavior)?

0 Likes

#3

There are openfl default values:
image

How to set scaleMode as StageScaleMode.SHOW_ALL ?
The following settings do not work. :thinking:
image

0 Likes

#4

I think that this behavior may be somewhat different between the NPM release and the Haxelib version – I am only getting 0 width x 0 height (resizing) or set width x set height (not resizing) working.

I think it might be easiest to handle the SHOW_ALL style approach manually for now.

I just got it working in this sample:

The strategy is to resize completely and then to handle the letterboxing yourself within the OpenFL code

0 Likes

#5

I think it’s best way to support by an root matrix. :thinking:
This will take h5 app a stronger adaptability of window’s inner size than flash,and it helps to maintain the render dirty area.
Most of other h5 engines have this export setting.
I will try my best to study the relevant source code first and see if I can implement this function. (Unfortunately, I am better at typescript rather than haxe, so this may take a long time…) :rofl:

0 Likes

#6

Now, the stage’s align and scale mode is supported perfectly(Only tested HTML5 target).

  1. Active this api as follow:
    Suggestion realization about HTML5Window

  2. Modify Stage.__resize

    switch (this.scaleMode)
    {
    	case StageScaleMode.NO_SCALE:
    		__logicalWidth = windowWidth;
    		__logicalHeight = windowHeight;
    	case StageScaleMode.SHOW_ALL, StageScaleMode.EXACT_FIT, StageScaleMode.NO_BORDER:
    		__logicalWidth = this.window.__attributes.width;
    		__logicalHeight = this.window.__attributes.height;
    }
    
    if (__logicalWidth == 0 && __logicalHeight == 0) 
    {
    	this.stageWidth = windowWidth;
        this.stageHeight = windowHeight;
    }
    else
    {
        this.stageWidth = __logicalWidth;
        this.stageHeight = __logicalHeight;
    
        var scaleX = windowWidth / this.stageWidth;
        var scaleY = windowHeight / this.stageHeight;
    
        switch (this.scaleMode)
        {
    		case StageScaleMode.NO_SCALE:
    			scaleX = scaleY = 1;
    		case StageScaleMode.SHOW_ALL:
    			scaleX = scaleY = Math.min(scaleX, scaleY);
    		case StageScaleMode.NO_BORDER:
    			scaleX = scaleY = Math.max(scaleX, scaleY);
    		case StageScaleMode.EXACT_FIT:
        }
    
        var top_y = 0;
        var middle_y = (windowHeight - (this.stageHeight * scaleY)) / 2;
        var bottom_y = windowHeight - this.stageHeight * scaleY;
    
        var left_x = 0;
        var right_x = windowWidth - this.stageWidth * scaleX;
        var middle_x = (windowWidth - (this.stageWidth * scaleX)) / 2;
    
        var offsetX = middle_x;
        var offsetY = middle_y;
    
        switch (this.align)
        {
    		case StageAlign.TOP:
    			offsetY = top_y;
    		case StageAlign.TOP_RIGHT:
    			offsetX = right_x;
    			offsetY = top_y;
    		case StageAlign.RIGHT:
    			offsetX = right_x;
    		case StageAlign.BOTTOM_RIGHT:
    			offsetX = right_x;
    			offsetY = bottom_y;
    		case StageAlign.BOTTOM:
    			offsetY = bottom_y;
    		case StageAlign.BOTTOM_LEFT:
    			offsetX = left_x;
    			offsetY = bottom_y;
    			case StageAlign.LEFT:
    			offsetX = left_x;
    		case StageAlign.TOP_LEFT:
    			offsetX = left_x;
    			offsetY = top_y;
        }
        this.__displayMatrix.scale(scaleX, scaleY);
        this.__displayMatrix.translate(offsetX, offsetY);
    }
    
  3. modify OpenGLRenderer.__resize
    https://github.com/openfl/openfl/blob/17bbd9f7ae65bfc9051d61275a9fa4a98644be5e/src/openfl/display/OpenGLRenderer.hx#L880-L886

    __offsetX = 0;
    __offsetY = 0;
    __displayWidth = width;
    __displayHeight = height;
    

Done, and there is useage:

// set stage size.
let stage = new Stage(800, 600, 0x000000, App);
// it seems stage.window need to open.
stage.window.resizable = true;
// flash default value
stage.align = "";
stage.scaleMode = StageScaleMode.SHOW_ALL;

Finally, I propose to amend some other places (or open existed API).

  1. Add stage.setStageSize(width, height) to enable change stage.stageWidth and stage.stageHeight.`
  2. Open stage.canvas to get real size of canvas element.
  3. Change stage.align and stage.scaleMode to setter and getter to enable update stage size immediately.
  4. Add a param to Stage constructor to enable put in resizable option.

:grinning:
Through above means, the characteristics of adaptive window will be strengthened.

0 Likes

#7

Do you think you could put these changes into a pull request?

0 Likes

#8

Other platforms have not been fully tested, and the operation of passing resizable parameters is best done with a public api.

I recommend that the original author perform the code merge operation. :rofl:

0 Likes

#9

Bug: It will be render error when TextField instance’s text changed

0 Likes