Is it possible to create the iOS Homescreen animation in Roblox?

Hello,

I’m looking to recreate this animation in Roblox using TweenService and a grid with frames, but I’m unsure how to go about it. This is what I’m going for:


It doesn’t have to do the bounce back thing, but I’m curious on how to do the thing where it gets smaller until it’s a normal size.

Thank you.

1 Like

Since grid layouts aren’t fond of their elements flying away and out of order, you could make a temporary fake frame that imitates where the apps would be, probably with AbsoluteSize/Absolute Position math. Save the position and size they’re supposed to be. You can calculate the offset between the center of the screen and the closest corner of an app, then scale that offset until the app is concealed. (the fake frame should have ClipsDescendants on) Tween all these fake apps to the saved position, then replace the gimmick frame with the actual grid. There’s a couple fun ways to determine where the apps fly in from and how their size changes while they reach their goal of planting into their respective spots.

1 Like

It does make a little sense. I already do this with notifications to make it so they have the ability to tween off to the side when their display time is over. I’m not sure how to correctly calculate the offset it should have though.

1 Like

When I tried to replicate this effect, I ended up scrapping half of my idea and I kept the offset math. You can get the offset between any two positions using AbsolutePosition.

local offset = frame.AbsolutePosition - referenceFrame.AbsolutePosition

referenceFrame would probably be the frame that encapsulates all those apps. I just cloned all apps and placed them on a duplicate frame with their Position and Size imitating their real copies using only the Scale parameter and not Offset. You can tween the size of a centered parent frame of those copies from 16 down to 1.

2 Likes

I’m not very sure what you mean. I tried just setting the offset of the mock frame to that like this, but it did not change:

		local offset = {v.AbsolutePosition - script.Parent.Parent["concept #1"]["Frame 1"].AbsolutePosition}
		
		print(offset) -- {0,0}
		
		v.Position = UDim2.new(0, offset[1], 0, offset[2])

I’m using the code on concept UI, it will be different in practice

It shouldn’t change. That’s the point. A fake copy of all apps should appear like its original copy but still retain the ability to be pushed away from the center by varying the parent’s size. What method are you planning to use?

I was planning on creating an exact clone of the apps page when the button is clicked, then tweeting them to be their normal sizes like that, I just wasn’t sure how to offset it like that.

Are you in favor of tweening all apps individually or just tweening the parent’s size while the apps all use Scale dimensions to shrink as the parent shrinks?

Either works, my original plan was to tween them all.

Alright, it helps to know so I don’t reason around an incompatible solution.

To avoid personalizing the offsets as much as possible for each fake app, one could choose to use the center of each app as the position used when imitating them on a fake frame. Calculate the largest centered rectangle that doesn’t overlap any app’s area and determine the scaled size of a screen-sized box that fits within the rectangle. Divide one by the smallest of the two dimensions of that scaled screen rectangle to get the off-screen offset for each fake app.

To get an offset from the center of an app to the center of the screen, half of the app’s AbsoluteSize’s dimension is either added/subtracted (whichever operation brings each offset’s dimension closer to zero) with the offset calculation snippet I shared earlier.

What does it look like when you try to imitate an app? I had an issue of them all breaking aspect ratio because I forgot to set SizeConstraint back to XY.

1 Like

I’m not on my PC at the moment, but it looks like the easiest solution might just be to scale the main frame up a lot and scale it down in the normal animation?

Yeah, that’s what I did. I lose the ability to make some apps fall slower like the iPhone does but it’s a lot simpler to implement.

1 Like

