Advertisement
kele666CN

notif 222

Apr 14th, 2025 (edited)
20
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.67 KB | None | 0 0
  1. -- 字体初始化
  2. if isfile("SmallestPixel7.font") then
  3. delfile("SmallestPixel7.font")
  4. end
  5.  
  6. writefile("fs-tahoma-8px.ttf", game:HttpGet("https://github.com/i77lhm/storage/raw/refs/heads/main/fonts/fs-tahoma-8px.ttf"))
  7.  
  8. -- 字体系统
  9. local Font = {
  10. new = function(path) return path end,
  11. Register = function() end,
  12. GetRegistry = function() end
  13. }
  14. Font = setreadonly(Font, false)
  15.  
  16. local fontAsset
  17. do
  18. getsynasset = getcustomasset or getsynasset
  19.  
  20. function Font:Register(Name, Weight, Style, Asset)
  21. if not isfile(Name .. ".font") then
  22. if not isfile(Asset.Id) then
  23. writefile(Asset.Id, Asset.Font)
  24. end
  25.  
  26. local Data = {
  27. name = Name,
  28. faces = {{
  29. name = "Regular",
  30. weight = Weight,
  31. style = Style,
  32. assetId = getsynasset(Asset.Id)
  33. }}
  34. }
  35.  
  36. writefile(Name .. ".font", game:GetService("HttpService"):JSONEncode(Data))
  37. return getsynasset(Name .. ".font")
  38. else
  39. warn("Font already registered")
  40. end
  41. end
  42.  
  43. function Font:GetRegistry(Name)
  44. if isfile(Name .. ".font") then
  45. return getsynasset(Name .. ".font")
  46. end
  47. end
  48.  
  49. Font:Register("SmallestPixel7", 400, "normal", {Id = "fs-tahoma-8px.ttf", Font = ""})
  50. fontAsset = Font:GetRegistry("SmallestPixel7")
  51. end
  52.  
  53. -- 配置
  54. local config = {
  55. minWidth = 120,
  56. maxWidth = 400,
  57. padding = 12,
  58. duration = 3,
  59. spacing = 10,
  60. accentColor = Color3.fromRGB(255, 174, 174),
  61. backgroundColor = Color3.fromRGB(30, 30, 40),
  62. textColor = Color3.fromRGB(255, 255, 255),
  63. titleColor = Color3.fromRGB(255, 255, 255),
  64. contentColor = Color3.fromRGB(200, 200, 200),
  65. fontSize = 12,
  66. titleSize = 14,
  67. contentSize = 12,
  68. lineSpacing = 5 -- 行间距
  69. }
  70.  
  71. -- 通知系统
  72. local Notifications = {ActiveNotifs = {}}
  73. local TweenService = game:GetService("TweenService")
  74. local RunService = game:GetService("RunService")
  75. local Players = game:GetService("Players")
  76. local CoreGui = game:GetService("CoreGui")
  77. local TextService = game:GetService("TextService")
  78.  
  79. -- 创建UI父级
  80. local ScreenGui = Instance.new("ScreenGui")
  81. ScreenGui.Name = "NotificationSystem"
  82. ScreenGui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling
  83. ScreenGui.Parent = RunService:IsStudio() and Players.LocalPlayer:WaitForChild("PlayerGui") or CoreGui
  84.  
  85. -- 设置字体
  86. local function SetFont(label, size)
  87. if fontAsset then
  88. label.FontFace = Font.new(fontAsset)
  89. else
  90. label.Font = Enum.Font.Arcade
  91. end
  92. label.TextSize = size or config.fontSize
  93. end
  94.  
  95. -- 计算文本宽度
  96. local function GetTextWidth(text, size)
  97. local success, result = pcall(function()
  98. local textParams = Instance.new("GetTextBoundsParams")
  99. textParams.Text = text
  100. textParams.Font = fontAsset and Font.new(fontAsset) or Enum.Font.Arcade
  101. textParams.Size = size or config.fontSize
  102. textParams.Width = math.huge
  103.  
  104. local bounds = TextService:GetTextBoundsAsync(textParams)
  105. return bounds.X
  106. end)
  107. return success and result or 150 -- 默认宽度
  108. end
  109.  
  110. -- 更新通知位置
  111. function Notifications:UpdatePositions()
  112. local startY = 20
  113. for i, notif in ipairs(self.ActiveNotifs) do
  114. local notificationHeight = notif.Container.AbsoluteSize.Y
  115. local yPos = startY + ((notificationHeight + config.spacing) * (i-1))
  116. local xPos = notif.Config.side == "right" and
  117. (workspace.CurrentCamera.ViewportSize.X - notif.Container.AbsoluteSize.X - 20) or
  118. 20
  119.  
  120. TweenService:Create(
  121. notif.Container,
  122. TweenInfo.new(0.3, Enum.EasingStyle.Quad, Enum.EasingDirection.Out),
  123. {Position = UDim2.new(0, xPos, 0, yPos)}
  124. ):Play()
  125. end
  126. end
  127.  
  128. -- 创建通知
  129. function Notifications:New(customConfig)
  130. local currentConfig = table.clone(config)
  131. for k,v in pairs(customConfig or {}) do
  132. currentConfig[k] = v
  133. end
  134.  
  135. -- 计算宽度
  136. local textWidth
  137. if currentConfig.isTwoLine then
  138. local titleWidth = GetTextWidth(currentConfig.title, currentConfig.titleSize)
  139. local contentWidth = GetTextWidth(currentConfig.content, currentConfig.contentSize)
  140. textWidth = math.max(titleWidth, contentWidth)
  141. else
  142. textWidth = GetTextWidth(currentConfig.text)
  143. end
  144.  
  145. local calculatedWidth = math.clamp(textWidth + currentConfig.padding * 2, currentConfig.minWidth, currentConfig.maxWidth)
  146. local containerHeight = currentConfig.isTwoLine and (currentConfig.titleSize + currentConfig.contentSize + config.lineSpacing * 3) or 30
  147.  
  148. -- 创建容器
  149. local container = Instance.new("Frame")
  150. container.Name = "Notification"
  151. container.BackgroundTransparency = 1
  152. container.Size = UDim2.new(0, calculatedWidth, 0, containerHeight)
  153. container.Position = UDim2.new(currentConfig.side == "right" and 1 or -1, currentConfig.side == "right" and -20 or 20, 0, 20)
  154. container.AnchorPoint = currentConfig.side == "right" and Vector2.new(1, 0) or Vector2.new(0, 0)
  155. container.Parent = ScreenGui
  156.  
  157. -- 背景
  158. local background = Instance.new("Frame")
  159. background.Name = "Background"
  160. background.Size = UDim2.new(1, 0, 1, 0)
  161. background.BackgroundColor3 = currentConfig.backgroundColor
  162. background.BackgroundTransparency = 1
  163. background.BorderSizePixel = 0
  164. background.Parent = container
  165.  
  166. -- 装饰条
  167. local accent = Instance.new("Frame")
  168. accent.Name = "Accent"
  169. accent.Size = UDim2.new(0, 3, 1, 0)
  170. accent.Position = UDim2.new(currentConfig.side == "right" and 1 or 0, currentConfig.side == "right" and -3 or 0, 0, 0)
  171. accent.AnchorPoint = currentConfig.side == "right" and Vector2.new(1, 0) or Vector2.new(0, 0)
  172. accent.BackgroundColor3 = currentConfig.color or currentConfig.accentColor
  173. accent.BackgroundTransparency = 1
  174. accent.BorderSizePixel = 0
  175. accent.Parent = background
  176.  
  177. -- 文本容器
  178. local textContainer = Instance.new("Frame")
  179. textContainer.Name = "TextContainer"
  180. textContainer.BackgroundTransparency = 1
  181. textContainer.Size = UDim2.new(1, -currentConfig.padding, 1, 0)
  182. textContainer.Position = UDim2.new(0, currentConfig.side == "right" and 0 or currentConfig.padding/2, 0, 0)
  183. textContainer.Parent = background
  184.  
  185. -- 通知对象
  186. local notification = {
  187. Container = container,
  188. Config = currentConfig,
  189. flashThread = nil,
  190. Destroy = function(self)
  191. if self.flashThread then
  192. coroutine.close(self.flashThread)
  193. end
  194.  
  195. local tweenOut = TweenInfo.new(0.5, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)
  196. local slideOutPos = UDim2.new(currentConfig.side == "right" and 1 or -1, currentConfig.side == "right" and -20 or 20, 0, container.Position.Y.Offset)
  197.  
  198. TweenService:Create(background, tweenOut, {BackgroundTransparency = 1}):Play()
  199. TweenService:Create(accent, tweenOut, {BackgroundTransparency = 1}):Play()
  200. TweenService:Create(container, tweenOut, {Position = slideOutPos}):Play()
  201.  
  202. if currentConfig.isTwoLine then
  203. TweenService:Create(self.titleLabel, tweenOut, {TextTransparency = 1}):Play()
  204. TweenService:Create(self.contentLabel, tweenOut, {TextTransparency = 1}):Play()
  205. else
  206. TweenService:Create(self.textLabel, tweenOut, {TextTransparency = 1}):Play()
  207. end
  208.  
  209. for i, notif in ipairs(Notifications.ActiveNotifs) do
  210. if notif == self then
  211. table.remove(Notifications.ActiveNotifs, i)
  212. break
  213. end
  214. end
  215.  
  216. Notifications:UpdatePositions()
  217.  
  218. task.wait(0.5)
  219. container:Destroy()
  220. end,
  221. UpdateText = function(self, newText, newContent)
  222. if currentConfig.isTwoLine then
  223. self.titleLabel.Text = newText or self.titleLabel.Text
  224. self.contentLabel.Text = newContent or self.contentLabel.Text
  225. local titleWidth = GetTextWidth(self.titleLabel.Text, currentConfig.titleSize)
  226. local contentWidth = GetTextWidth(self.contentLabel.Text, currentConfig.contentSize)
  227. local newWidth = math.clamp(math.max(titleWidth, contentWidth) + currentConfig.padding * 2,
  228. currentConfig.minWidth, currentConfig.maxWidth)
  229. TweenService:Create(container, TweenInfo.new(0.3), {Size = UDim2.new(0, newWidth, 0, containerHeight)}):Play()
  230. else
  231. self.textLabel.Text = newText
  232. local newWidth = math.clamp(GetTextWidth(newText) + currentConfig.padding * 2,
  233. currentConfig.minWidth, currentConfig.maxWidth)
  234. TweenService:Create(container, TweenInfo.new(0.3), {Size = UDim2.new(0, newWidth, 0, containerHeight)}):Play()
  235. end
  236. Notifications:UpdatePositions()
  237. end
  238. }
  239.  
  240. if currentConfig.isTwoLine then
  241. -- 双行模式
  242. local titleLabel = Instance.new("TextLabel")
  243. titleLabel.Name = "Title"
  244. titleLabel.Text = currentConfig.title
  245. SetFont(titleLabel, currentConfig.titleSize)
  246. titleLabel.TextColor3 = currentConfig.titleColor
  247. titleLabel.TextTransparency = 1
  248. titleLabel.TextXAlignment = currentConfig.side == "right" and Enum.TextXAlignment.Right or Enum.TextXAlignment.Left
  249. titleLabel.BackgroundTransparency = 1
  250. titleLabel.Size = UDim2.new(1, 0, 0, currentConfig.titleSize)
  251. titleLabel.Position = UDim2.new(0, 0, 0, 0)
  252. titleLabel.Parent = textContainer
  253.  
  254. local contentLabel = Instance.new("TextLabel")
  255. contentLabel.Name = "Content"
  256. contentLabel.Text = currentConfig.content
  257. SetFont(contentLabel, currentConfig.contentSize)
  258. contentLabel.TextColor3 = currentConfig.contentColor
  259. contentLabel.TextTransparency = 1
  260. contentLabel.TextXAlignment = currentConfig.side == "right" and Enum.TextXAlignment.Right or Enum.TextXAlignment.Left
  261. contentLabel.BackgroundTransparency = 1
  262. contentLabel.Size = UDim2.new(1, 0, 0, currentConfig.contentSize)
  263. contentLabel.Position = UDim2.new(0, 0, 0, currentConfig.titleSize + config.lineSpacing)
  264. contentLabel.Parent = textContainer
  265.  
  266. notification.titleLabel = titleLabel
  267. notification.contentLabel = contentLabel
  268. else
  269. -- 单行模式
  270. local textLabel = Instance.new("TextLabel")
  271. textLabel.Name = "Text"
  272. textLabel.Text = currentConfig.text
  273. SetFont(textLabel)
  274. textLabel.TextColor3 = currentConfig.textColor
  275. textLabel.TextTransparency = 1
  276. textLabel.TextXAlignment = currentConfig.side == "right" and Enum.TextXAlignment.Right or Enum.TextXAlignment.Left
  277. textLabel.BackgroundTransparency = 1
  278. textLabel.Size = UDim2.new(1, 0, 1, 0)
  279. textLabel.Position = UDim2.new(0, 0, 0, 0)
  280. textLabel.Parent = textContainer
  281.  
  282. notification.textLabel = textLabel
  283. end
  284.  
  285. table.insert(self.ActiveNotifs, notification)
  286.  
  287. -- 滑入动画
  288. local tweenIn = TweenInfo.new(0.5, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)
  289. local targetX = currentConfig.side == "right" and (workspace.CurrentCamera.ViewportSize.X - calculatedWidth - 20) or 20
  290.  
  291. TweenService:Create(background, tweenIn, {BackgroundTransparency = 0}):Play()
  292. TweenService:Create(accent, tweenIn, {BackgroundTransparency = 0}):Play()
  293. TweenService:Create(container, tweenIn, {Position = UDim2.new(0, targetX, 0, 20)}):Play()
  294.  
  295. if currentConfig.isTwoLine then
  296. TweenService:Create(titleLabel, tweenIn, {TextTransparency = 0}):Play()
  297. TweenService:Create(contentLabel, tweenIn, {TextTransparency = 0}):Play()
  298. else
  299. TweenService:Create(textLabel, tweenIn, {TextTransparency = 0}):Play()
  300. end
  301.  
  302. self:UpdatePositions()
  303.  
  304. -- 闪烁效果
  305. if currentConfig.flash then
  306. notification.flashThread = task.spawn(function()
  307. local time = 0
  308. while task.wait(0.05) do
  309. if not container.Parent then break end
  310. time = time + 0.05
  311. local pulse = (math.sin(time * 5) + 1) / 2
  312. accent.BackgroundColor3 = (currentConfig.color or currentConfig.accentColor):Lerp(Color3.new(1, 1, 1), pulse)
  313. end
  314. end)
  315. end
  316.  
  317. -- 自动销毁
  318. task.delay(currentConfig.duration, function()
  319. if container.Parent then
  320. notification:Destroy()
  321. end
  322. end)
  323.  
  324. return notification
  325. end
  326.  
  327. -- 通知接口
  328. function Notifications:Notify(arg1, arg2, arg3, arg4, arg5)
  329. local isTwoLine = type(arg2) == "string" and type(arg3) ~= "boolean"
  330.  
  331. if isTwoLine then
  332. return self:New({
  333. title = arg1,
  334. content = arg2,
  335. duration = arg3 or config.duration + 2,
  336. flash = arg4 or false,
  337. side = arg5 or "left",
  338. isTwoLine = true
  339. })
  340. else
  341. return self:New({
  342. text = arg1,
  343. duration = arg2 or config.duration,
  344. flash = arg3 or false,
  345. side = arg4 or "left",
  346. isTwoLine = false
  347. })
  348. end
  349. end
  350.  
  351. return Notifications
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement