Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hugo/feature/Add Gradient class #560

Draft
wants to merge 5 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ extension PairingView {
case .reinforcer:
let reinforcers: [Robot.Reinforcer] = [.fire, .rainbow, .sprinkles]
return [
(0.0, { Robot.shared.run(reinforcers.randomElement()!) }),
(5.0, { Robot.shared.run(reinforcers.randomElement()!) }),
]
case .light:
let color: [Robot.Color] = [.blue, .green, .orange, .pink, .purple, .red, .yellow]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,7 @@ extension PairingView {
self.updateLightIntensity()

DispatchQueue.main.asyncAfter(deadline: .now() + self.lightIntensityChangeDuration) {
let shadeOfColor: Robot.Color = .init(fromGradient: (.black, .lightBlue), at: self.lightIntensity)
self.robot.shine(.all(in: shadeOfColor))
self.robot.shine(.all(in: Robot.Gradient(fromColors: .black, .white).color(at: self.lightIntensity)))
self.breathe()
}
}
Expand Down
22 changes: 22 additions & 0 deletions Modules/RobotKit/Sources/Extensions/UIColor+toHSV.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Leka - iOS Monorepo
// Copyright APF France handicap
// SPDX-License-Identifier: Apache-2.0

import SwiftUI

// swiftlint:disable identifier_name large_tuple

extension UIColor {
func toHSV() -> (hue: CGFloat, saturation: CGFloat, value: CGFloat) {
var hue: CGFloat = 0
var saturation: CGFloat = 0
var brightness: CGFloat = 0
var alpha: CGFloat = 0

self.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha)

return (hue, saturation, brightness)
}
}

// swiftlint:enable identifier_name large_tuple
41 changes: 23 additions & 18 deletions Modules/RobotKit/Sources/Robot+Colors.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import SwiftUI

// MARK: - Robot.Color

// swiftlint:disable nesting identifier_name line_length
// swiftlint:disable nesting

