
KeylessUniversal

-- 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)No comments yet for this script.



