A powerful and fully animated customization UI designed for The Cat Shelter π±.
This script allows players to customize their catβs appearance using decals, live preview system, and an integrated decal marketplace. Includes smooth animations, pagination system, verified filter, and real-time preview updates.
Built with a clean modern UI design and optimized for performance.
No comments yet. Be the first to comment!
1-- Cat Face Customizer Made By GZ
2
3local Players = game:GetService("Players")
4local TweenService = game:GetService("TweenService")
5local UserInputService = game:GetService("UserInputService")
6local HttpService = game:GetService("HttpService")
7local ReplicatedStorage = game:GetService("ReplicatedStorage")
8
9local LocalPlayer = Players.LocalPlayer
10local PlayerGui = LocalPlayer:WaitForChild("PlayerGui")
11
12-- ScreenGui
13local ScreenGui = Instance.new("ScreenGui")
14ScreenGui.Name = "CatCustomizerUI"
15ScreenGui.ResetOnSpawn = false
16ScreenGui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling
17ScreenGui.Parent = PlayerGui
18
19-- ββββββββββββββββββββββββββββββββββββββββββ
20-- MAIN PANEL
21-- ββββββββββββββββββββββββββββββββββββββββββ
22local MainFrame = Instance.new("Frame")
23MainFrame.Name = "MainFrame"
24MainFrame.Size = UDim2.new(0, 280, 0, 130)
25MainFrame.Position = UDim2.new(1, -300, 0.5, -65)
26MainFrame.BackgroundColor3 = Color3.fromRGB(18, 18, 24)
27MainFrame.BorderSizePixel = 0
28MainFrame.ClipsDescendants = true
29MainFrame.Parent = ScreenGui
30
31local MainCorner = Instance.new("UICorner")
32MainCorner.CornerRadius = UDim.new(0, 16)
33MainCorner.Parent = MainFrame
34
35local MainStroke = Instance.new("UIStroke")
36MainStroke.Color = Color3.fromRGB(80, 80, 110)
37MainStroke.Thickness = 1.2
38MainStroke.Parent = MainFrame
39
40local MainGrad = Instance.new("UIGradient")
41MainGrad.Color = ColorSequence.new({
42 ColorSequenceKeypoint.new(0, Color3.fromRGB(28, 28, 38)),
43 ColorSequenceKeypoint.new(1, Color3.fromRGB(14, 14, 20)),
44})
45MainGrad.Rotation = 135
46MainGrad.Parent = MainFrame
47
48local TitleLabel = Instance.new("TextLabel")
49TitleLabel.Size = UDim2.new(1, 0, 0, 28)
50TitleLabel.Position = UDim2.new(0, 0, 0, 0)
51TitleLabel.BackgroundTransparency = 1
52TitleLabel.Text = "πΎ Cat Customizer"
53TitleLabel.TextColor3 = Color3.fromRGB(220, 210, 255)
54TitleLabel.TextSize = 13
55TitleLabel.Font = Enum.Font.GothamBold
56TitleLabel.TextXAlignment = Enum.TextXAlignment.Center
57TitleLabel.Parent = MainFrame
58
59local Divider = Instance.new("Frame")
60Divider.Size = UDim2.new(1, -24, 0, 1)
61Divider.Position = UDim2.new(0, 12, 0, 28)
62Divider.BackgroundColor3 = Color3.fromRGB(70, 70, 100)
63Divider.BorderSizePixel = 0
64Divider.Parent = MainFrame
65
66-- Preview
67local PreviewFrame = Instance.new("Frame")
68PreviewFrame.Size = UDim2.new(0, 56, 0, 56)
69PreviewFrame.Position = UDim2.new(0, 10, 0, 36)
70PreviewFrame.BackgroundColor3 = Color3.fromRGB(30, 30, 45)
71PreviewFrame.BorderSizePixel = 0
72PreviewFrame.Parent = MainFrame
73
74local PreviewCorner = Instance.new("UICorner")
75PreviewCorner.CornerRadius = UDim.new(0, 10)
76PreviewCorner.Parent = PreviewFrame
77
78local PreviewStroke = Instance.new("UIStroke")
79PreviewStroke.Color = Color3.fromRGB(100, 90, 160)
80PreviewStroke.Thickness = 1
81PreviewStroke.Parent = PreviewFrame
82
83local PreviewImage = Instance.new("ImageLabel")
84PreviewImage.Size = UDim2.new(1, -6, 1, -6)
85PreviewImage.Position = UDim2.new(0, 3, 0, 3)
86PreviewImage.BackgroundTransparency = 1
87PreviewImage.Image = "rbxthumb://type=Asset&id=0&w=150&h=150"
88PreviewImage.ScaleType = Enum.ScaleType.Fit
89PreviewImage.Parent = PreviewFrame
90
91-- Decal TextBox
92local DecalBox = Instance.new("TextBox")
93DecalBox.Size = UDim2.new(0, 170, 0, 34)
94DecalBox.Position = UDim2.new(0, 74, 0, 38)
95DecalBox.BackgroundColor3 = Color3.fromRGB(28, 28, 42)
96DecalBox.BorderSizePixel = 0
97DecalBox.PlaceholderText = "Enter Decal ID..."
98DecalBox.PlaceholderColor3 = Color3.fromRGB(100, 95, 130)
99DecalBox.Text = ""
100DecalBox.TextColor3 = Color3.fromRGB(230, 225, 255)
101DecalBox.TextSize = 12
102DecalBox.Font = Enum.Font.GothamMedium
103DecalBox.ClearTextOnFocus = false
104DecalBox.Parent = MainFrame
105
106local DecalBoxCorner = Instance.new("UICorner")
107DecalBoxCorner.CornerRadius = UDim.new(0, 8)
108DecalBoxCorner.Parent = DecalBox
109
110local DecalBoxStroke = Instance.new("UIStroke")
111DecalBoxStroke.Color = Color3.fromRGB(80, 75, 120)
112DecalBoxStroke.Thickness = 1
113DecalBoxStroke.Parent = DecalBox
114
115local DecalPadding = Instance.new("UIPadding")
116DecalPadding.PaddingLeft = UDim.new(0, 8)
117DecalPadding.Parent = DecalBox
118
119-- APPLY Button
120local ApplyBtn = Instance.new("TextButton")
121ApplyBtn.Size = UDim2.new(0, 170, 0, 28)
122ApplyBtn.Position = UDim2.new(0, 74, 0, 76)
123ApplyBtn.BackgroundColor3 = Color3.fromRGB(52, 199, 89)
124ApplyBtn.BorderSizePixel = 0
125ApplyBtn.Text = "APPLY"
126ApplyBtn.TextColor3 = Color3.fromRGB(255, 255, 255)
127ApplyBtn.TextSize = 12
128ApplyBtn.Font = Enum.Font.GothamBold
129ApplyBtn.AutoButtonColor = false
130ApplyBtn.Parent = MainFrame
131
132local ApplyCorner = Instance.new("UICorner")
133ApplyCorner.CornerRadius = UDim.new(0, 8)
134ApplyCorner.Parent = ApplyBtn
135
136-- Decal Store Button
137local StoreBtn = Instance.new("TextButton")
138StoreBtn.Size = UDim2.new(0, 170, 0, 22)
139StoreBtn.Position = UDim2.new(0, 74, 0, 108)
140StoreBtn.BackgroundColor3 = Color3.fromRGB(45, 45, 70)
141StoreBtn.BorderSizePixel = 0
142StoreBtn.Text = "πΌ Decal Store"
143StoreBtn.TextColor3 = Color3.fromRGB(180, 170, 230)
144StoreBtn.TextSize = 11
145StoreBtn.Font = Enum.Font.GothamMedium
146StoreBtn.AutoButtonColor = false
147StoreBtn.Parent = MainFrame
148
149local StoreBtnCorner = Instance.new("UICorner")
150StoreBtnCorner.CornerRadius = UDim.new(0, 7)
151StoreBtnCorner.Parent = StoreBtn
152
153local StoreBtnStroke = Instance.new("UIStroke")
154StoreBtnStroke.Color = Color3.fromRGB(90, 85, 140)
155StoreBtnStroke.Thickness = 1
156StoreBtnStroke.Parent = StoreBtn
157
158-- ββββββββββββββββββββββββββββββββββββββββββ
159-- DECAL STORE PANEL
160-- ββββββββββββββββββββββββββββββββββββββββββ
161local StoreFrame = Instance.new("Frame")
162StoreFrame.Size = UDim2.new(0, 280, 0, 0)
163StoreFrame.Position = UDim2.new(1, -300, 0.5, 70)
164StoreFrame.BackgroundColor3 = Color3.fromRGB(15, 15, 22)
165StoreFrame.BorderSizePixel = 0
166StoreFrame.ClipsDescendants = true
167StoreFrame.Visible = false
168StoreFrame.Parent = ScreenGui
169
170local StoreCorner = Instance.new("UICorner")
171StoreCorner.CornerRadius = UDim.new(0, 16)
172StoreCorner.Parent = StoreFrame
173
174local StoreStroke = Instance.new("UIStroke")
175StoreStroke.Color = Color3.fromRGB(80, 80, 110)
176StoreStroke.Thickness = 1.2
177StoreStroke.Parent = StoreFrame
178
179local StoreHeader = Instance.new("Frame")
180StoreHeader.Size = UDim2.new(1, 0, 0, 48)
181StoreHeader.BackgroundTransparency = 1
182StoreHeader.Parent = StoreFrame
183
184local StoreTitle = Instance.new("TextLabel")
185StoreTitle.Size = UDim2.new(1, -80, 1, 0)
186StoreTitle.Position = UDim2.new(0, 12, 0, 0)
187StoreTitle.BackgroundTransparency = 1
188StoreTitle.Text = "πΌ Decal Store"
189StoreTitle.TextColor3 = Color3.fromRGB(220, 210, 255)
190StoreTitle.TextSize = 13
191StoreTitle.Font = Enum.Font.GothamBold
192StoreTitle.TextXAlignment = Enum.TextXAlignment.Left
193StoreTitle.Parent = StoreHeader
194
195local PageLabel = Instance.new("TextLabel")
196PageLabel.Size = UDim2.new(0, 60, 0, 20)
197PageLabel.Position = UDim2.new(1, -70, 0.5, -10)
198PageLabel.BackgroundTransparency = 1
199PageLabel.Text = "Page 1"
200PageLabel.TextColor3 = Color3.fromRGB(130, 120, 180)
201PageLabel.TextSize = 11
202PageLabel.Font = Enum.Font.Gotham
203PageLabel.Parent = StoreHeader
204
205local CloseStoreBtn = Instance.new("TextButton")
206CloseStoreBtn.Size = UDim2.new(0, 22, 0, 22)
207CloseStoreBtn.Position = UDim2.new(1, -32, 0.5, -11)
208CloseStoreBtn.BackgroundColor3 = Color3.fromRGB(60, 40, 60)
209CloseStoreBtn.BorderSizePixel = 0
210CloseStoreBtn.Text = "β"
211CloseStoreBtn.TextColor3 = Color3.fromRGB(200, 180, 220)
212CloseStoreBtn.TextSize = 11
213CloseStoreBtn.Font = Enum.Font.GothamBold
214CloseStoreBtn.AutoButtonColor = false
215CloseStoreBtn.Parent = StoreHeader
216
217local CloseStoreBtnCorner = Instance.new("UICorner")
218CloseStoreBtnCorner.CornerRadius = UDim.new(0, 6)
219CloseStoreBtnCorner.Parent = CloseStoreBtn
220
221local StoreDivider = Instance.new("Frame")
222StoreDivider.Size = UDim2.new(1, -24, 0, 1)
223StoreDivider.Position = UDim2.new(0, 12, 0, 48)
224StoreDivider.BackgroundColor3 = Color3.fromRGB(55, 55, 85)
225StoreDivider.BorderSizePixel = 0
226StoreDivider.Parent = StoreFrame
227
228-- Search row
229local SearchRow = Instance.new("Frame")
230SearchRow.Size = UDim2.new(1, -20, 0, 30)
231SearchRow.Position = UDim2.new(0, 10, 0, 56)
232SearchRow.BackgroundTransparency = 1
233SearchRow.Parent = StoreFrame
234
235local SearchBox = Instance.new("TextBox")
236SearchBox.Size = UDim2.new(0, 120, 1, 0)
237SearchBox.BackgroundColor3 = Color3.fromRGB(28, 28, 42)
238SearchBox.BorderSizePixel = 0
239SearchBox.PlaceholderText = "Search decals..."
240SearchBox.PlaceholderColor3 = Color3.fromRGB(100, 95, 130)
241SearchBox.Text = ""
242SearchBox.TextColor3 = Color3.fromRGB(230, 225, 255)
243SearchBox.TextSize = 11
244SearchBox.Font = Enum.Font.GothamMedium
245SearchBox.ClearTextOnFocus = false
246SearchBox.Parent = SearchRow
247
248local SearchBoxCorner = Instance.new("UICorner")
249SearchBoxCorner.CornerRadius = UDim.new(0, 7)
250SearchBoxCorner.Parent = SearchBox
251
252local SearchBoxStroke = Instance.new("UIStroke")
253SearchBoxStroke.Color = Color3.fromRGB(70, 65, 110)
254SearchBoxStroke.Thickness = 1
255SearchBoxStroke.Parent = SearchBox
256
257local SearchPadding = Instance.new("UIPadding")
258SearchPadding.PaddingLeft = UDim.new(0, 7)
259SearchPadding.Parent = SearchBox
260
261local LimitLabel = Instance.new("TextLabel")
262LimitLabel.Size = UDim2.new(0, 28, 1, 0)
263LimitLabel.Position = UDim2.new(0, 128, 0, 0)
264LimitLabel.BackgroundTransparency = 1
265LimitLabel.Text = "Limit"
266LimitLabel.TextColor3 = Color3.fromRGB(120, 110, 160)
267LimitLabel.TextSize = 10
268LimitLabel.Font = Enum.Font.Gotham
269LimitLabel.Parent = SearchRow
270
271local LimitBox = Instance.new("TextBox")
272LimitBox.Size = UDim2.new(0, 34, 1, 0)
273LimitBox.Position = UDim2.new(0, 156, 0, 0)
274LimitBox.BackgroundColor3 = Color3.fromRGB(28, 28, 42)
275LimitBox.BorderSizePixel = 0
276LimitBox.Text = "50"
277LimitBox.TextColor3 = Color3.fromRGB(230, 225, 255)
278LimitBox.TextSize = 11
279LimitBox.Font = Enum.Font.GothamMedium
280LimitBox.ClearTextOnFocus = false
281LimitBox.Parent = SearchRow
282
283local LimitBoxCorner = Instance.new("UICorner")
284LimitBoxCorner.CornerRadius = UDim.new(0, 7)
285LimitBoxCorner.Parent = LimitBox
286
287local LimitBoxStroke = Instance.new("UIStroke")
288LimitBoxStroke.Color = Color3.fromRGB(70, 65, 110)
289LimitBoxStroke.Thickness = 1
290LimitBoxStroke.Parent = LimitBox
291
292local LimitPad = Instance.new("UIPadding")
293LimitPad.PaddingLeft = UDim.new(0, 5)
294LimitPad.Parent = LimitBox
295
296-- Verified checkbox
297local VerifiedRow = Instance.new("Frame")
298VerifiedRow.Size = UDim2.new(0, 80, 1, 0)
299VerifiedRow.Position = UDim2.new(0, 196, 0, 0)
300VerifiedRow.BackgroundTransparency = 1
301VerifiedRow.Parent = SearchRow
302
303local VerifiedCheck = Instance.new("TextButton")
304VerifiedCheck.Size = UDim2.new(0, 16, 0, 16)
305VerifiedCheck.Position = UDim2.new(0, 0, 0.5, -8)
306VerifiedCheck.BackgroundColor3 = Color3.fromRGB(28, 28, 42)
307VerifiedCheck.BorderSizePixel = 0
308VerifiedCheck.Text = ""
309VerifiedCheck.AutoButtonColor = false
310VerifiedCheck.Parent = VerifiedRow
311
312local VCCorner = Instance.new("UICorner")
313VCCorner.CornerRadius = UDim.new(0, 4)
314VCCorner.Parent = VerifiedCheck
315
316local VCStroke = Instance.new("UIStroke")
317VCStroke.Color = Color3.fromRGB(80, 75, 130)
318VCStroke.Thickness = 1
319VCStroke.Parent = VerifiedCheck
320
321local CheckMark = Instance.new("TextLabel")
322CheckMark.Size = UDim2.new(1, 0, 1, 0)
323CheckMark.BackgroundTransparency = 1
324CheckMark.Text = ""
325CheckMark.TextColor3 = Color3.fromRGB(80, 220, 120)
326CheckMark.TextSize = 11
327CheckMark.Font = Enum.Font.GothamBold
328CheckMark.Parent = VerifiedCheck
329
330local VerifiedLabel = Instance.new("TextLabel")
331VerifiedLabel.Size = UDim2.new(1, -20, 1, 0)
332VerifiedLabel.Position = UDim2.new(0, 20, 0, 0)
333VerifiedLabel.BackgroundTransparency = 1
334VerifiedLabel.Text = "Verified"
335VerifiedLabel.TextColor3 = Color3.fromRGB(140, 130, 185)
336VerifiedLabel.TextSize = 10
337VerifiedLabel.Font = Enum.Font.Gotham
338VerifiedLabel.TextXAlignment = Enum.TextXAlignment.Left
339VerifiedLabel.Parent = VerifiedRow
340
341-- Search button
342local SearchBtn = Instance.new("TextButton")
343SearchBtn.Size = UDim2.new(1, -20, 0, 26)
344SearchBtn.Position = UDim2.new(0, 10, 0, 94)
345SearchBtn.BackgroundColor3 = Color3.fromRGB(80, 70, 150)
346SearchBtn.BorderSizePixel = 0
347SearchBtn.Text = "π Search"
348SearchBtn.TextColor3 = Color3.fromRGB(230, 225, 255)
349SearchBtn.TextSize = 11
350SearchBtn.Font = Enum.Font.GothamBold
351SearchBtn.AutoButtonColor = false
352SearchBtn.Parent = StoreFrame
353
354local SearchBtnCorner = Instance.new("UICorner")
355SearchBtnCorner.CornerRadius = UDim.new(0, 8)
356SearchBtnCorner.Parent = SearchBtn
357
358-- Pagination
359local PaginationRow = Instance.new("Frame")
360PaginationRow.Size = UDim2.new(1, -20, 0, 26)
361PaginationRow.Position = UDim2.new(0, 10, 0, 126)
362PaginationRow.BackgroundTransparency = 1
363PaginationRow.Parent = StoreFrame
364
365local PrevBtn = Instance.new("TextButton")
366PrevBtn.Size = UDim2.new(0, 70, 1, 0)
367PrevBtn.BackgroundColor3 = Color3.fromRGB(40, 40, 62)
368PrevBtn.BorderSizePixel = 0
369PrevBtn.Text = "β Prev"
370PrevBtn.TextColor3 = Color3.fromRGB(180, 170, 230)
371PrevBtn.TextSize = 11
372PrevBtn.Font = Enum.Font.GothamMedium
373PrevBtn.AutoButtonColor = false
374PrevBtn.Parent = PaginationRow
375
376local PrevCorner = Instance.new("UICorner")
377PrevCorner.CornerRadius = UDim.new(0, 7)
378PrevCorner.Parent = PrevBtn
379
380local NextBtn = Instance.new("TextButton")
381NextBtn.Size = UDim2.new(0, 70, 1, 0)
382NextBtn.Position = UDim2.new(1, -70, 0, 0)
383NextBtn.BackgroundColor3 = Color3.fromRGB(40, 40, 62)
384NextBtn.BorderSizePixel = 0
385NextBtn.Text = "Next βΆ"
386NextBtn.TextColor3 = Color3.fromRGB(180, 170, 230)
387NextBtn.TextSize = 11
388NextBtn.Font = Enum.Font.GothamMedium
389NextBtn.AutoButtonColor = false
390NextBtn.Parent = PaginationRow
391
392local NextCorner = Instance.new("UICorner")
393NextCorner.CornerRadius = UDim.new(0, 7)
394NextCorner.Parent = NextBtn
395
396local TotalLabel = Instance.new("TextLabel")
397TotalLabel.Size = UDim2.new(1, -160, 1, 0)
398TotalLabel.Position = UDim2.new(0, 80, 0, 0)
399TotalLabel.BackgroundTransparency = 1
400TotalLabel.Text = ""
401TotalLabel.TextColor3 = Color3.fromRGB(120, 110, 160)
402TotalLabel.TextSize = 10
403TotalLabel.Font = Enum.Font.Gotham
404TotalLabel.Parent = PaginationRow
405
406-- Scroll frame
407local ScrollFrame = Instance.new("ScrollingFrame")
408ScrollFrame.Size = UDim2.new(1, -16, 0, 320)
409ScrollFrame.Position = UDim2.new(0, 8, 0, 158)
410ScrollFrame.BackgroundTransparency = 1
411ScrollFrame.BorderSizePixel = 0
412ScrollFrame.ScrollBarThickness = 4
413ScrollFrame.ScrollBarImageColor3 = Color3.fromRGB(90, 80, 140)
414ScrollFrame.CanvasSize = UDim2.new(0, 0, 0, 0)
415ScrollFrame.ClipsDescendants = true
416ScrollFrame.Parent = StoreFrame
417
418local GridLayout = Instance.new("UIGridLayout")
419GridLayout.CellSize = UDim2.new(0, 76, 0, 90)
420GridLayout.CellPadding = UDim2.new(0, 6, 0, 6)
421GridLayout.SortOrder = Enum.SortOrder.LayoutOrder
422GridLayout.Parent = ScrollFrame
423
424local GridPad = Instance.new("UIPadding")
425GridPad.PaddingTop = UDim.new(0, 4)
426GridPad.PaddingLeft = UDim.new(0, 4)
427GridPad.Parent = ScrollFrame
428
429local StatusLabel = Instance.new("TextLabel")
430StatusLabel.Size = UDim2.new(1, 0, 0, 30)
431StatusLabel.Position = UDim2.new(0, 0, 0, 158)
432StatusLabel.BackgroundTransparency = 1
433StatusLabel.Text = ""
434StatusLabel.TextColor3 = Color3.fromRGB(160, 150, 200)
435StatusLabel.TextSize = 11
436StatusLabel.Font = Enum.Font.Gotham
437StatusLabel.Visible = false
438StatusLabel.Parent = StoreFrame
439
440-- ββββββββββββββββββββββββββββββββββββββββββ
441-- DRAGGING
442-- ββββββββββββββββββββββββββββββββββββββββββ
443local function makeDraggable(frame)
444 local dragging, dragInput, dragStart, startPos = false, nil, nil, nil
445 frame.InputBegan:Connect(function(input)
446 if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
447 dragging = true
448 dragStart = input.Position
449 startPos = frame.Position
450 input.Changed:Connect(function()
451 if input.UserInputState == Enum.UserInputState.End then dragging = false end
452 end)
453 end
454 end)
455 frame.InputChanged:Connect(function(input)
456 if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
457 dragInput = input
458 end
459 end)
460 UserInputService.InputChanged:Connect(function(input)
461 if input == dragInput and dragging then
462 local delta = input.Position - dragStart
463 local newPos = UDim2.new(startPos.X.Scale, startPos.X.Offset + delta.X, startPos.Y.Scale, startPos.Y.Offset + delta.Y)
464 TweenService:Create(frame, TweenInfo.new(0.07, Enum.EasingStyle.Linear), {Position = newPos}):Play()
465 if frame == MainFrame and StoreFrame.Visible then
466 StoreFrame.Position = UDim2.new(startPos.X.Scale, startPos.X.Offset + delta.X, startPos.Y.Scale, startPos.Y.Offset + delta.Y + MainFrame.AbsoluteSize.Y + 6)
467 end
468 end
469 end)
470end
471
472makeDraggable(MainFrame)
473
474-- ββββββββββββββββββββββββββββββββββββββββββ
475-- APPLY BUTTON ANIMATION
476-- ββββββββββββββββββββββββββββββββββββββββββ
477local applyNormalColor = Color3.fromRGB(52, 199, 89)
478local applyPressColor = Color3.fromRGB(30, 130, 55)
479local applyNormalSize = UDim2.new(0, 170, 0, 28)
480local applyPressSize = UDim2.new(0, 162, 0, 25)
481local applyNormalPos = UDim2.new(0, 74, 0, 76)
482local applyPressPos = UDim2.new(0, 78, 0, 77.5)
483
484local function applyPress()
485 TweenService:Create(ApplyBtn, TweenInfo.new(0.1, Enum.EasingStyle.Quad), {BackgroundColor3 = applyPressColor, Size = applyPressSize, Position = applyPressPos}):Play()
486end
487local function applyRelease()
488 TweenService:Create(ApplyBtn, TweenInfo.new(0.15, Enum.EasingStyle.Back, Enum.EasingDirection.Out), {BackgroundColor3 = applyNormalColor, Size = applyNormalSize, Position = applyNormalPos}):Play()
489end
490
491ApplyBtn.MouseButton1Down:Connect(applyPress)
492ApplyBtn.MouseButton1Up:Connect(applyRelease)
493ApplyBtn.InputBegan:Connect(function(i) if i.UserInputType == Enum.UserInputType.Touch then applyPress() end end)
494ApplyBtn.InputEnded:Connect(function(i) if i.UserInputType == Enum.UserInputType.Touch then applyRelease() end end)
495
496-- ββββββββββββββββββββββββββββββββββββββββββ
497-- PREVIEW UPDATE
498-- ββββββββββββββββββββββββββββββββββββββββββ
499local previewDebounce = nil
500local function updatePreview(id)
501 local cleaned = tostring(id):match("^%s*(.-)%s*$")
502 if cleaned ~= "" and tonumber(cleaned) then
503 PreviewImage.Image = "rbxthumb://type=Asset&id=" .. cleaned .. "&w=150&h=150"
504 else
505 PreviewImage.Image = "rbxthumb://type=Asset&id=0&w=150&h=150"
506 end
507end
508
509DecalBox:GetPropertyChangedSignal("Text"):Connect(function()
510 if previewDebounce then task.cancel(previewDebounce) end
511 previewDebounce = task.delay(0.3, function()
512 updatePreview(DecalBox.Text)
513 previewDebounce = nil
514 end)
515end)
516
517-- ββββββββββββββββββββββββββββββββββββββββββ
518-- GET CAT COLOR REALTIME ("RGB Format")
519-- ββββββββββββββββββββββββββββββββββββββββββ
520local function getCatColor()
521 -- CatColor.Value is a string like "255, 255, 255"
522 local raw = LocalPlayer.Data.CatColor.Value
523 local r, g, b = tostring(raw):match("^%s*(%d+)%s*,%s*(%d+)%s*,%s*(%d+)%s*$")
524 if r and g and b then
525 return Color3.fromRGB(tonumber(r), tonumber(g), tonumber(b))
526 end
527 -- Fallback: if it's already a Color3 stored as a Color3Value
528 if typeof(raw) == "Color3" then
529 return raw
530 end
531 return Color3.fromRGB(255, 255, 255)
532end
533
534-- ββββββββββββββββββββββββββββββββββββββββββ
535-- APPLY FIRE
536-- ββββββββββββββββββββββββββββββββββββββββββ
537ApplyBtn.MouseButton1Click:Connect(function()
538 local decalId = DecalBox.Text:match("^%s*(.-)%s*$")
539 if decalId == "" or not tonumber(decalId) then return end
540
541 local catColor = getCatColor()
542 local hatName = LocalPlayer.Data.HatName.Value
543 local textureUrl = "rbxthumb://type=Asset&id=" .. decalId .. "&w=150&h=150"
544
545 ReplicatedStorage:WaitForChild("Remotes"):WaitForChild("CatCustomizerRemote"):FireServer(catColor, hatName, textureUrl)
546end)
547
548-- ββββββββββββββββββββββββββββββββββββββββββ
549-- DECAL STORE
550-- ββββββββββββββββββββββββββββββββββββββββββ
551local storeOpen = false
552local verifiedOnly = false
553local currentPage = 0
554local currentKeyword = ""
555local currentLimit = 50
556local STORE_HEIGHT = 490
557local API_BASE = "https://open-source-ten-eta.vercel.app/api/decal.js"
558
559local function syncStorePos()
560 StoreFrame.Position = UDim2.new(
561 MainFrame.Position.X.Scale, MainFrame.Position.X.Offset,
562 MainFrame.Position.Y.Scale, MainFrame.Position.Y.Offset + MainFrame.AbsoluteSize.Y + 6
563 )
564end
565
566local function tweenStoreOpen(open)
567 if open then
568 syncStorePos()
569 StoreFrame.Visible = true
570 TweenService:Create(StoreFrame, TweenInfo.new(0.28, Enum.EasingStyle.Quint, Enum.EasingDirection.Out), {Size = UDim2.new(0, 280, 0, STORE_HEIGHT)}):Play()
571 else
572 TweenService:Create(StoreFrame, TweenInfo.new(0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.In), {Size = UDim2.new(0, 280, 0, 0)}):Play()
573 task.delay(0.21, function() StoreFrame.Visible = false end)
574 end
575end
576
577VerifiedCheck.MouseButton1Click:Connect(function()
578 verifiedOnly = not verifiedOnly
579 CheckMark.Text = verifiedOnly and "β" or ""
580 VCStroke.Color = verifiedOnly and Color3.fromRGB(80, 220, 120) or Color3.fromRGB(80, 75, 130)
581end)
582
583local function clearGrid()
584 for _, c in ipairs(ScrollFrame:GetChildren()) do
585 if c:IsA("Frame") or c:IsA("TextButton") then c:Destroy() end
586 end
587end
588
589local function createCard(decalId, order)
590 local card = Instance.new("TextButton")
591 card.Size = UDim2.new(0, 76, 0, 90)
592 card.BackgroundColor3 = Color3.fromRGB(28, 26, 42)
593 card.BorderSizePixel = 0
594 card.Text = ""
595 card.AutoButtonColor = false
596 card.LayoutOrder = order
597 card.Parent = ScrollFrame
598
599 local cc = Instance.new("UICorner"); cc.CornerRadius = UDim.new(0, 8); cc.Parent = card
600 local cs = Instance.new("UIStroke"); cs.Color = Color3.fromRGB(60, 55, 95); cs.Thickness = 1; cs.Parent = card
601
602 local img = Instance.new("ImageLabel")
603 img.Size = UDim2.new(1, -8, 0, 58); img.Position = UDim2.new(0, 4, 0, 4)
604 img.BackgroundColor3 = Color3.fromRGB(20, 18, 32)
605 img.Image = "rbxthumb://type=Asset&id=" .. decalId .. "&w=150&h=150"
606 img.ScaleType = Enum.ScaleType.Fit; img.BorderSizePixel = 0; img.Parent = card
607 local ic = Instance.new("UICorner"); ic.CornerRadius = UDim.new(0, 6); ic.Parent = img
608
609 local lbl = Instance.new("TextLabel")
610 lbl.Size = UDim2.new(1, -4, 0, 26); lbl.Position = UDim2.new(0, 2, 0, 63)
611 lbl.BackgroundTransparency = 1; lbl.Text = decalId
612 lbl.TextColor3 = Color3.fromRGB(180, 170, 220); lbl.TextSize = 9
613 lbl.Font = Enum.Font.Gotham; lbl.TextWrapped = true; lbl.Parent = card
614
615 card.MouseEnter:Connect(function()
616 TweenService:Create(card, TweenInfo.new(0.1), {BackgroundColor3 = Color3.fromRGB(50, 45, 75)}):Play()
617 TweenService:Create(cs, TweenInfo.new(0.1), {Color = Color3.fromRGB(120, 100, 200)}):Play()
618 end)
619 card.MouseLeave:Connect(function()
620 TweenService:Create(card, TweenInfo.new(0.1), {BackgroundColor3 = Color3.fromRGB(28, 26, 42)}):Play()
621 TweenService:Create(cs, TweenInfo.new(0.1), {Color = Color3.fromRGB(60, 55, 95)}):Play()
622 end)
623 card.MouseButton1Click:Connect(function()
624 DecalBox.Text = decalId
625 updatePreview(decalId)
626 end)
627end
628
629local function fetchDecals(keyword, limit, pageNum, verified)
630 StatusLabel.Text = "β³ Loading..."
631 StatusLabel.Visible = true
632 ScrollFrame.Visible = false
633 clearGrid()
634
635 local url = API_BASE
636 .. "?limit=" .. tostring(limit)
637 .. "&pageNumber=" .. tostring(pageNum)
638 .. "&keyword=" .. HttpService:UrlEncode(keyword)
639 .. "&includeOnlyVerifiedCreators=" .. tostring(verified)
640
641 local ok, res = pcall(function()
642 return HttpService:RequestAsync({ Url = url, Method = "GET" })
643 end)
644
645 if not ok or not res or not res.Success then
646 StatusLabel.Text = "β Fetch failed. Enable HTTP in executor."
647 return
648 end
649
650 local ps, data = pcall(HttpService.JSONDecode, HttpService, res.Body)
651 if not ps or not data then
652 StatusLabel.Text = "β Parse error."
653 return
654 end
655
656 local items = data.data
657 if not items or #items == 0 then
658 StatusLabel.Text = "No results found."
659 return
660 end
661
662 StatusLabel.Visible = false
663 ScrollFrame.Visible = true
664 TotalLabel.Text = data.totalResults and (data.totalResults .. " total") or ""
665 PageLabel.Text = "Page " .. (pageNum + 1)
666
667 for i, item in ipairs(items) do
668 createCard(tostring(item.id), i)
669 end
670
671 task.wait()
672 local rows = math.ceil(#items / 3)
673 ScrollFrame.CanvasSize = UDim2.new(0, 0, 0, rows * 96 + 10)
674 ScrollFrame.CanvasPosition = Vector2.new(0, 0)
675end
676
677local function doSearch()
678 currentKeyword = SearchBox.Text:match("^%s*(.-)%s*$")
679 currentLimit = math.clamp(tonumber(LimitBox.Text) or 50, 1, 100)
680 currentPage = 0
681 fetchDecals(currentKeyword, currentLimit, currentPage, verifiedOnly)
682end
683
684SearchBtn.MouseButton1Click:Connect(doSearch)
685SearchBox.FocusLost:Connect(function(enter) if enter then doSearch() end end)
686
687PrevBtn.MouseButton1Click:Connect(function()
688 if currentPage > 0 then
689 currentPage -= 1
690 fetchDecals(currentKeyword, currentLimit, currentPage, verifiedOnly)
691 end
692end)
693
694NextBtn.MouseButton1Click:Connect(function()
695 currentPage += 1
696 fetchDecals(currentKeyword, currentLimit, currentPage, verifiedOnly)
697end)
698
699StoreBtn.MouseButton1Click:Connect(function()
700 storeOpen = not storeOpen
701 tweenStoreOpen(storeOpen)
702 if storeOpen and StatusLabel.Text == "" then
703 fetchDecals("", 50, 0, false)
704 end
705end)
706
707CloseStoreBtn.MouseButton1Click:Connect(function()
708 storeOpen = false
709 tweenStoreOpen(false)
710end)
711
712-- Hover effects
713StoreBtn.MouseEnter:Connect(function() TweenService:Create(StoreBtn, TweenInfo.new(0.12), {BackgroundColor3 = Color3.fromRGB(60, 60, 100)}):Play() end)
714StoreBtn.MouseLeave:Connect(function() TweenService:Create(StoreBtn, TweenInfo.new(0.12), {BackgroundColor3 = Color3.fromRGB(45, 45, 70)}):Play() end)
715SearchBtn.MouseEnter:Connect(function() TweenService:Create(SearchBtn, TweenInfo.new(0.12), {BackgroundColor3 = Color3.fromRGB(100, 90, 180)}):Play() end)
716SearchBtn.MouseLeave:Connect(function() TweenService:Create(SearchBtn, TweenInfo.new(0.12), {BackgroundColor3 = Color3.fromRGB(80, 70, 150)}):Play() end)