HTML5 / Develop: Possible fix for MovieClip gotoAndStop colorTransform bug


#1

Hi team,

there is currently a bug in OpenFL with colorTransform and gotoAndStop in MovieClips. In short, colorTransform is not set back to the initial state when gotoAndStop is called. This is calling an obvious bug in our buttons where we use a colorTransform state to hightlight the background in the “_over” and “_down” labels but have not set any colorTransform in the “_up” state. Because when gotoAndStop("_up") is called, the colorTransform is not removed.

With the recent addition of the _up, _over and _down behavior in buttonMode we now want to fix this colorTransform bug. What happens is that frameObject.colorTransform is null and hence displayObject.transform.colorTransform is left as it is, meaning it is left with the wrong value from the “_over” frame.

An easy fix seems to be to change MovieClip.hx in line 778:

if (frameObject.colorTransform != null) {
			
	displayObject.transform.colorTransform = frameObject.colorTransform;
			
}

to

if (frameObject.colorTransform != null) {
			
	displayObject.transform.colorTransform = frameObject.colorTransform;
			
}
else {
			
	displayObject.transform.colorTransform = new ColorTransform();
			
}

However I am not sure if this might cause unwanted side effects that I am currently not aware of so I wanted to ask before creating a merge request. Possibly, similar updates like matrix might require the same fix, however they are currently not affecting us and I don’t want to change code without testing it.

It might be neccessary to only update when the colorTransform has been set before to avoid Object Creation spamming. An alternative would be to change SWFLite to set a default ColorTransform for every object in the first frame, or make the renderer work with transform.colorTransform being null, which fails right now.

Please let me know what you think and if we should create a PR.

Thanks,
Ruben


#2

I think it is important to see what happens if you 1.) set a colorTransform and 2.) other properties (unrelated to colorTransform) are updated in subsequent frames.

I think some properties are null in subsequent frames when they are not updated, but the previous value remains, in order to prevent needing to define it every single frame, but perhaps colorTransform doesn’t work this way.


#3

In my test it looks like colorTransform is set in the frameObject.colorTransform every single frame it exists, not just in the first frame where it changes its’ behavior. But maybe it would be performance friendly then to have a default colorTransform for every first frame of a MovieClip in SWFLite, if no other colorTransform is defined, instead of updating every frame. Let me know if you have a preference and I will look into creating a pull request.


#4

If that appears to be the case (frames that don’t set a color transform have it replicated every time) then a pull request would be great :slight_smile:


#5

Just to avoid a misunderstanding. The current situation looks like when no colorTransform is set in the SWF for a given frame, then frameObject.colorTransform is null. In every other frame it looks like the colorTransform is set in frameObject.colorTransform, even if it was introduced in an earlier frame and did not change its’ behavior since then.

A fix would be either to a) add a default ColorTransform for every first frame of a MovieClip that does not have any other colorTransform in SWFLite or b) use the code I wrote above, possibly with an optimization to avoid object creation spamming, although I am not sure how that could look like.

Let me know your preference :slight_smile:


#6

Let’s leave the symbol behavior as it is – no colorTransform is common, so let’s keep that light and null.

If this is truly the case, then your proposed fix is good. There’s an internal __equals method (and an internal __isDefault method) on ColorTransform you can use to avoid creating a new ColorTransform each frame


#7

The fix turned out to be simpler than what I expected because the behavior was a bit different to what I thought I observed. The colorTransform is null both for the first frame where the object is created, as well as for any other frame after a colorTransform was set but did not change. That means a check for colorTransform == null would not work because there is no difference whether it means this is a default colorTransform, or the colorTransform that was introduced in an earlier frame.

So instead I introduced a reset parameter in the __updateDisplayObject function that is true only when an object is created, because when an object is created, all properties should be reset to default unless a different behavior is specified. This might possibly also be used for matrix, etc., but this is currently not something we have a test case for so I did not change that behavior.

The PR is here: https://github.com/openfl/openfl/pull/1881

Thanks again for your input :slight_smile: