Hi everyone. I’m glad to join Corona SDK community.
I’m just beginning to research framework capabilities so don’t laugh if my question is stupid or trivial.
Here is the task.
I’m trying to create something like a mask for the whole scene. The situation is pretty much the same as a Flashlight sample project but with some differences.
The most important difference is that I can’t use ready-to-use mask image, i.e. mask mus be dynamic.
Obviously the easiest way to create some shape is to use vector elements. In my case RoundedRect is almost exactly what I want. The main problem with vector objects is that I couldn’t find a way to blur the edges properly. Of course I can use filter.blurGaussian effect but it is heavy operation and I need to apply this in each frame which causes very poor performance when many (up to about 30-50) objects are used to create a compound “mask”.
I already tried several approaches and my last attempt was with snapshot. In fact I was able to get the result I want but I’m sure that the approach I’m using is not the most efficient.
Could you please suggest what else I can do to achieve the same result as on the screenshot?
Maybe some trick with real mask? I tried that but I’m stuck at the moment when I need to change the dimentions of the mask (length or width in this particular case) w/o deforming it.
Again, this is almost the same as Flashlight from the samples but mask must by dynamic so I can’t use “blurry rounded rectangle” image because the width of the rectangle could be different in each frame.
Please check the code to see what I mean. This is full listing of the main.lua file
local centerX = display.contentCenterX local centerY = display.contentCenterY local w = display.actualContentWidth local h = display.actualContentHeight local image = display.newImageRect( "image.png", 768, 1024 ) image:translate( centerX, centerY ) -- snapshot local snapshot = display.newSnapshot(w, h) snapshot:translate(centerX, centerY) local background = display.newRect( 0, 0, w, h) background:setFillColor(0, 0, 0, 0.9) snapshot.canvas:insert(background) -- mask coord local maskX1, maskY1 = 50, 50 local maskX2, maskY2 = 500, 1000 local function refreshMask(maskX, maskY, destX, destY) -- add transparent mask local length = math.sqrt( (destX - maskX) ^ 2 + (destY - maskY) ^ 2) local deltaAngle = 360 - math.deg(math.atan2(destX - maskX, destY - maskY)) local mask = display.newRoundedRect(0, 0, 200, length, 100) mask.anchorX = 0.5 mask.anchorY = 0 mask.x = maskX - snapshot.x mask.y = maskY - snapshot.y mask.rotation = deltaAngle mask.fill.blendMode = { srcColor = "zero", dstColor="oneMinusSrcAlpha" } snapshot.canvas:insert(mask) -- blur masked image snapshot.fill.effect = "filter.blurGaussian" snapshot.fill.effect.horizontal.blurSize = 200 snapshot.fill.effect.vertical.blurSize = 200 -- refresh snapshot snapshot:invalidate("canvas") end local function screenTouch ( event ) if (event.phase == "moved") then -- clear snapshot because mask could be changed in each frame snapshot:invalidate() -- renew background snapshot.canvas:insert(background) -- draw compound mask refreshMask(maskX1, maskY1, event.x, event.y) refreshMask(maskX2, maskY2, event.x, event.y) end end local stage = display.getCurrentStage() stage:addEventListener("touch", screenTouch)