Hello everyone!
Is it possible to create a mask from polygon(or rect, or circle) so display group will be clipped by this polygon?
As far as I see the only way to create mask is to use mask image from app bundle.
Hello everyone!
Is it possible to create a mask from polygon(or rect, or circle) so display group will be clipped by this polygon?
As far as I see the only way to create mask is to use mask image from app bundle.
Basically, you’d want something like this:
Get the contentBounds of the object
Extend it by three pixels in each direction
Draw a black rect in this region
Set the fill color of your object to black
Apply filter.invert to your object to turn it white
Put it over the black rect
display.captureBounds
display.save the capture
At some point schroederapps mentioned something along these lines. I’m not sure where that’s at right now.
The mask also must be evenly divisible by 4 in both directions. So I would say extend it by 3 or more pixels in all directions to point where it’s divisible by 4.
Rob
Thank you for answers! I tried to implement them in my app; there was some interesting point and caveats, so I’m going to share the story with other developers.
In my game I tried to implement some vessels, fully or partially filled with water. Vessels will have different shape and size, so the only suitable way to draw water that I found – draw it as rect and then clip it by edges of the vessel. That’s how I encountered this problem of polygon clipping.
You can see my code in this gist – https://gist.github.com/alexdoloz/65e71b6ee6e0309e5432
There are two gotchas:
Jan 22 13:18:40 Corona Simulator[36758] <Error>: CGBitmapContextCreateWithData: failed to create delegate.
Jan 22 13:18:40 Corona Simulator[36758] <Error>: CGContextDrawImage: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
Jan 22 13:18:40 Corona Simulator[36758] <Error>: CGBitmapContextCreateImage: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
Mask image has double size, so to work properly, it has to be scaled by 0.5 or less.
Also I have a question to StarCrunch – you suggested make object black and then filter.invert it. But why, if it’s possible to just make object white?
Yes, captures are full of surprises.
As for making the object black, it’s just a concession to how the colors work. The fill color is a tint, so black really will make an object black, but “white” only leaves its color intact.
I should point out that I’m allowing for the possibility of using images and sprites when you make a mask. If it’s only shapes, then of course they will already be white.
I have made this work in very specific circumastances, but my solution involves saving a new captured PNG and loading it as a mask. If you know the device’s resolution (like if you are making an iPad-only app), then it is possible. But if you are using dynamic scaling to support multiple resolutions then it gets very hard to guarantee that the outputted image meets the “divide by 4” requirement for masks (because the outputted image is set to the device’s native resolution, not in stage coordinates). I’m traveling today so it’ll take some time, but I do have an “automask” module that I was working in last year. It works, but only when you can control the screen resolution. I’ll post it here (fair warning - it won’t be commented and may be horribly formatted).
Basically, you’d want something like this:
Get the contentBounds of the object
Extend it by three pixels in each direction
Draw a black rect in this region
Set the fill color of your object to black
Apply filter.invert to your object to turn it white
Put it over the black rect
display.captureBounds
display.save the capture
At some point schroederapps mentioned something along these lines. I’m not sure where that’s at right now.
The mask also must be evenly divisible by 4 in both directions. So I would say extend it by 3 or more pixels in all directions to point where it’s divisible by 4.
Rob
Thank you for answers! I tried to implement them in my app; there was some interesting point and caveats, so I’m going to share the story with other developers.
In my game I tried to implement some vessels, fully or partially filled with water. Vessels will have different shape and size, so the only suitable way to draw water that I found – draw it as rect and then clip it by edges of the vessel. That’s how I encountered this problem of polygon clipping.
You can see my code in this gist – https://gist.github.com/alexdoloz/65e71b6ee6e0309e5432
There are two gotchas:
Jan 22 13:18:40 Corona Simulator[36758] <Error>: CGBitmapContextCreateWithData: failed to create delegate.
Jan 22 13:18:40 Corona Simulator[36758] <Error>: CGContextDrawImage: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
Jan 22 13:18:40 Corona Simulator[36758] <Error>: CGBitmapContextCreateImage: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
Mask image has double size, so to work properly, it has to be scaled by 0.5 or less.
Also I have a question to StarCrunch – you suggested make object black and then filter.invert it. But why, if it’s possible to just make object white?
Yes, captures are full of surprises.
As for making the object black, it’s just a concession to how the colors work. The fill color is a tint, so black really will make an object black, but “white” only leaves its color intact.
I should point out that I’m allowing for the possibility of using images and sprites when you make a mask. If it’s only shapes, then of course they will already be white.
I have made this work in very specific circumastances, but my solution involves saving a new captured PNG and loading it as a mask. If you know the device’s resolution (like if you are making an iPad-only app), then it is possible. But if you are using dynamic scaling to support multiple resolutions then it gets very hard to guarantee that the outputted image meets the “divide by 4” requirement for masks (because the outputted image is set to the device’s native resolution, not in stage coordinates). I’m traveling today so it’ll take some time, but I do have an “automask” module that I was working in last year. It works, but only when you can control the screen resolution. I’ll post it here (fair warning - it won’t be commented and may be horribly formatted).