GradientFill issues?

Hello OpenFL Community.
I’m rediscovering weird gradient fill behaviors.

gradientFill

In a long long time, maybe 5/6 years, I’ve well the memory to have rectified that with ratio/matrix tricks.
Then I can’t remember when I drop the trick, useless, because the gradient was working good, doesn’t it ?

Is it a deliberate retro-behavioring or… am I becoming seriously insane. ^^’

I guess this part of CanvasGraphics is responsible at least for HTML5 graphics:

case LINEAR:
				
				point = Point.__pool.get ();
				point.setTo (-819.2 * 0.12, 0);
				matrix.__transformPoint (point);
				
				point2 = Point.__pool.get ();
				point2.setTo (819.2 * 0.12, 0);
				matrix.__transformPoint (point2);
				
				gradientFill = context.createLinearGradient (point.x, point.y, point2.x, point2.y);

and I’ve just added 0.12 value for both point1 and point2 (~100.0 if you do the math) which gives me a following effect but I do not know where that original 819.2 value is from, could not find any source on that besides one site that pops up first on Google searching for “819.2 gradient fill” so maybe that was accurate at some point and now it is not?

I guess we have to wait for @singmajesty to respond and maybe we will find out the origin of 819.2 :slight_smile:

HTML5:

FLASH:

I’ve tested a different length of canvas like 300x100 because apparently 819.2 * 0.12 ~ 100.0 and the previous width x height was 200x100 so I guessed it may be a half of the width but it seems that -100.0 and 100.0 are the correct value at least to imitate Flash in HTML5.

I’ve tested this with code:

package;

import openfl.display.SpreadMethod;
import openfl.display.GradientType;
import openfl.display.Sprite;

class Main extends Sprite {
    public function new() {
        super();

        this.graphics.beginGradientFill(
            GradientType.LINEAR,
            [0x0000FF, 0x00FF00],
            [1.0, 1.0],
            [0, 255],
            null,
            SpreadMethod.PAD
        );
        this.graphics.drawRect(0.0, 0.0, 300.0, 300.0);
        this.graphics.endFill();
    }
}

having CanvasGraphics::createGradientPattern method modified as follows:

			case LINEAR:
				
				point = Point.__pool.get ();
				point.setTo (-100.0, 0);
				matrix.__transformPoint (point);
				
				point2 = Point.__pool.get ();
				point2.setTo (100.0, 0);
				matrix.__transformPoint (point2);
				
				gradientFill = context.createLinearGradient (point.x, point.y, point2.x, point2.y);
			
		}

having project.xml like this:

<window width="300" height="100" fps="60" hardware="true" allow-shaders="true" require-shaders="true" resizable="false"/>

Effects for Flash:
flash%20300x100

and HTML5:
html%20300x100

You’re right.
Beside in my memories, I used points with coordinates :


//point.setTo (-819.2, 0);
point.setTo (0, 0);

//point2.setTo (819.2, 0);
point2.setTo (100, 0);

to retrieve the pure firstColor value at 0.
you haven’t in your case.
at 0, yours’ is already half-green.

and I was scaling the gradient with matric to his true fill size.

And I have to apologize.
In fact, I may remember, it was only working on Flash export at that period.
It was a long time, sorry.
At that time, I got too much errors with an old own AS2/AS3 Frame+1 UI Framework, so I may have stopped the portability on Haxe>OpenFl>Flash and my gradients may never been tested on another platform,
So like you demonstrate, I have only to adapt it for other platforms.
It is some really good news !

So, after some tries.
I confirm.

for HTML5 Gradient Fill

1- rectify CanvasGraphics.hx

in private static function createGradientPattern function :


case LINEAR

point = Point.__pool.get ();
point.setTo (0, 0); // <-------------- here.
matrix.__transformPoint (point);

point2 = Point.__pool.get ();
point2.setTo (100, 0); // <-------------- .
matrix.__transformPoint (point2);

I tried with greater value to see if the gradient was smoother set with higher resolution, without clue.
So I kept 100.

But then, you have to scale your gradientfill with a Matrix xScale calculated for your fill size.

Something like that :

package;

import openfl.display.GradientType;
import openfl.display.Sprite;
import openfl.geom.Matrix;

class GradientFill extends Sprite
{

public function new() 
{
	super();
	
	var width = 1920;
	var height = 1080;
	var matrix:Matrix = new Matrix( width / 100, 0, 0, 1, 0, 0 );
	graphics.beginGradientFill( GradientType.LINEAR, [0x0000FF, 0x00FF00], [1, 1], [0, 255], matrix );
	graphics.drawRect( 0, 0, width, height );
	
}

}

If I remember well, because a vertical linear gradient is just an oriented ones… or maybe just inverting width/100 by height/100 on the same matrix, and the linear rotation matrix was doing the rest of the job.

So you retrieve well

gradientFill-02

But at that time, Flash gradient were accurate, weren’t they ?
Now, they are not anymore.
They are weird like Neko/Windows ones.

