HTML5 Masks in OpenFL?

Hey everyone,

I’m relatively new to OpenFL. I’m working on writing some cross-platform games (Flash, HTML5, Android, iOS) and one has a feature that requires a mask to be built dynamically as the user moves the mouse. I’ve got this working in flash by using a mask and adding to it’s graphics object based on the user’s mouse movement. However, it’s not working in HTML5 at all.

First, are masks even supported in HTML5 now? I’ve done lots of googling on the topic and most of the info I’m digging up is 1 to 3 years old.

Second, if masks are supported, can they be complex shapes (i.e. not a rectangle)? Can a bitmap image be used to create an irregular shape?

Cheers

I don’t know about the regular functionality, but you could always use bitmap drawing features to simulate it.

Specifically, use copyPixels()'s alphaBitmapData parameter.

You’ll need to draw your source image(s) to a bitmap beforehand, but other than that it should do pretty much exactly what you want.

Thanks for the reply, this looked really promising. I tried it out and it works as you would expect in Flash (well sort of…more later) but in HTML5, I just get the full image I’m trying to mask. It looks like it’s just ignored the alphaBitmapData parameter entirely. So should I take that to mean that this type of masking is not supported in the HTML5 target?

Side note, in Flash this did work quite nicely, except that any time I draw to the alphaBitmapData object and it overlaps pixels that are already there, the overlapping portions are treated as unmasked. For example, if I create a sprite and draw to its graphics twice (two calls to drawCircle) and then draw that sprite to the bitmap data object used for alphaBitmapData, the overlapping portions of the circles act as though they are fully transparent creating a “venn diagram”-like knockout instead of two merged circles as I would expect. Any pointers on this? I’m probably just missing something.

Hopefully this functionality will be coming soon to HTML5, but I guess you could reinvent that wheel too. (Get a byte array from the pixels, modify the array manually, then put it back in the bitmap. Not necessarily efficient, but it should be faster than modifying pixels one at a time.)

I’m not sure about the issue with overlapping. Are you passing true or false for mergeAlpha?

Actually, BlendMode.ALPHA is probably the way to go if this doesn’t work.

Well, i’ve tried this as well and still no luck. Thanks for pointing me to several different options to try.

To recap, trying to use a normal mask (setting the mask property to a sprite) didn’t work in HTML5 at all.

Using copy pixels with an alphabitmapmask seems to display nothing at all.

Using blend modes just composites the mask on top of the image

Here’s what they look like in Flash. First, the orange box is what i’m trying to mask. I’ve just added it to the stage unaltered. Next, the four overlapping black circles is my mask. Again, I’ve just added it to the stage unaltered. The third image is the two images composited together using BlendMode.ALPHA. The fourth image is the first two images composited together using copy pixels and the alphabitmapmask.

Now the same code in the HTML5 target. The first two images (the image to be masked and the mask itself) display fine. The third image shows how BlendMode.ALPHA is just compositing the two together. The last image is blank, which is what seems to happen when trying to use copyPixels with an alphabitmapmask.

So it seems that masks don’t work (still don’t have a clear answer on whether they should) and any bitmap operations involving the alpha channel seem to either ignore the alpha or flat out fail to work at all.

Looks like masking in HTML5 is just not realistic at this point? I’ve used EaselJS to do this kind of thing on a canvas without issue so I don’t think it’s an issue with the browser.

If you use displayObject.mask it should be supported in HTML5 canvas, but I’ve noticed that canvas masking only works with simple shapes, complex drawing seems to fail, but perhaps it depends on the browser

I noticed with the masks on HTML 5 canvas, that, while they work well, there seems to be bug in applying the mask to a shape and then rotating the whole shape. The mask in HTML5 rotates the wrong way compared to the shape being masked. Perhaps an example best demonstrates…

package;

import openfl.display.Sprite;
import openfl.events.MouseEvent;
import openfl.Lib;


class MaskTest extends Sprite 
{
	
	private var demo_btn:Sprite = new Sprite();
	private var sq:Sprite = new Sprite();
	private var sqMask:Sprite = new Sprite();

	public function new() 
	{
		super();
		
		demo_btn.graphics.beginFill(0xFF0000, 1);
		demo_btn.graphics.drawRoundRect(0, 0, 100, 30, 8, 8);
		demo_btn.graphics.endFill();
		demo_btn.buttonMode = true;
		this.addChild(demo_btn);
		#if flash
		demo_btn.addEventListener(MouseEvent.CLICK, rotateSq);
		#end
		#if js
		demo_btn.addEventListener(MouseEvent.MOUSE_DOWN, rotateSq);
		#end
		
		sq.graphics.beginFill(0x0000FF, 1);
		sq.graphics.drawRect(0, 0, 150, 150);
		sq.graphics.endFill();
		sq.x = 360;
		sq.y = 240;
		this.addChild(sq);
		
		sqMask.graphics.beginFill(0, 1);
		sqMask.graphics.drawRect(0, 0, 150, 150);
		sq.addChild(sqMask);
		sq.mask = sqMask;
	}
	
	private function rotateSq(e:MouseEvent):Void {
		sq.rotation += 15;
	}

}

1 Like

I have same issue. @singmajesty

Does anyone else have this issue?

Tricky, I can’t immediately find what’s causing this :frowning:

Masks in next don’t work using text, or drawing a bitmap of text to use as a mask in html5, works fine in flash.