Are you able to show how you did this? I’m looking for the same effect and have not gotten very far with this code, cheers!

	local TweenService = game:GetService("TweenService")

	local ScaleFactor = 1.5

	local DuplicateFrame = frame:Clone()
	DuplicateFrame.Parent = frame.Parent
	DuplicateFrame.Size = UDim2.new(
		frame.Size.X.Scale * ScaleFactor,
		0,
		frame.Size.Y.Scale * ScaleFactor,
		0
	)

	DuplicateFrame.Position = UDim2.new(
		0,
		DuplicateFrame.AbsolutePosition.X - frame.AbsolutePosition.X,
		0,
		DuplicateFrame.AbsolutePosition.Y - frame.AbsolutePosition.Y
	)

	local Tween = TweenService:Create(DuplicateFrame, TweenInfo.new(
		1,
		Enum.EasingStyle.Quad,
		Enum.EasingDirection.Out,
		0,
		false,
		0
		), {
			Size = frame.Size
		}
	)
	Tween:Play()

	Tween.Completed:Connect(function()
		DuplicateFrame:Destroy()
	end)

I tried coding it myself using this, but it’s not what I was hoping for.

	local Apps = MainFrame.Apps
	local Clone = Apps.MainFrame:Clone()
	
	Clone.Parent = Apps
	Clone.Visible = false
	Clone.Name = "Duplicate"
	
	for i, v: Frame in ipairs(Clone:GetChildren()) do
		if not v:IsA("Frame") then continue end
		
		v.BackgroundTransparency = 0
		
		for i, v in ipairs(v:GetChildren()) do
			if v:IsA("TextLabel") then
				v.TextTransparency = 1
			elseif v:IsA("ImageLabel") then
				v.ImageTransparency = 0
			end
		end
	end
	
	Clone.Position = UDim2.new(-0.07,0,-.157,0)
	Clone.Size = UDim2.new(1.164,0,1.34,0)
	
	TweenService:Create(Apps, TweenInfo.new(TimeToComplete + (TimeToComplete * .4), Enum.EasingStyle.Quart, Enum.EasingDirection.Out, 0, false), {BackgroundTransparency = .1}):Play()
	
	local Tween = TweenService:Create(Clone, TweenInfo.new(TimeToComplete, Enum.EasingStyle.Quart), {Position = UDim2.new(.017,0,0.35,0), Size= UDim2.new(.965,0,.928,0)})
	
	for i, v: Frame in ipairs(Clone:GetChildren()) do
		if not v:IsA("Frame") then continue end

		TweenService:Create(v, TweenInfo.new(TimeToComplete + .2, Enum.EasingStyle.Quart), {BackgroundTransparency = .2}):Play()

		for i, v in ipairs(v:GetChildren()) do
			if v:IsA("TextLabel") then
				TweenService:Create(v, TweenInfo.new(TimeToComplete * .4, Enum.EasingStyle.Quart), {TextTransparency = 0}):Play()
			elseif v:IsA("ImageLabel") then
				TweenService:Create(v, TweenInfo.new(TimeToComplete * .4, Enum.EasingStyle.Quart), {ImageTransparency = 0}):Play()
			end
		end
	end
	
	Clone.Visible = true
	Tween:Play()
	Tween.Completed:Wait()
	
	Tween = TweenService:Create(Clone, TweenInfo.new(TimeToComplete * .4, Enum.EasingStyle.Quart, Enum.EasingDirection.Out, 0, false), {Position = UDim2.new(.027,0,.051,0), Size = UDim2.new(.947,0,.894,0)})
	Tween:Play()
	
	Tween.Completed:Wait()
	
	Tween = TweenService:Create(Clone, TweenInfo.new(TimeToComplete * .4, Enum.EasingStyle.Quart, Enum.EasingDirection.Out, 0, false), {Position = UDim2.new(.017,0,0.35,0), Size= UDim2.new(.965,0,.928,0)})
	Tween:Play()

Looks like you’re headed in the right direction, you just aren’t applying the tweens in the proper order. Have you tried changing the anchor point to the background frame to be in the center? From there you could modify the scale and use Bounce as the TweenStyle. Alternatively look into using springs.

I’m not 100% sure what you’re looking for. I notice the zoom effect does work. You’re setting the transparency of images in each square to 0, then playing a tween that brings the transparency to 0 again. Did you mean to initially set it to 1 instead?

Thank you, did this and it’s looking good. I removed the bounce back, but I like how it looks.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.