-- Services local Players = game:GetService("Players") local ContentProvider = game:GetService("ContentProvider") local UserInputService = game:GetService("UserInputService") local player = Players.LocalPlayer local playerGui = player:WaitForChild("PlayerGui") ------------------------------------------------------------------------ -- 1. BUILD THE MOBILE-FRIENDLY UI ------------------------------------------------------------------------ local screenGui = Instance.new("ScreenGui") screenGui.Name = "MobileImageWorkshop" screenGui.ResetOnSpawn = false -- Toggle Button (Larger tap target for mobile thumbs) local toggleButton = Instance.new("TextButton") toggleButton.Name = "ToggleButton" toggleButton.Size = UDim2.new(0, 130, 0, 50) toggleButton.Position = UDim2.new(0, 15, 0, 15) toggleButton.BackgroundColor3 = Color3.fromRGB(0, 120, 215) toggleButton.Text = "🔧 Workshop" toggleButton.TextColor3 = Color3.fromRGB(255, 255, 255) toggleButton.TextSize = 16 toggleButton.Font = Enum.Font.SourceSansBold toggleButton.Parent = screenGui local toggleCorner = Instance.new("UICorner") toggleCorner.CornerRadius = UDim.new(0, 8) toggleCorner.Parent = toggleButton -- Main Window Frame (Sized cleanly for smaller screens) local frame = Instance.new("Frame") frame.Name = "MainFrame" frame.Size = UDim2.new(0, 320, 0, 420) frame.Position = UDim2.new(0.5, -160, 0.5, -210) frame.BackgroundColor3 = Color3.fromRGB(30, 30, 30) frame.BorderSizePixel = 0 frame.Active = true frame.Visible = true frame.Parent = screenGui local uiCorner = Instance.new("UICorner") uiCorner.CornerRadius = UDim.new(0, 10) uiCorner.Parent = frame -- Large Touch Target for Close Button local closeXButton = Instance.new("TextButton") closeXButton.Name = "CloseX" closeXButton.Size = UDim2.new(0, 44, 0, 44) -- Standard minimum mobile tap index closeXButton.Position = UDim2.new(1, -46, 0, 2) closeXButton.BackgroundTransparency = 1 closeXButton.Text = "✕" closeXButton.TextColor3 = Color3.fromRGB(180, 180, 180) closeXButton.TextSize = 20 closeXButton.Font = Enum.Font.SourceSansBold closeXButton.Parent = frame local titleLabel = Instance.new("TextLabel") titleLabel.Size = UDim2.new(1, -50, 0, 44) titleLabel.BackgroundTransparency = 1 titleLabel.Text = " IMAGE WORKSHOP" titleLabel.TextColor3 = Color3.fromRGB(255, 255, 255) titleLabel.TextSize = 14 titleLabel.Font = Enum.Font.SourceSansBold titleLabel.TextXAlignment = Enum.TextXAlignment.Left titleLabel.Parent = frame -- Larger Input Box to make tapping into it effortless local inputBox = Instance.new("TextBox") inputBox.Size = UDim2.new(0.92, 0, 0, 42) inputBox.Position = UDim2.new(0.04, 0, 0, 50) inputBox.BackgroundColor3 = Color3.fromRGB(45, 45, 45) inputBox.PlaceholderText = "Tap here to paste ID or Link" inputBox.Text = "" inputBox.TextColor3 = Color3.fromRGB(255, 255, 255) inputBox.TextSize = 14 inputBox.Font = Enum.Font.SourceSans inputBox.ClearTextOnFocus = false inputBox.Parent = frame local inputCorner = Instance.new("UICorner") inputCorner.CornerRadius = UDim.new(0, 6) inputCorner.Parent = inputBox local displayImage = Instance.new("ImageLabel") displayImage.Size = UDim2.new(0, 180, 0, 180) displayImage.Position = UDim2.new(0.5, -90, 0, 105) displayImage.BackgroundColor3 = Color3.fromRGB(15, 15, 15) displayImage.Image = "" displayImage.ScaleType = Enum.ScaleType.Fit displayImage.Parent = frame local idLabel = Instance.new("TextLabel") idLabel.Size = UDim2.new(1, 0, 0, 30) idLabel.Position = UDim2.new(0, 0, 0, 295) idLabel.BackgroundTransparency = 1 idLabel.Text = "No Image Loaded" idLabel.TextColor3 = Color3.fromRGB(180, 180, 180) idLabel.TextSize = 14 idLabel.Font = Enum.Font.SourceSansItalic idLabel.Parent = frame -- Tall button for reliable finger presses local insertButton = Instance.new("TextButton") insertButton.Size = UDim2.new(0.92, 0, 0, 50) insertButton.Position = UDim2.new(0.04, 0, 0, 340) insertButton.BackgroundColor3 = Color3.fromRGB(0, 140, 60) insertButton.Text = "INSERT LOCAL CANVAS" insertButton.TextColor3 = Color3.fromRGB(255, 255, 255) insertButton.TextSize = 16 insertButton.Font = Enum.Font.SourceSansBold insertButton.Parent = frame local buttonCorner = Instance.new("UICorner") buttonCorner.CornerRadius = UDim.new(0, 8) buttonCorner.Parent = insertButton screenGui.Parent = playerGui ------------------------------------------------------------------------ -- 2. UNIVERSAL MOBILE DRAGGING SYSTEM ------------------------------------------------------------------------ local dragging, dragInput, dragStart, startPos local function updateDrag(input) local delta = input.Position - dragStart frame.Position = UDim2.new(startPos.X.Scale, startPos.X.Offset + delta.X, startPos.Y.Scale, startPos.Y.Offset + delta.Y) end frame.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then dragging = true dragStart = input.Position startPos = frame.Position input.Changed:Connect(function() if input.UserInputState == Enum.UserInputState.End then dragging = false end end) end end) frame.InputChanged:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then dragInput = input end end) UserInputService.InputChanged:Connect(function(input) if input == dragInput and dragging then updateDrag(input) end end) ------------------------------------------------------------------------ -- 3. CORE LOGIC ------------------------------------------------------------------------ local function extractAssetId(text) return string.match(text, "%d+") end local function updateImageViewer() local assetId = extractAssetId(inputBox.Text) if assetId and assetId ~= "" then local assetUrl = "rbxassetid://" .. assetId displayImage.Image = assetUrl idLabel.Text = "Current Asset ID: " .. assetId task.spawn(function() pcall(function() ContentProvider:PreloadAsync({displayImage}) end) end) else idLabel.Text = "Invalid Input." displayImage.Image = "" end end local function localInsertImage() local assetId = extractAssetId(inputBox.Text) if not assetId or assetId == "" then return end local part = Instance.new("Part") part.Name = "LocalViewer_" .. assetId part.Size = Vector3.new(5, 5, 0.1) part.Anchored = true part.Material = Enum.Material.SmoothPlastic local character = player.Character if character and character:FindFirstChild("HumanoidRootPart") then part.Position = character.HumanoidRootPart.Position + (character.HumanoidRootPart.CFrame.LookVector * 5) else part.Position = Vector3.new(0, 10, 0) end local decal = Instance.new("Decal") decal.Texture = "rbxassetid://" .. assetId decal.Face = Enum.NormalId.Front decal.Parent = part part.Parent = workspace end local function toggleWindow() frame.Visible = not frame.Visible end -- FocusLost handles 'Return/Done' buttons on virtual keyboards inputBox.FocusLost:Connect(updateImageViewer) insertButton.MouseButton1Click:Connect(localInsertImage) toggleButton.MouseButton1Click:Connect(toggleWindow) closeXButton.MouseButton1Click:Connect(toggleWindow)