Last active
May 2, 2022 04:13
-
-
Save HoraceBury/70f46d144c3371f8db3d to your computer and use it in GitHub Desktop.
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- 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