Added Card, Glow Refactor

This commit is contained in:
Francisco Gindre 2020-06-19 09:29:44 -03:00
parent d3e2769327
commit 1fa3bb1c7d
5 changed files with 394 additions and 75 deletions

View File

@ -7,6 +7,9 @@
objects = {
/* Begin PBXBuildFile section */
0D11D3CE249C294E00223146 /* NeumorphicButtons.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D11D3CD249C294E00223146 /* NeumorphicButtons.swift */; };
0D11D3D0249C3AE400223146 /* Card.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D11D3CF249C3AE300223146 /* Card.swift */; };
0D11D3D2249CE6C800223146 /* GlowEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D11D3D1249CE6C800223146 /* GlowEffect.swift */; };
0D1366AC24991A6000F0EB54 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D1366AB24991A6000F0EB54 /* AppDelegate.swift */; };
0D1366AE24991A6000F0EB54 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D1366AD24991A6000F0EB54 /* SceneDelegate.swift */; };
0D1366B024991A6000F0EB54 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D1366AF24991A6000F0EB54 /* ContentView.swift */; };
@ -19,7 +22,7 @@
0D6A22C5249AB1FC00B4E946 /* ZcashSymbol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D6A22C4249AB1FC00B4E946 /* ZcashSymbol.swift */; };
0D6A22C7249AB36100B4E946 /* ZcashButtonBackground.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D6A22C6249AB36100B4E946 /* ZcashButtonBackground.swift */; };
0D6A22C9249AB3CA00B4E946 /* ZcashButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D6A22C8249AB3CA00B4E946 /* ZcashButton.swift */; };
0D6A22CB249AB61200B4E946 /* Glow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D6A22CA249AB61200B4E946 /* Glow.swift */; };
0D6A22CB249AB61200B4E946 /* Glow_Preview.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D6A22CA249AB61200B4E946 /* Glow_Preview.swift */; };
4A79AF7FBA1F1ABC33BDD0DD /* Pods_Zircles.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0EF685DA606F425B52CC5DC2 /* Pods_Zircles.framework */; };
9DE24A8E04467408269AD782 /* Pods_ZirclesTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BBBDF5C4ADB5C51259A3817D /* Pods_ZirclesTests.framework */; };
A78732A65E5555C51A0C4D44 /* Pods_Zircles_ZirclesUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6205D6783F82D4352213AE76 /* Pods_Zircles_ZirclesUITests.framework */; };
@ -44,6 +47,9 @@
/* Begin PBXFileReference section */
08F4F839AA82F245159E5A95 /* Pods-ZirclesUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ZirclesUITests.release.xcconfig"; path = "Target Support Files/Pods-ZirclesUITests/Pods-ZirclesUITests.release.xcconfig"; sourceTree = "<group>"; };
0D11D3CD249C294E00223146 /* NeumorphicButtons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NeumorphicButtons.swift; sourceTree = "<group>"; };
0D11D3CF249C3AE300223146 /* Card.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Card.swift; sourceTree = "<group>"; };
0D11D3D1249CE6C800223146 /* GlowEffect.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlowEffect.swift; sourceTree = "<group>"; };
0D1366A824991A6000F0EB54 /* Zircles.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Zircles.app; sourceTree = BUILT_PRODUCTS_DIR; };
0D1366AB24991A6000F0EB54 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
0D1366AD24991A6000F0EB54 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
@ -62,7 +68,7 @@
0D6A22C4249AB1FC00B4E946 /* ZcashSymbol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZcashSymbol.swift; sourceTree = "<group>"; };
0D6A22C6249AB36100B4E946 /* ZcashButtonBackground.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZcashButtonBackground.swift; sourceTree = "<group>"; };
0D6A22C8249AB3CA00B4E946 /* ZcashButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZcashButton.swift; sourceTree = "<group>"; };
0D6A22CA249AB61200B4E946 /* Glow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Glow.swift; sourceTree = "<group>"; };
0D6A22CA249AB61200B4E946 /* Glow_Preview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Glow_Preview.swift; sourceTree = "<group>"; };
0EF685DA606F425B52CC5DC2 /* Pods_Zircles.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Zircles.framework; sourceTree = BUILT_PRODUCTS_DIR; };
1F41B44F15E6B8B8AC35DA82 /* Pods-ZirclesUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ZirclesUITests.debug.xcconfig"; path = "Target Support Files/Pods-ZirclesUITests/Pods-ZirclesUITests.debug.xcconfig"; sourceTree = "<group>"; };
215B95DF0D4FE064A7C4BD8D /* Pods-ZirclesTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ZirclesTests.debug.xcconfig"; path = "Target Support Files/Pods-ZirclesTests/Pods-ZirclesTests.debug.xcconfig"; sourceTree = "<group>"; };
@ -174,7 +180,7 @@
0D6A22C8249AB3CA00B4E946 /* ZcashButton.swift */,
0D6A22C6249AB36100B4E946 /* ZcashButtonBackground.swift */,
0D6A22C4249AB1FC00B4E946 /* ZcashSymbol.swift */,
0D6A22CA249AB61200B4E946 /* Glow.swift */,
0D6A22CA249AB61200B4E946 /* Glow_Preview.swift */,
);
path = Components;
sourceTree = "<group>";
@ -182,6 +188,9 @@
0D6A22CC249ACD6C00B4E946 /* Neumorphic */ = {
isa = PBXGroup;
children = (
0D11D3CD249C294E00223146 /* NeumorphicButtons.swift */,
0D11D3CF249C3AE300223146 /* Card.swift */,
0D11D3D1249CE6C800223146 /* GlowEffect.swift */,
);
path = Neumorphic;
sourceTree = "<group>";
@ -454,9 +463,12 @@
0D6A22C0249A9C3000B4E946 /* Colors+Zircles.swift in Sources */,
0D6A22C5249AB1FC00B4E946 /* ZcashSymbol.swift in Sources */,
0D1366AC24991A6000F0EB54 /* AppDelegate.swift in Sources */,
0D11D3CE249C294E00223146 /* NeumorphicButtons.swift in Sources */,
0D6A22C7249AB36100B4E946 /* ZcashButtonBackground.swift in Sources */,
0D1366AE24991A6000F0EB54 /* SceneDelegate.swift in Sources */,
0D6A22CB249AB61200B4E946 /* Glow.swift in Sources */,
0D11D3D0249C3AE400223146 /* Card.swift in Sources */,
0D6A22CB249AB61200B4E946 /* Glow_Preview.swift in Sources */,
0D11D3D2249CE6C800223146 /* GlowEffect.swift in Sources */,
0D1366B024991A6000F0EB54 /* ContentView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -512,6 +524,7 @@
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_CODE_COVERAGE = NO;
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
@ -572,6 +585,7 @@
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_CODE_COVERAGE = NO;
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;

View File

@ -9,77 +9,6 @@
import Foundation
import SwiftUI
typealias GlowVibe = GlowModifier.GlowVibe
typealias GlowSoul = GlowModifier.GlowSoul
struct GlowModifier: ViewModifier {
enum GlowVibe {
case mild
case cool
case heavy
}
enum GlowSoul {
case solid(color: Color)
case split(left: Color, right: Color)
}
var vibe: GlowVibe
var soul: GlowSoul
func body(content: Content) -> some View {
let colors = color(soul: soul)
return content
.shadow(color:colors.0.opacity(0.7), radius: radius(vibe), x: -offsetX(vibe), y: 0)
.shadow(color:colors.1.opacity(0.7), radius: radius(vibe), x: offsetX(vibe), y: 0)
}
func color(soul: GlowSoul) -> (Color, Color) {
switch soul {
case .solid(let color):
return (color,color)
case .split(let left,let right):
return (left, right)
}
}
func radius(_ vibe: GlowVibe) -> CGFloat {
switch vibe {
case .mild:
return 6
case .cool:
return 20
case .heavy:
return 40
}
}
func offsetX(_ vibe: GlowVibe) -> CGFloat {
switch vibe {
case .mild:
return 3
case .cool:
return 12
case .heavy:
return 24
}
}
}
extension View {
func glow(vibe: GlowVibe, soul: GlowSoul) -> some View {
self.modifier(
GlowModifier(vibe: vibe, soul: soul)
)
}
}
struct GlowButtons_Previews: PreviewProvider {
static var previews: some View {
ZStack {

View File

@ -0,0 +1,39 @@
//
// Card.swift
// Zircles
//
// Created by Francisco Gindre on 6/18/20.
// Copyright © 2020 Electric Coin Company. All rights reserved.
//
import SwiftUI
struct Card<Content: View>: View {
@Binding var isToggled: Bool
let content: Content
init(isOn: Binding<Bool>, @ViewBuilder content: () -> Content) {
self._isToggled = isOn
self.content = content()
}
var body: some View {
Toggle(isOn: $isToggled) {
content
}
.toggleStyle(SimpleToggleStyle(cornerRadius: 25))
}
}
struct Card_Previews: PreviewProvider {
@State static var isToggled: Bool = false
static var previews: some View {
ZStack {
Color.background
Card(isOn: $isToggled) {
Image(systemName: "heart.fill")
.foregroundColor(.gray)
.frame(width: 200, height: 200)
}
}
}
}

View File

@ -0,0 +1,79 @@
//
// GlowEffect.swift
// Zircles
//
// Created by Francisco Gindre on 6/19/20.
// Copyright © 2020 Electric Coin Company. All rights reserved.
//
import SwiftUI
typealias GlowVibe = GlowEffect.Vibe
typealias GlowSoul = GlowEffect.Soul
struct GlowEffect: ViewModifier {
enum Vibe {
case mild
case cool
case heavy
}
enum Soul {
case solid(color: Color)
case split(left: Color, right: Color)
}
var vibe: Vibe
var soul: Soul
func body(content: Content) -> some View {
let colors = color(soul: soul)
return content
.shadow(color:colors.0.opacity(0.7), radius: radius(vibe), x: -offsetX(vibe), y: 0)
.shadow(color:colors.1.opacity(0.7), radius: radius(vibe), x: offsetX(vibe), y: 0)
}
func color(soul: Soul) -> (Color, Color) {
switch soul {
case .solid(let color):
return (color,color)
case .split(let left,let right):
return (left, right)
}
}
func radius(_ vibe: Vibe) -> CGFloat {
switch vibe {
case .mild:
return 6
case .cool:
return 20
case .heavy:
return 40
}
}
func offsetX(_ vibe: Vibe) -> CGFloat {
switch vibe {
case .mild:
return 3
case .cool:
return 12
case .heavy:
return 24
}
}
}
extension View {
func glow(vibe: GlowVibe, soul: GlowSoul) -> some View {
self.modifier(
GlowEffect(vibe: vibe, soul: soul)
)
}
}

View File

@ -0,0 +1,258 @@
import SwiftUI
extension Color {
static let offWhite = Color(red: 225 / 255, green: 225 / 255, blue: 235 / 255)
static let darkStart = Color(red: 50 / 255, green: 60 / 255, blue: 65 / 255)
static let darkEnd = Color(red: 25 / 255, green: 25 / 255, blue: 30 / 255)
static let lightStart = Color(red: 60 / 255, green: 160 / 255, blue: 240 / 255)
static let lightEnd = Color(red: 30 / 255, green: 80 / 255, blue: 120 / 255)
}
extension LinearGradient {
init(_ colors: Color...) {
self.init(gradient: Gradient(colors: colors), startPoint: .topLeading, endPoint: .bottomTrailing)
}
}
struct SimpleButtonStyle: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.padding(30)
.contentShape(Circle())
.background(
Group {
if configuration.isPressed {
Circle()
.fill(Color.offWhite)
.overlay(
Circle()
.stroke(Color.gray, lineWidth: 4)
.blur(radius: 4)
.offset(x: 2, y: 2)
.mask(Circle().fill(LinearGradient(Color.black, Color.clear)))
)
.overlay(
Circle()
.stroke(Color.white, lineWidth: 8)
.blur(radius: 4)
.offset(x: -2, y: -2)
.mask(Circle().fill(LinearGradient(Color.clear, Color.black)))
)
} else {
Circle()
.fill(Color.offWhite)
.shadow(color: Color.black.opacity(0.2), radius: 10, x: 10, y: 10)
.shadow(color: Color.white.opacity(0.7), radius: 10, x: -5, y: -5)
}
}
)
}
}
struct SimpleBackground<S: Shape>: View {
var isHighlighted: Bool
var shape: S
var body: some View {
ZStack {
if isHighlighted {
shape
.fill(Color.offWhite)
.overlay(
shape
.stroke(Color.gray, lineWidth: 4)
.blur(radius: 4)
.offset(x: 2, y: 2)
.mask(shape.fill(LinearGradient(Color.black, Color.clear)))
)
.overlay(
shape
.stroke(Color.white, lineWidth: 8)
.blur(radius: 4)
.offset(x: -2, y: -2)
.mask(shape.fill(LinearGradient(Color.clear, Color.black)))
)
} else {
shape
.fill(Color.offWhite)
.shadow(color: Color.black.opacity(0.2), radius: 10, x: 10, y: 10)
.shadow(color: Color.white.opacity(0.7), radius: 10, x: -5, y: -5)
}
}
}
}
struct DarkBackground<S: Shape>: View {
var isHighlighted: Bool
var shape: S
var body: some View {
ZStack {
if isHighlighted {
shape
.fill(LinearGradient(Color.darkEnd, Color.darkStart))
.overlay(shape.stroke(LinearGradient(Color.darkStart, Color.darkEnd), lineWidth: 4))
.shadow(color: Color.darkStart, radius: 10, x: 5, y: 5)
.shadow(color: Color.darkEnd, radius: 10, x: -5, y: -5)
} else {
shape
.fill(LinearGradient(Color.darkStart, Color.darkEnd))
.overlay(shape.stroke(Color.darkEnd, lineWidth: 4))
.shadow(color: Color.darkStart, radius: 10, x: -10, y: -10)
.shadow(color: Color.darkEnd, radius: 10, x: 10, y: 10)
}
}
}
}
struct ColorfulBackground<S: Shape>: View {
var isHighlighted: Bool
var shape: S
var body: some View {
ZStack {
if isHighlighted {
shape
.fill(LinearGradient(Color.lightEnd, Color.lightStart))
.overlay(shape.stroke(LinearGradient(Color.lightStart, Color.lightEnd), lineWidth: 4))
.shadow(color: Color.darkStart, radius: 10, x: 5, y: 5)
.shadow(color: Color.darkEnd, radius: 10, x: -5, y: -5)
} else {
shape
.fill(LinearGradient(Color.darkStart, Color.darkEnd))
.overlay(shape.stroke(LinearGradient(Color.lightStart, Color.lightEnd), lineWidth: 4))
.shadow(color: Color.darkStart, radius: 10, x: -10, y: -10)
.shadow(color: Color.darkEnd, radius: 10, x: 10, y: 10)
}
}
}
}
struct DarkButtonStyle: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.padding(30)
.contentShape(Circle())
.background(
DarkBackground(isHighlighted: configuration.isPressed, shape: Circle())
)
.animation(nil)
}
}
struct DarkToggleStyle: ToggleStyle {
func makeBody(configuration: Self.Configuration) -> some View {
Button(action: {
configuration.isOn.toggle()
}) {
configuration.label
.padding(30)
.contentShape(Circle())
}
.background(
DarkBackground(isHighlighted: configuration.isOn, shape: Circle())
)
}
}
struct ColorfulButtonStyle: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.padding(30)
.contentShape(Circle())
.background(
ColorfulBackground(isHighlighted: configuration.isPressed, shape: Circle())
)
.animation(nil)
}
}
struct SimpleToggleStyle: ToggleStyle {
var cornerRadius: CGFloat = 5
func makeBody(configuration: Self.Configuration) -> some View {
Button(action: {
configuration.isOn.toggle()
}) {
configuration.label
.contentShape(RoundedRectangle(cornerRadius: cornerRadius))
.padding(30)
}
.background(
SimpleBackground(isHighlighted: configuration.isOn, shape: RoundedRectangle(cornerRadius: cornerRadius))
)
}
}
struct ColorfulToggleStyle: ToggleStyle {
func makeBody(configuration: Self.Configuration) -> some View {
Button(action: {
configuration.isOn.toggle()
}) {
configuration.label
.padding(30)
.contentShape(RoundedRectangle(cornerRadius: 5))
}
.background(
ColorfulBackground(isHighlighted: configuration.isOn, shape: RoundedRectangle(cornerRadius: 5))
)
}
}
struct NeumorphicContentView: View {
@State private var isToggled = false
var body: some View {
VStack {
ZStack {
LinearGradient(Color.darkStart, Color.darkEnd)
VStack(spacing: 40) {
Button(action: {
print("Button tapped")
}) {
Image(systemName: "heart.fill")
.foregroundColor(.white)
}
.buttonStyle(ColorfulButtonStyle())
Toggle(isOn: $isToggled) {
Image(systemName: "heart.fill")
.foregroundColor(.white)
}
.toggleStyle(ColorfulToggleStyle())
}
}
ZStack {
Color.offWhite
VStack(spacing: 40) {
Button(action: {
print("Button tapped")
}) {
Image(systemName: "heart.fill")
.foregroundColor(.gray)
}
.buttonStyle(SimpleButtonStyle())
Toggle(isOn: $isToggled) {
Image(systemName: "heart.fill")
.foregroundColor(.gray)
.frame(width: 200, height: 200)
}
.toggleStyle(SimpleToggleStyle(cornerRadius: 50))
}
}
}
.edgesIgnoringSafeArea(.all)
}
}
struct ButtonsView_Previews: PreviewProvider {
static var previews: some View {
NeumorphicContentView()
}
}