public extension Robot {
struct Color {
Expand All @@ -26,22 +26,9 @@ public extension Robot {
self = color
}

public init(r: UInt8, g: UInt8, b: UInt8) {
self.robotRGB = [r, g, b]
self.screenRGB = [r, g, b]
}

public init(fromGradient colors: (Color, Color), at position: Float) {
let positionClamped = max(min(position, 1), 0)
let (r1, g1, b1) = (Float(colors.0.robotRGB[0]), Float(colors.0.robotRGB[1]), Float(colors.0.robotRGB[2]))
let (r2, g2, b2) = (Float(colors.1.robotRGB[0]), Float(colors.1.robotRGB[1]), Float(colors.1.robotRGB[2]))

let r = UInt8(r1 + (r2 - r1) * positionClamped)
let g = UInt8(g1 + (g2 - g1) * positionClamped)
let b = UInt8(b1 + (b2 - b1) * positionClamped)

self.robotRGB = [r, g, b]
self.screenRGB = [r, g, b]
public init(red: UInt8, green: UInt8, blue: UInt8) {
self.robotRGB = [red, green, blue]
self.screenRGB = [red, green, blue]
}

// MARK: Public
Expand All @@ -58,6 +45,24 @@ public extension Robot {
)
}

public var robotUiColor: UIColor {
UIColor(
red: Double(self.robotRGB[0]) / 255.0,
green: Double(self.robotRGB[1]) / 255.0,
blue: Double(self.robotRGB[2]) / 255.0,
alpha: 1.0
)
}

public var screenUiColor: UIColor {
UIColor(
red: Double(self.screenRGB[0]) / 255.0,
green: Double(self.screenRGB[1]) / 255.0,
blue: Double(self.screenRGB[2]) / 255.0,
alpha: 1.0
)
}
Comment on lines +48 to +64
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pourquoi tu as besoin de passer par UIColor? pourquoi pas une simple struct?

Comment on lines +48 to +64
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public var robotUiColor: UIColor {
UIColor(
red: Double(self.robotRGB[0]) / 255.0,
green: Double(self.robotRGB[1]) / 255.0,
blue: Double(self.robotRGB[2]) / 255.0,
alpha: 1.0
)
}
public var screenUiColor: UIColor {
UIColor(
red: Double(self.screenRGB[0]) / 255.0,
green: Double(self.screenRGB[1]) / 255.0,
blue: Double(self.screenRGB[2]) / 255.0,
alpha: 1.0
)
}
public var robotUIColor: UIColor {
UIColor(
red: Double(self.robotRGB[0]) / 255.0,
green: Double(self.robotRGB[1]) / 255.0,
blue: Double(self.robotRGB[2]) / 255.0,
alpha: 1.0
)
}
public var screenUIColor: UIColor {
UIColor(
red: Double(self.screenRGB[0]) / 255.0,
green: Double(self.screenRGB[1]) / 255.0,
blue: Double(self.screenRGB[2]) / 255.0,
alpha: 1.0
)
}


// MARK: Private

private enum ColorString: String {
Expand Down Expand Up @@ -120,4 +125,4 @@ public extension Robot.Color {
static let yellow: Robot.Color = .init(robot: 255, 255, 0, screen: 251, 232, 0)
}

// swiftlint:enable nesting identifier_name line_length
// swiftlint:enable nesting
71 changes: 71 additions & 0 deletions Modules/RobotKit/Sources/Robot+Gradient.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Leka - iOS Monorepo
// Copyright APF France handicap
// SPDX-License-Identifier: Apache-2.0

import SwiftUI

// MARK: - Robot.Color

// swiftlint:disable identifier_name

public extension Robot {
struct Gradient {
// MARK: Lifecycle

public init(fromColors colors: Color...) {
self.gradientColors = colors
}
Comment on lines +15 to +17
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

j'ai un "petit" soucis avec ça : c'est que si tu mets + de 2 couleurs, tu pars du principe qu'elles sont toutes équidistante les unes des autres.

dans Illustrator, tu peux faire varier la distance entre 2 couleurs.

dans notre cas ça peut être très pratique pour "accélérer/raccourcir" les zones dans lesquelles les variations sont faibles (ou faiblement perçues) et "ralentir/allonger" des zones où la variation est plus importante

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

une manière simple est d'avoir un autre init qui te permet d'associer couleur et position


// MARK: Public

public func color(at position: Float) -> Robot.Color {
let positionClamped = max(min(position, 1), 0)

let scaledIndex = positionClamped * Float(self.gradientColors.count - 1)
let firstIndex = Int(scaledIndex)
let secondIndex = min(firstIndex + 1, gradientColors.count - 1)
let fraction = CGFloat(scaledIndex - Float(firstIndex))

let firstColor = self.gradientColors[firstIndex]
let secondColor = self.gradientColors[secondIndex]

let (h1, s1, v1) = firstColor.robotUiColor.toHSV()
let (h2, s2, v2) = secondColor.robotUiColor.toHSV()

let h = self.interpolateHue(from: h1, to: h2, fraction: fraction)
let s = self.interpolate(from: s1, to: s2, fraction: fraction)
let v = self.interpolate(from: v1, to: v2, fraction: fraction)

let uiColor = UIColor(hue: h, saturation: s, brightness: v, alpha: 1)

let r = UInt8(max(min(uiColor.cgColor.components![0] * 255.0, 255), 0))
let g = UInt8(max(min(uiColor.cgColor.components![1] * 255.0, 255), 0))
let b = UInt8(max(min(uiColor.cgColor.components![2] * 255.0, 255), 0))

return Robot.Color(red: r, green: g, blue: b)
}
Comment on lines +21 to +46
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

par curiosité, cette formule elle vient d'où? c'est intéressant de mettre en commentaire la source de l'explication scientifique/mathématiques du calcul


// MARK: Private

private let gradientColors: [Robot.Color]

private func interpolate(from start: CGFloat, to end: CGFloat, fraction: CGFloat) -> CGFloat {
start + (end - start) * fraction
}

private func interpolateHue(from start: CGFloat, to end: CGFloat, fraction: CGFloat) -> CGFloat {
let diff = abs(end - start)
if diff > 0.5 {
if start > end {
return (start + ((1.0 + end - start) * fraction)).truncatingRemainder(dividingBy: 1.0)
} else {
return (start - ((1.0 + start - end) * fraction)).truncatingRemainder(dividingBy: 1.0)
}
} else {
return self.interpolate(from: start, to: end, fraction: fraction)
}
}
}
}

// swiftlint:enable identifier_name
Loading