.../Source/Extensions/NSColor+HexColorString.swift
Line | Count | Source (jump to first uncovered line) |
1 | | // |
2 | | // NSColor+HexColorString.swift |
3 | | // CutBox |
4 | | // |
5 | | // Created by Jason on 30/5/22. |
6 | | // Copyright © 2023 ocodo. All rights reserved. |
7 | | // |
8 | | |
9 | | import Foundation |
10 | | import AppKit.NSColor |
11 | | |
12 | | extension String { |
13 | 24.0k | var color: NSColor? { |
14 | 24.0k | guard let color = NSColor(hex: self) else { |
15 | 1 | return nil |
16 | 24.0k | } |
17 | 24.0k | return color |
18 | 24.0k | } |
19 | | } |
20 | | |
21 | | extension NSColor { |
22 | 24.0k | convenience init?(hex: String) { |
23 | 24.0k | var hexSanitized = hex.trimmingCharacters(in: .whitespacesAndNewlines) |
24 | 24.0k | hexSanitized = hexSanitized.replacingOccurrences(of: "#", with: "") |
25 | 24.0k | |
26 | 24.0k | var rgb: UInt64 = 0 |
27 | 24.0k | |
28 | 24.0k | var red: CGFloat = 0.0 |
29 | 24.0k | var green: CGFloat = 0.0 |
30 | 24.0k | var blue: CGFloat = 0.0 |
31 | 24.0k | var alpha: CGFloat = 1.0 |
32 | 24.0k | |
33 | 24.0k | let length = hexSanitized.count |
34 | 24.0k | |
35 | 24.0k | guard Scanner(string: hexSanitized).scanHexInt64(&rgb) else { |
36 | 1 | return nil |
37 | 24.0k | } |
38 | 24.0k | |
39 | 24.0k | if length == 6 { |
40 | 22.2k | red = CGFloat((rgb & 0xFF0000) >> 16) / 255.0 |
41 | 22.2k | green = CGFloat((rgb & 0x00FF00) >> 8) / 255.0 |
42 | 22.2k | blue = CGFloat(rgb & 0x0000FF) / 255.0 |
43 | 24.0k | } else if length == 8 { |
44 | 1.84k | red = CGFloat((rgb & 0xFF000000) >> 24) / 255.0 |
45 | 1.84k | green = CGFloat((rgb & 0x00FF0000) >> 16) / 255.0 |
46 | 1.84k | blue = CGFloat((rgb & 0x0000FF00) >> 8) / 255.0 |
47 | 1.84k | alpha = CGFloat(rgb & 0x000000FF) / 255.0 |
48 | 24.0k | } |
49 | 24.0k | |
50 | 24.0k | self.init(red: red, green: green, blue: blue, alpha: alpha) |
51 | 24.0k | } |
52 | | |
53 | 2 | var toHex: String? { |
54 | 2 | return toHex() |
55 | 2 | } |
56 | | |
57 | 2 | var toHexAlpha: String? { |
58 | 2 | return toHex(alpha: true) |
59 | 2 | } |
60 | | |
61 | 5 | func toHex(alpha hasAlpha: Bool = false) -> String? { |
62 | 5 | guard let components = cgColor.components, components.count >= 3 else { |
63 | 0 | return nil |
64 | 5 | } |
65 | 5 | let red = Float(components[0]) |
66 | 5 | let green = Float(components[1]) |
67 | 5 | let blue = Float(components[2]) |
68 | 5 | var alpha = Float(1.0) |
69 | 5 | if components.count >= 4 { |
70 | 5 | alpha = Float(components[3]) |
71 | 5 | } |
72 | 5 | |
73 | 5 | if hasAlpha { |
74 | 3 | return String(format: "%02lX%02lX%02lX%02lX", |
75 | 3 | lroundf(red * 255), lroundf(green * 255), lroundf(blue * 255), lroundf(alpha * 255)) |
76 | 3 | } else { |
77 | 2 | return String(format: "%02lX%02lX%02lX", |
78 | 2 | lroundf(red * 255), lroundf(green * 255), lroundf(blue * 255)) |
79 | 2 | } |
80 | 0 | } |
81 | | } |