Button fill animation

Hello everyone.

I am trying to make this type of click effect.


How can I achieve it? I am not quite sure. I know how to trigger it. But I don’t know how to make it. All help appreciated


Hi. I understand your issue and the problem you are facing.

I’ll try to put it into simple understanding for you as I feel it’d be better to teach you how to do something than to just do it for you, If you need full code though, you can DM me on arvin#6145.

By the Button Fill Animation, I assume you mean the circle that appears on the button.

In reality it’s quite easy.


To achieve the circle:

The first step is to insert the circle.

The developer of the Gui has retrieved the Mouse Position, and used ROBLOX’s Instance.new() to insert a circle there, you can simply get a photoshop image of a circle if you please.

To achieve the growing size

Next, the developer used a loop to increase the size, this can be achieved in a similar form as such:

size = 1
for i = 1, 100 do
circle.size = Udim2.new(ScalarX, size+1, ScalarY, size+1)

To achieve the transparency gradient

Simpler than you think, this also uses a loop;

for i = 1, 50 do
circle.Transparency = circle.Transparency+2

Pretty sure they use ClipsDescendants (so the circle doesn’t clip past the button).

For the position, you’d get the Mouse’s position minus the button’s AbsolutePosition. I also had to subtract the y position by 36, I’m guessing it’s because of the topbar. Remember to set the circle’s AnchorPoint to (.5,.5), makes it way easier to handle this.

Now, use TweenService to make the white circle slowly grow in size and dissapear.

This is what I ended up with:


local tweenService = game:GetService("TweenService")
local textButton = script.Parent
local circle = textButton.Circle

script.Parent.MouseButton1Down:Connect(function(x,y) -- mouse position
	local pos = UDim2.new(0,x-textButton.AbsolutePosition.X,0,y-textButton.AbsolutePosition.Y-36)
	circle.Position = pos
	circle.Size = UDim2.new(0,1,0,1)
	circle.ImageTransparency = .5
	local goal = {}
	goal.Size = UDim2.new(0,500,0,500)
	goal.ImageTransparency = 1
	local tween = tweenService:Create(circle, TweenInfo.new(1,Enum.EasingStyle.Sine,Enum.EasingDirection.Out), goal)
	-- button stuff

Good script!
@himmerm you should look at individual things in the code as well so you can understand and use them in the future. I find this helps me as well :slight_smile:

Of course, you have to have the two variables for the button and the circle image. The circle NEEDS to be placed inside the button, and the button needs to have ClipsDescendants to true. TweenService is a service that allows the interpolation (transition) of instances for any sort of values (Position, CFrame, Number Properties like Transparency, etc.).

When the button is clicked, you receive two extra variables only available in the enclosing function, which is the x and y of the mouse click position, relative to the button. Getting and subtracting absolute position of the button allows proper placement to the pixel.

You then see this:

local goal = {}
goal.Size = UDim2.new(0,500,0,500)
goal.ImageTransparency = 1

Goal is a table, and you are setting two table values. What you see here is the equivalent to this:
local goal = {Size = UDim2.new(0,500,0,500),ImageTransparency = 1}

When using TweenService, you input the instance (the circle image), tween info (time,style,math direction), and any properties you want to change as a table. If you didn’t want the goal variable, and wanted to not have to reference an extra instance, the alternative was this:

tweenService:Create(circle, TweenInfo.new(1,Enum.EasingStyle.Sine,Enum.EasingDirection.Out), local goal = {Size = UDim2.new(0,500,0,500),ImageTransparency = 1}):Play()

However, that looks messy and is not recommended. I just did it to show you what is actually happening.

And that’s how it works!
Hope that helps :slight_smile:



For anyone new reading this post, I made a quick module based on @Lightning_Splash’s code.



local module = require(modulelocation.BubbleButtonAPI)

module.Connect(button, {button}, optionalParentOverride) 
-- Second parameter is a list of objects you would like the module to clip.
-- Third Parameter is if you'd like the circle to be parented to something which is not the button, such as a frame etc.


For people that want to create a new circle on every click, just do

	--creating a new circle instead of using a pre-made one.
	local Circle = Instance.new("ImageLabel",MainFrame) --Change MainFrame to whatever you're clicking on.
	Circle.Image = "rbxassetid://11400274201"
	Circle.AnchorPoint = Vector2.new(0.5,0.5)
	Circle.Position = UDim2.new(2,0,2,0)
	Circle.BackgroundTransparency = 1
	Circle.Name = "TempCircle"

	local pos = UDim2.new(0,x-MainFrame.AbsolutePosition.X,0,y-MainFrame.AbsolutePosition.Y)
	Circle.Position = pos
	Circle.Size = UDim2.new(0,1,0,1)
	Circle.ImageTransparency = .5
	local goal = {}
	goal.Size = UDim2.new(0,500,0,500)
	goal.ImageTransparency = 1
	local tween = TweenService:Create(Circle, TweenInfo.new(1,Enum.EasingStyle.Sine,Enum.EasingDirection.Out), goal)
	Circle:Destroy() --Make sure to destroy the circle after the tween is completed else your game will go laggy