Any hint where to check ?
I’m losing myself in drawCommanderBuffer/Reader.

Even simpler !

To retrieve the true gradient teints on all plateforms.

Without modification on CanvasGraphics.hx.

Play with the translationX property of the matrix.
Just translate with the half size of the view.

eg:

package;

import openfl.display.GradientType;
import openfl.display.Sprite;
import openfl.geom.Matrix;

class GradientFill extends Sprite 
{

	public function new() 
	{
		super();
		
		var width = 1600;
		var height = 900;
		var matrix:Matrix = new Matrix( 1, 0, 0, 1, width/2, 0);
		graphics.beginGradientFill( GradientType.LINEAR, [0x0000FF, 0x00FF00], [1, 1], [0, 255], matrix );
		graphics.drawRect( 0, 0, width, height );
		
	}
	
}

In fact, I was just missing a primordial part of the gradient.fill tools.

Matrix.createGradientBox()…

package;

import openfl.display.GradientType;
import openfl.display.Sprite;
import openfl.geom.Matrix;

class GradientFill extends Sprite 
{
	public function new() 
	{
		super();
	
		var width = 1600;
		var height = 900;
		var matrix:Matrix = new Matrix( 1, 0, 0, 1, 0, 0);
		matrix.createGradientBox( width, height, 0, 0, 0 );
		graphics.beginGradientFill( GradientType.LINEAR, [0x0000FF, 0x00FF00], [1, 1], [0, 255], matrix );
		graphics.drawRect( 0, 0, width, height );
	}
}

Which one resolve all my teints problems whatever the platform.

However, I’m wondering if in the AS3 version, a default null matrix was autofilling the right matrix with an automatic createGradientBox matrix who filled the view with the right projected width/height…

To avoid that default and not accurate gradient behaviors.

Or maybe I had implemented it, and have lost track of it it in my newer UI attempt version.

The wheel is wheeled. ^^’

If Flash does not do it then other platforms also should not. Seems like -100.0/100.0 are still the correct values to have the same effect like in Flash while you needed something different.

What do you mean by AS3 version? Was that Flex?

@Outline
In my long time memories, when you let an empty matrix in beginGradientFill(), your gradient colors were still accurate.

Presently they are not.

Whatever the with -100 and 100 without the matrix, (or with a null default matrix), you only have the half right side of the gradient.
Your blue is not blue at x = 0, it is already half-green.
And your green is full green at x = 100.
So all pixels after x=100, are not gradiented anymore.

Actually the default null matrix leads to a wrong gradient.

You’re fully correct that these gradients are now displayed incorrectly with null Matrix (corresponding to how they actually look and what they should look like) but I’ve just checked it on Flash plaform (target FP26) directly and this is how they display in Flash with the same code and parameters. It might be different in the past, I could not remember - primarily because I’ve not used gradients that much :frowning:

From what I understood OpenFL goal is to imitate Flash API so as long as new parameters makes OpenFL result similar/identical to Flash’s, they should be treated as fully correct ones.

So -100.0/100.0 are correct to imitate Flash’s but may be incorrect looking at the final gradient result on screen, still it is consistent throughout all platforms instead of having good-looking gradient on some and an invalid on some other :slight_smile: It is great though you’ve found a solution for yourself to get the gradient exactly how you need it to look like :slight_smile:

@outline
I could have agreed with you.
Could have :stuck_out_tongue:
But the goal of the API may remain to display the right thing at the right place.

With the default null matrix, in my flashdeveloper old memories, with matrix left to null.
We were retrieving a fromColor to toColor normal gradient

gradientFill-03

If matrix can be left null, the displayed gradient could auto generate the size relative GradientBox.
I’m stil looking for it.
But it requires data who are not yet defined… they are set later in the draw methods.

I’m not fan of modifying lib files.
The proof is… I may have lost a bunch of little modifications for years now which rectified some particular UI behavior, and am just discovering now why it did not work anymore.
^^’

Anyway, currently, thanks for your reminder, I can do it with my frame+1 Framework, because I was already externalising “Fill behavior” of my components, I have just to pass a reference to the GraphicsED class to check its size and autofill a createGradientBox if matrix == null.

All that said,
The more probable now is I am wrong from all my long time memories, and gradients never worked without createGradientBox, and am just so used to my UI implementation, I realize only now that I lose them, how it truly works
And all was said in the first post, I am seriously becoming insane. ^^

Thanks for your point of view and clarification Outline :wink:

1 Like

If we find parameters that look correct in multiple different kinds of gradient tests, we do want consistency with Flash, and hopefully between platforms. There’s a lot of experimentation/guessing involved in trying to get the correct values. We did just change to 32-bit color by default instead of 24-bit, so there’s a chance that changed some things, or it could have just been specific tests we were doing. Don’t forget about radial gradients as well :sweat:

@singmajesty
Thanks to Outline, I realized it was the repository itself, Flash, I wasn’t taking account of.
You’re true ! How to reach a multiplatform homogeneity without repository…
Anyway, keep on your good work :slight_smile: