Match SwiftUI Color (#177)
This commit is contained in:
parent
97406f1383
commit
2b3010a631
|
@ -15,9 +15,13 @@
|
|||
// Created by Max Desiatov on 16/10/2018.
|
||||
//
|
||||
|
||||
public struct Color: Equatable {
|
||||
public enum Space {
|
||||
public struct Color: Hashable, Equatable {
|
||||
// FIXME: This is not injected.
|
||||
@Environment(\.accentColor) static var envAccentColor: Color?
|
||||
|
||||
public enum RGBColorSpace {
|
||||
case sRGB
|
||||
case sRGBLinear
|
||||
case displayP3
|
||||
}
|
||||
|
||||
|
@ -25,13 +29,13 @@ public struct Color: Equatable {
|
|||
public let green: Double
|
||||
public let blue: Double
|
||||
public let opacity: Double
|
||||
public let space: Space
|
||||
public let space: RGBColorSpace
|
||||
|
||||
public init(_ colorSpace: Space = .sRGB,
|
||||
public init(_ colorSpace: RGBColorSpace = .sRGB,
|
||||
red: Double,
|
||||
green: Double,
|
||||
blue: Double,
|
||||
opacity: Double) {
|
||||
opacity: Double = 1) {
|
||||
self.red = red
|
||||
self.green = green
|
||||
self.blue = blue
|
||||
|
@ -39,11 +43,50 @@ public struct Color: Equatable {
|
|||
space = colorSpace
|
||||
}
|
||||
|
||||
public static var white = Color(red: 1.0, green: 1.0, blue: 1.0, opacity: 1.0)
|
||||
public static var black = Color(red: 0.0, green: 0.0, blue: 0.0, opacity: 1.0)
|
||||
public static var red = Color(red: 1.0, green: 0.0, blue: 0.0, opacity: 1.0)
|
||||
public static var green = Color(red: 0.0, green: 1.0, blue: 0.0, opacity: 1.0)
|
||||
public static var blue = Color(red: 0.0, green: 0.0, blue: 1.0, opacity: 1.0)
|
||||
public init(_ colorSpace: RGBColorSpace = .sRGB,
|
||||
white: Double,
|
||||
opacity: Double = 1) {
|
||||
red = white
|
||||
green = white
|
||||
blue = white
|
||||
self.opacity = opacity
|
||||
space = colorSpace
|
||||
}
|
||||
|
||||
// Source for the formula:
|
||||
// https://en.wikipedia.org/wiki/HSL_and_HSV#HSL_to_RGB_alternative
|
||||
public init(hue: Double,
|
||||
saturation: Double,
|
||||
brightness: Double,
|
||||
opacity: Double = 1) {
|
||||
let a = saturation * min(brightness / 2, 1 - (brightness / 2))
|
||||
let f: (Int) -> Double = { n in
|
||||
let k = Double((n + Int(hue * 12)) % 12)
|
||||
return brightness - (a * max(-1, min(k - 3, 9 - k, 1)))
|
||||
}
|
||||
red = f(0)
|
||||
green = f(8)
|
||||
blue = f(4)
|
||||
self.opacity = opacity
|
||||
space = .sRGB
|
||||
}
|
||||
}
|
||||
|
||||
extension Color {
|
||||
public static let clear: Self = .init(red: 0, green: 0, blue: 0, opacity: 0)
|
||||
public static let black: Self = .init(white: 0)
|
||||
public static let white: Self = .init(white: 1)
|
||||
public static let gray: Self = .init(white: 0.6)
|
||||
public static let red: Self = .init(red: 1.00, green: 0.27, blue: 0.23)
|
||||
public static let green: Self = .init(red: 0.20, green: 0.84, blue: 0.29)
|
||||
public static let blue: Self = .init(red: 0.04, green: 0.52, blue: 1.00)
|
||||
public static let orange: Self = .init(red: 1.00, green: 0.62, blue: 0.04)
|
||||
public static let yellow: Self = .init(red: 1.00, green: 0.84, blue: 0.04)
|
||||
public static let pink: Self = .init(red: 1.00, green: 0.22, blue: 0.37)
|
||||
public static let purple: Self = .init(red: 0.75, green: 0.36, blue: 0.95)
|
||||
// FIXME: Switch to use colorScheme
|
||||
public static let primary: Self = .black
|
||||
public static let secondary: Self = .gray
|
||||
}
|
||||
|
||||
extension Color: ExpressibleByIntegerLiteral {
|
||||
|
@ -84,3 +127,30 @@ extension Color: View {
|
|||
_ShapeView(shape: Rectangle(), style: self)
|
||||
}
|
||||
}
|
||||
|
||||
struct AccentColorKey: EnvironmentKey {
|
||||
static let defaultValue: Color? = nil
|
||||
}
|
||||
|
||||
public extension EnvironmentValues {
|
||||
var accentColor: Color? {
|
||||
get {
|
||||
self[AccentColorKey.self]
|
||||
}
|
||||
set {
|
||||
self[AccentColorKey.self] = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension View {
|
||||
public func accentColor(_ accentColor: Color?) -> some View {
|
||||
environment(\.accentColor, accentColor)
|
||||
}
|
||||
}
|
||||
|
||||
extension Color {
|
||||
public static var accentColor: Self {
|
||||
envAccentColor ?? .blue
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
// Copyright 2019-2020 Tokamak contributors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Created by Carson Katri on 7/12/20.
|
||||
//
|
||||
|
||||
#if canImport(SwiftUI)
|
||||
import SwiftUI
|
||||
#else
|
||||
import TokamakDOM
|
||||
#endif
|
||||
|
||||
public struct ColorDemo: View {
|
||||
var color: Color {
|
||||
guard let v0d = Double(v0),
|
||||
let v1d = Double(v1),
|
||||
let v2d = Double(v2) else {
|
||||
return .white
|
||||
}
|
||||
switch colorForm {
|
||||
case .rgb:
|
||||
return Color(red: v0d, green: v1d, blue: v2d)
|
||||
case .hsb:
|
||||
return Color(hue: v0d, saturation: v1d, brightness: v2d)
|
||||
}
|
||||
}
|
||||
|
||||
enum ColorForm: String {
|
||||
case rgb, hsb
|
||||
}
|
||||
|
||||
@State private var colorForm: ColorForm = .hsb
|
||||
|
||||
@State private var v0: String = "0.9"
|
||||
@State private var v1: String = "1"
|
||||
@State private var v2: String = "0.5"
|
||||
|
||||
let colors: [Color] = [
|
||||
.clear,
|
||||
.black,
|
||||
.white,
|
||||
.gray,
|
||||
.red,
|
||||
.green,
|
||||
.blue,
|
||||
.orange,
|
||||
.yellow,
|
||||
.pink,
|
||||
.purple,
|
||||
.primary,
|
||||
.secondary,
|
||||
]
|
||||
|
||||
public var body: some View {
|
||||
VStack {
|
||||
Button("Input \(colorForm.rawValue.uppercased())") {
|
||||
colorForm = colorForm == .rgb ? .hsb : .rgb
|
||||
}
|
||||
TextField(colorForm == .rgb ? "Red" : "Hue", text: $v0)
|
||||
TextField(colorForm == .rgb ? "Green" : "Saturation", text: $v1)
|
||||
TextField(colorForm == .rgb ? "Blue" : "Brightness", text: $v2)
|
||||
Text("\(v0) \(v1) \(v2)")
|
||||
.bold()
|
||||
.padding()
|
||||
.background(color)
|
||||
Text("Accent Color: \(Color.accentColor.description)")
|
||||
.bold()
|
||||
.padding()
|
||||
.background(Color.accentColor)
|
||||
ForEach(colors, id: \.self) {
|
||||
Text($0.description)
|
||||
.font(.caption)
|
||||
.bold()
|
||||
.padding()
|
||||
.background($0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -56,6 +56,8 @@ struct TokamakDemoView: View {
|
|||
if #available(OSX 10.16, *) {
|
||||
OutlineGroupDemo()
|
||||
}
|
||||
ColorDemo()
|
||||
.padding()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
85ED18B624AD42D70085DFA0 /* NSAppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85ED189424AD41B90085DFA0 /* NSAppDelegate.swift */; };
|
||||
B51F215024B920B400CF2583 /* PathDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51F214F24B920B400CF2583 /* PathDemo.swift */; };
|
||||
B51F215124B920B400CF2583 /* PathDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51F214F24B920B400CF2583 /* PathDemo.swift */; };
|
||||
B56F22E024BC89FD001738DF /* ColorDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56F22DF24BC89FD001738DF /* ColorDemo.swift */; };
|
||||
B56F22E124BC89FD001738DF /* ColorDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56F22DF24BC89FD001738DF /* ColorDemo.swift */; };
|
||||
D1B4229024B3B9BB00682F74 /* ListDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1B4228E24B3B9BB00682F74 /* ListDemo.swift */; };
|
||||
D1B4229124B3B9BB00682F74 /* ListDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1B4228E24B3B9BB00682F74 /* ListDemo.swift */; };
|
||||
D1B4229224B3B9BB00682F74 /* OutlineGroupDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1B4228F24B3B9BB00682F74 /* OutlineGroupDemo.swift */; };
|
||||
|
@ -50,6 +52,7 @@
|
|||
85ED18BD24AD46340085DFA0 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
85ED18BF24AD464B0085DFA0 /* iOS Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "iOS Info.plist"; sourceTree = "<group>"; };
|
||||
B51F214F24B920B400CF2583 /* PathDemo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PathDemo.swift; sourceTree = "<group>"; };
|
||||
B56F22DF24BC89FD001738DF /* ColorDemo.swift */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.swift; path = ColorDemo.swift; sourceTree = "<group>"; tabWidth = 2; };
|
||||
D1B4228E24B3B9BB00682F74 /* ListDemo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListDemo.swift; sourceTree = "<group>"; };
|
||||
D1B4228F24B3B9BB00682F74 /* OutlineGroupDemo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OutlineGroupDemo.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
@ -108,6 +111,7 @@
|
|||
85ED189F24AD425E0085DFA0 /* TextFieldDemo.swift */,
|
||||
85ED18A024AD425E0085DFA0 /* EnvironmentDemo.swift */,
|
||||
B51F214F24B920B400CF2583 /* PathDemo.swift */,
|
||||
B56F22DF24BC89FD001738DF /* ColorDemo.swift */,
|
||||
);
|
||||
name = TokamakDemo;
|
||||
path = ../Sources/TokamakDemo;
|
||||
|
@ -214,6 +218,7 @@
|
|||
files = (
|
||||
85ED186A24AD38F20085DFA0 /* UIAppDelegate.swift in Sources */,
|
||||
D1B4229224B3B9BB00682F74 /* OutlineGroupDemo.swift in Sources */,
|
||||
B56F22E024BC89FD001738DF /* ColorDemo.swift in Sources */,
|
||||
B51F215024B920B400CF2583 /* PathDemo.swift in Sources */,
|
||||
85ED18AF24AD425E0085DFA0 /* EnvironmentDemo.swift in Sources */,
|
||||
85ED18A324AD425E0085DFA0 /* SpacerDemo.swift in Sources */,
|
||||
|
@ -232,6 +237,7 @@
|
|||
files = (
|
||||
85ED18AA24AD425E0085DFA0 /* TokamakDemo.swift in Sources */,
|
||||
D1B4229324B3B9BB00682F74 /* OutlineGroupDemo.swift in Sources */,
|
||||
B56F22E124BC89FD001738DF /* ColorDemo.swift in Sources */,
|
||||
B51F215124B920B400CF2583 /* PathDemo.swift in Sources */,
|
||||
85ED18A424AD425E0085DFA0 /* SpacerDemo.swift in Sources */,
|
||||
85ED18B024AD425E0085DFA0 /* EnvironmentDemo.swift in Sources */,
|
||||
|
|
Loading…
Reference in New Issue