Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Flood fill a display object with a Gfx2.0 gradient fill. Can be used to provide the Android Material Design button interaction animation, eg: http://www.google.com/design/spec/components/buttons.html#buttons-flat-raised-buttons
-- ref: http://docs.coronalabs.com/daily/guide/graphics/effects.html#generator.radialgradient
local back, outer, inner = {0,1,0,1}, {0,.9,0,.05}, {0,1,0,.05}
-- backing colour rect
display.newRect( display.actualCenterX*.5, display.actualContentHeight*.25, 220, 220 ).fill = back
-- radial fill rect
local r = display.newRect( display.actualCenterX*.5, display.actualContentHeight*.25, 200, 200 )
local function getRadius( r, xOffset, yOffset )
local xFactor, yFactor
if (xOffset < .5) then xFactor=xOffset else xFactor=math.abs(xOffset-1) end
if (yOffset < .5) then yFactor=yOffset else yFactor=math.abs(yOffset-1) end
local c = math.lengthOf( xFactor, yFactor , (r.width/r.height),1 ) + .3
return c
end
local function fillIn( r, xOffset, yOffset )
local c = getRadius( r, xOffset, yOffset )
r.fill.effect = "generator.radialGradient"
r.fill.effect.color1 = inner
r.fill.effect.color2 = outer
r.fill.effect.center_and_radiuses = { .5,.5 , c,c+.05 }
r.fill.effect.aspectRatio = r.width / r.height -- adjust for non-square rectangles
end
fillIn( r, .5,.5 )
r.fill.effect.center_and_radiuses = { .5,.5 , 1,1 }
local function tap(e)
-- temp value to be adjusted and then applied to the fill effect per screen frame
local values = { x=0, y=0, radius=0, target=0 }
-- updates the fill size
local function enterFrameOne()
e.target.fill.effect.center_and_radiuses = { values.x, values.y, values.radius, values.radius+.01 }
-- change the radial fill to the current frame value
-- there needs to be a difference between the inner and outer radii
-- .01 for a slight aliasing on the border between the two colours
end
-- begins the screen updates
local function startEnterFrameOne()
values.radius = 0
e.target.fill.effect.center_and_radiuses = { values.x, values.y, values.radius, values.radius+.01 }
r.fill.effect.color1 = inner
r.fill.effect.color2 = outer
Runtime:addEventListener( "enterFrame", enterFrameOne )
end
-- ends the screen updates
local function endEnterFrameOne()
Runtime:removeEventListener( "enterFrame", enterFrameOne )
end
-- updates the fill size
local function enterFrameTwo()
e.target.fill.effect.center_and_radiuses = { values.x, values.y, values.radius+.01, values.radius }
end
-- begins the screen updates
local function startEnterFrameTwo()
values.radius = 0
Runtime:addEventListener( "enterFrame", enterFrameTwo )
end
-- ends the screen updates
local function endEnterFrameTwo()
Runtime:removeEventListener( "enterFrame", enterFrameTwo )
end
-- calculate location within the rect of the tap
local x, y = e.target:contentToLocal( e.x, e.y )
values.x, values.y = (x + e.target.width/2)/e.target.width, (y + e.target.height/2)/e.target.height
values.target = getRadius( e.target, values.x, values.y )
local t = 300 -- expansion times
transition.to( values, { delay=0, time=t, radius=values.target, onStart=startEnterFrameOne, onComplete=endEnterFrameOne } )
transition.to( values, { delay=t, time=t, radius=values.target, onStart=startEnterFrameTwo, onComplete=endEnterFrameTwo } )
return true
end
r:addEventListener( "tap", tap )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.