123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- //
- // SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
- // SPDX-License-Identifier: GPL-3.0-or-later
- //
- // See https://github.com/nextcloud/nextcloud-vue/blob/56b79afae93f4701a0cb933bfeb7b4a2fbd590fb/src/functions/usernameToColor/usernameToColor.js
- // and https://github.com/nextcloud/nextcloud-vue/blob/56b79afae93f4701a0cb933bfeb7b4a2fbd590fb/src/utils/GenColors.js
- import Foundation
- import CryptoKit
- @objcMembers class ColorGenerator: NSObject {
- public static let shared = ColorGenerator()
- private let steps = 6
- private let finalPalette: [UIColor]
- // See: https://stackoverflow.com/a/22334560
- private static let multiplier = CGFloat(255.999999)
- private override init() {
- finalPalette = ColorGenerator.genColors(steps)
- super.init()
- }
- private static func stepCalc(_ steps: Int, _ ends: [UIColor]) -> [CGFloat] {
- var step: [CGFloat] = [0, 0, 0]
- var red0: CGFloat = 0
- var green0: CGFloat = 0
- var blue0: CGFloat = 0
- var red1: CGFloat = 0
- var green1: CGFloat = 0
- var blue1: CGFloat = 0
- ends[0].getRed(&red0, green: &green0, blue: &blue0, alpha: nil)
- ends[1].getRed(&red1, green: &green1, blue: &blue1, alpha: nil)
- step[0] = (red1 - red0) / CGFloat(steps)
- step[1] = (green1 - green0) / CGFloat(steps)
- step[2] = (blue1 - blue0) / CGFloat(steps)
- return step
- }
- private static func mixPalette(_ steps: Int, _ color1: UIColor, _ color2: UIColor) -> [UIColor] {
- var palette: [UIColor] = [color1]
- let step = stepCalc(steps, [color1, color2])
- for i in 1...steps - 1 {
- var red: CGFloat = 0
- var green: CGFloat = 0
- var blue: CGFloat = 0
- color1.getRed(&red, green: &green, blue: &blue, alpha: nil)
- let r = abs(red + step[0] * CGFloat(i))
- let g = abs(green + step[1] * CGFloat(i))
- let b = abs(blue + step[2] * CGFloat(i))
- palette.append(UIColor(red: r, green: g, blue: b, alpha: 1))
- }
- return palette
- }
- public static func genColors(_ steps: Int) -> [UIColor] {
- let red = UIColor(red: 182 / multiplier, green: 70 / multiplier, blue: 157 / multiplier, alpha: 1)
- let yellow = UIColor(red: 221 / multiplier, green: 203 / multiplier, blue: 85 / multiplier, alpha: 1)
- let blue = UIColor(red: 0, green: 130 / multiplier, blue: 201 / multiplier, alpha: 1)
- var palette1 = mixPalette(steps, red, yellow)
- let palette2 = mixPalette(steps, yellow, blue)
- let palette3 = mixPalette(steps, blue, red)
- palette1.append(contentsOf: palette2)
- palette1.append(contentsOf: palette3)
- return palette1
- }
- public func usernameToColor(_ username: String) -> UIColor {
- let hash = username.lowercased()
- var hashInt = 0
- if let usernameData = hash.data(using: .utf8) {
- let md5Hash = Insecure.MD5.hash(data: usernameData)
- let t = md5Hash.map { String(format: "%02hhx", $0) }.joined()
- hashInt = t.map { Int(String($0), radix: 16)! % 16}.reduce(0, +)
- }
- let maximum = steps * 3
- hashInt = hashInt % maximum
- return finalPalette[hashInt]
- }
- }
|