Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>
This commit is contained in:
parent
c846ef05ac
commit
b08e92a402
@ -43,7 +43,9 @@ enum Design {
|
|||||||
static let xSmall: CGFloat = 9
|
static let xSmall: CGFloat = 9
|
||||||
static let small: CGFloat = 10
|
static let small: CGFloat = 10
|
||||||
static let body: CGFloat = 12
|
static let body: CGFloat = 12
|
||||||
|
static let callout: CGFloat = 13
|
||||||
static let medium: CGFloat = 14
|
static let medium: CGFloat = 14
|
||||||
|
static let subheadline: CGFloat = 15
|
||||||
static let large: CGFloat = 16
|
static let large: CGFloat = 16
|
||||||
static let xLarge: CGFloat = 18
|
static let xLarge: CGFloat = 18
|
||||||
static let xxLarge: CGFloat = 20
|
static let xxLarge: CGFloat = 20
|
||||||
@ -83,22 +85,46 @@ enum Design {
|
|||||||
static let quick: Double = 0.3
|
static let quick: Double = 0.3
|
||||||
static let springDuration: Double = 0.4
|
static let springDuration: Double = 0.4
|
||||||
static let springBounce: Double = 0.3
|
static let springBounce: Double = 0.3
|
||||||
|
static let cardFlipBounce: Double = 0.2
|
||||||
static let fadeInDuration: Double = 0.3
|
static let fadeInDuration: Double = 0.3
|
||||||
static let cardFlipDuration: Double = 0.5
|
static let cardFlipDuration: Double = 0.5
|
||||||
|
static let selectionDuration: Double = 0.2
|
||||||
|
static let staggerDelay1: Double = 0.2
|
||||||
|
static let staggerDelay2: Double = 0.4
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Opacity
|
// MARK: - Opacity
|
||||||
|
|
||||||
enum Opacity {
|
enum Opacity {
|
||||||
static let disabled: Double = 0.5
|
static let verySubtle: Double = 0.05
|
||||||
static let subtle: Double = 0.1
|
static let subtle: Double = 0.1
|
||||||
|
static let hint: Double = 0.2
|
||||||
static let light: Double = 0.3
|
static let light: Double = 0.3
|
||||||
static let overlay: Double = 0.4
|
static let overlay: Double = 0.4
|
||||||
static let medium: Double = 0.5
|
static let medium: Double = 0.5
|
||||||
static let secondary: Double = 0.5
|
static let secondary: Double = 0.5
|
||||||
|
static let disabled: Double = 0.5
|
||||||
static let strong: Double = 0.7
|
static let strong: Double = 0.7
|
||||||
static let heavy: Double = 0.8
|
static let heavy: Double = 0.8
|
||||||
static let nearOpaque: Double = 0.85
|
static let nearOpaque: Double = 0.85
|
||||||
|
static let almostFull: Double = 0.9
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Scale Effects
|
||||||
|
|
||||||
|
enum Scale {
|
||||||
|
static let shrunk: Double = 0.5
|
||||||
|
static let slightShrink: Double = 0.8
|
||||||
|
static let normal: Double = 1.0
|
||||||
|
static let selected: Double = 1.1
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Minimum Scale Factor (for text)
|
||||||
|
|
||||||
|
enum MinScaleFactor {
|
||||||
|
static let tight: Double = 0.5
|
||||||
|
static let comfortable: Double = 0.6
|
||||||
|
static let relaxed: Double = 0.7
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Line Widths
|
// MARK: - Line Widths
|
||||||
|
|||||||
@ -35,7 +35,7 @@ struct CardView: View {
|
|||||||
.degrees(isFaceUp ? 0 : 180),
|
.degrees(isFaceUp ? 0 : 180),
|
||||||
axis: (x: 0, y: 1, z: 0)
|
axis: (x: 0, y: 1, z: 0)
|
||||||
)
|
)
|
||||||
.animation(.spring(duration: 0.4, bounce: 0.2), value: isFaceUp)
|
.animation(.spring(duration: Design.Animation.springDuration, bounce: Design.Animation.cardFlipBounce), value: isFaceUp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,6 +45,16 @@ struct CardFrontView: View {
|
|||||||
let width: CGFloat
|
let width: CGFloat
|
||||||
let height: CGFloat
|
let height: CGFloat
|
||||||
|
|
||||||
|
// MARK: - Layout Constants
|
||||||
|
|
||||||
|
private let rankFontRatio: CGFloat = 0.22
|
||||||
|
private let suitFontRatio: CGFloat = 0.18
|
||||||
|
private let centerSuitFontRatio: CGFloat = 0.5
|
||||||
|
private let contentPaddingRatio: CGFloat = 0.08
|
||||||
|
private let backgroundWhite: Double = 0.96
|
||||||
|
private let borderLightGray: Double = 0.8
|
||||||
|
private let borderDarkGray: Double = 0.6
|
||||||
|
|
||||||
private var suitColor: Color {
|
private var suitColor: Color {
|
||||||
card.suit.isRed ? .red : .black
|
card.suit.isRed ? .red : .black
|
||||||
}
|
}
|
||||||
@ -52,24 +62,24 @@ struct CardFrontView: View {
|
|||||||
var body: some View {
|
var body: some View {
|
||||||
ZStack {
|
ZStack {
|
||||||
// Card background with subtle gradient
|
// Card background with subtle gradient
|
||||||
RoundedRectangle(cornerRadius: 8)
|
RoundedRectangle(cornerRadius: Design.CornerRadius.small)
|
||||||
.fill(
|
.fill(
|
||||||
LinearGradient(
|
LinearGradient(
|
||||||
colors: [.white, Color(white: 0.96)],
|
colors: [.white, Color(white: backgroundWhite)],
|
||||||
startPoint: .topLeading,
|
startPoint: .topLeading,
|
||||||
endPoint: .bottomTrailing
|
endPoint: .bottomTrailing
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
// Card border
|
// Card border
|
||||||
RoundedRectangle(cornerRadius: 8)
|
RoundedRectangle(cornerRadius: Design.CornerRadius.small)
|
||||||
.strokeBorder(
|
.strokeBorder(
|
||||||
LinearGradient(
|
LinearGradient(
|
||||||
colors: [Color(white: 0.8), Color(white: 0.6)],
|
colors: [Color(white: borderLightGray), Color(white: borderDarkGray)],
|
||||||
startPoint: .topLeading,
|
startPoint: .topLeading,
|
||||||
endPoint: .bottomTrailing
|
endPoint: .bottomTrailing
|
||||||
),
|
),
|
||||||
lineWidth: 1
|
lineWidth: Design.LineWidth.thin
|
||||||
)
|
)
|
||||||
|
|
||||||
// Card content
|
// Card content
|
||||||
@ -78,9 +88,9 @@ struct CardFrontView: View {
|
|||||||
HStack {
|
HStack {
|
||||||
VStack(spacing: 0) {
|
VStack(spacing: 0) {
|
||||||
Text(card.rank.symbol)
|
Text(card.rank.symbol)
|
||||||
.font(.system(size: width * 0.22, weight: .bold, design: .serif))
|
.font(.system(size: width * rankFontRatio, weight: .bold, design: .serif))
|
||||||
Text(card.suit.rawValue)
|
Text(card.suit.rawValue)
|
||||||
.font(.system(size: width * 0.18))
|
.font(.system(size: width * suitFontRatio))
|
||||||
}
|
}
|
||||||
.foregroundStyle(suitColor)
|
.foregroundStyle(suitColor)
|
||||||
Spacer()
|
Spacer()
|
||||||
@ -90,7 +100,7 @@ struct CardFrontView: View {
|
|||||||
|
|
||||||
// Center suit (large)
|
// Center suit (large)
|
||||||
Text(card.suit.rawValue)
|
Text(card.suit.rawValue)
|
||||||
.font(.system(size: width * 0.5))
|
.font(.system(size: width * centerSuitFontRatio))
|
||||||
.foregroundStyle(suitColor)
|
.foregroundStyle(suitColor)
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
@ -100,18 +110,18 @@ struct CardFrontView: View {
|
|||||||
Spacer()
|
Spacer()
|
||||||
VStack(spacing: 0) {
|
VStack(spacing: 0) {
|
||||||
Text(card.suit.rawValue)
|
Text(card.suit.rawValue)
|
||||||
.font(.system(size: width * 0.18))
|
.font(.system(size: width * suitFontRatio))
|
||||||
Text(card.rank.symbol)
|
Text(card.rank.symbol)
|
||||||
.font(.system(size: width * 0.22, weight: .bold, design: .serif))
|
.font(.system(size: width * rankFontRatio, weight: .bold, design: .serif))
|
||||||
}
|
}
|
||||||
.foregroundStyle(suitColor)
|
.foregroundStyle(suitColor)
|
||||||
.rotationEffect(.degrees(180))
|
.rotationEffect(.degrees(180))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding(width * 0.08)
|
.padding(width * contentPaddingRatio)
|
||||||
}
|
}
|
||||||
.frame(width: width, height: height)
|
.frame(width: width, height: height)
|
||||||
.shadow(color: .black.opacity(0.2), radius: 4, x: 2, y: 2)
|
.shadow(color: .black.opacity(Design.Opacity.hint), radius: Design.Shadow.radiusSmall, x: 2, y: 2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,6 +130,14 @@ struct CardBackView: View {
|
|||||||
let width: CGFloat
|
let width: CGFloat
|
||||||
let height: CGFloat
|
let height: CGFloat
|
||||||
|
|
||||||
|
// MARK: - Layout Constants
|
||||||
|
|
||||||
|
private let innerPaddingRatio: CGFloat = 0.1
|
||||||
|
private let patternPaddingRatio: CGFloat = 0.12
|
||||||
|
private let emblemGradientRatio: CGFloat = 0.15
|
||||||
|
private let emblemSizeRatio: CGFloat = 0.3
|
||||||
|
private let logoFontRatio: CGFloat = 0.18
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
ZStack {
|
ZStack {
|
||||||
// Base
|
// Base
|
||||||
@ -161,14 +179,14 @@ struct CardBackView: View {
|
|||||||
endPoint: .bottom
|
endPoint: .bottom
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.padding(width * 0.1)
|
.padding(width * innerPaddingRatio)
|
||||||
|
|
||||||
// Diamond pattern overlay
|
// Diamond pattern overlay
|
||||||
DiamondPatternView()
|
DiamondPatternView()
|
||||||
.foregroundStyle(
|
.foregroundStyle(
|
||||||
Color.Card.diamondPattern.opacity(Design.Opacity.light)
|
Color.Card.diamondPattern.opacity(Design.Opacity.light)
|
||||||
)
|
)
|
||||||
.padding(width * 0.12)
|
.padding(width * patternPaddingRatio)
|
||||||
.clipShape(RoundedRectangle(cornerRadius: Design.CornerRadius.small / 2))
|
.clipShape(RoundedRectangle(cornerRadius: Design.CornerRadius.small / 2))
|
||||||
|
|
||||||
// Center emblem
|
// Center emblem
|
||||||
@ -181,14 +199,14 @@ struct CardBackView: View {
|
|||||||
],
|
],
|
||||||
center: .center,
|
center: .center,
|
||||||
startRadius: 0,
|
startRadius: 0,
|
||||||
endRadius: width * 0.15
|
endRadius: width * emblemGradientRatio
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.frame(width: width * 0.3, height: width * 0.3)
|
.frame(width: width * emblemSizeRatio, height: width * emblemSizeRatio)
|
||||||
|
|
||||||
// B for Baccarat
|
// B for Baccarat
|
||||||
Text("B")
|
Text("B")
|
||||||
.font(.system(size: width * 0.18, weight: .bold, design: .serif))
|
.font(.system(size: width * logoFontRatio, weight: .bold, design: .serif))
|
||||||
.foregroundStyle(Color.Card.logoText)
|
.foregroundStyle(Color.Card.logoText)
|
||||||
}
|
}
|
||||||
.frame(width: width, height: height)
|
.frame(width: width, height: height)
|
||||||
|
|||||||
@ -19,6 +19,15 @@ struct ChipView: View {
|
|||||||
self.isSelected = isSelected
|
self.isSelected = isSelected
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Layout Constants
|
||||||
|
|
||||||
|
private let innerCircleRatio: CGFloat = 0.65
|
||||||
|
private let innerGradientRatio: CGFloat = 0.4
|
||||||
|
private let textSizeRatio: CGFloat = 0.25
|
||||||
|
private let selectionGlowPadding: CGFloat = 6
|
||||||
|
private let shadowOffset: CGFloat = 2
|
||||||
|
private let shadowOffsetY: CGFloat = 3
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
ZStack {
|
ZStack {
|
||||||
// Base circle with gradient
|
// Base circle with gradient
|
||||||
@ -28,7 +37,7 @@ struct ChipView: View {
|
|||||||
colors: [
|
colors: [
|
||||||
denomination.secondaryColor,
|
denomination.secondaryColor,
|
||||||
denomination.primaryColor,
|
denomination.primaryColor,
|
||||||
denomination.primaryColor.opacity(0.8)
|
denomination.primaryColor.opacity(Design.Opacity.heavy)
|
||||||
],
|
],
|
||||||
center: .topLeading,
|
center: .topLeading,
|
||||||
startRadius: 0,
|
startRadius: 0,
|
||||||
@ -50,24 +59,24 @@ struct ChipView: View {
|
|||||||
],
|
],
|
||||||
center: .topLeading,
|
center: .topLeading,
|
||||||
startRadius: 0,
|
startRadius: 0,
|
||||||
endRadius: size * 0.4
|
endRadius: size * innerGradientRatio
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.frame(width: size * 0.65, height: size * 0.65)
|
.frame(width: size * innerCircleRatio, height: size * innerCircleRatio)
|
||||||
|
|
||||||
// Inner border
|
// Inner border
|
||||||
Circle()
|
Circle()
|
||||||
.strokeBorder(
|
.strokeBorder(
|
||||||
denomination.stripeColor.opacity(0.8),
|
denomination.stripeColor.opacity(Design.Opacity.heavy),
|
||||||
lineWidth: Design.LineWidth.medium
|
lineWidth: Design.LineWidth.medium
|
||||||
)
|
)
|
||||||
.frame(width: size * 0.65, height: size * 0.65)
|
.frame(width: size * innerCircleRatio, height: size * innerCircleRatio)
|
||||||
|
|
||||||
// Denomination text
|
// Denomination text
|
||||||
Text(denomination.displayText)
|
Text(denomination.displayText)
|
||||||
.font(.system(size: size * 0.25, weight: .heavy, design: .rounded))
|
.font(.system(size: size * textSizeRatio, weight: .heavy, design: .rounded))
|
||||||
.foregroundStyle(denomination.stripeColor)
|
.foregroundStyle(denomination.stripeColor)
|
||||||
.shadow(color: .black.opacity(Design.Opacity.light), radius: 1, x: 1, y: 1)
|
.shadow(color: .black.opacity(Design.Opacity.light), radius: Design.LineWidth.thin, x: 1, y: 1)
|
||||||
|
|
||||||
// Outer border
|
// Outer border
|
||||||
Circle()
|
Circle()
|
||||||
@ -87,13 +96,13 @@ struct ChipView: View {
|
|||||||
if isSelected {
|
if isSelected {
|
||||||
Circle()
|
Circle()
|
||||||
.strokeBorder(Color.yellow, lineWidth: Design.LineWidth.thick)
|
.strokeBorder(Color.yellow, lineWidth: Design.LineWidth.thick)
|
||||||
.frame(width: size + 6, height: size + 6)
|
.frame(width: size + selectionGlowPadding, height: size + selectionGlowPadding)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.frame(width: size, height: size)
|
.frame(width: size, height: size)
|
||||||
.shadow(color: .black.opacity(Design.Opacity.overlay), radius: isSelected ? 8 : 4, x: 2, y: 3)
|
.shadow(color: .black.opacity(Design.Opacity.overlay), radius: isSelected ? Design.Shadow.radiusSmall * 2 : Design.Shadow.radiusSmall, x: shadowOffset, y: shadowOffsetY)
|
||||||
.scaleEffect(isSelected ? 1.1 : 1.0)
|
.scaleEffect(isSelected ? Design.Scale.selected : Design.Scale.normal)
|
||||||
.animation(.spring(duration: 0.2), value: isSelected)
|
.animation(.spring(duration: Design.Animation.selectionDuration), value: isSelected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -267,7 +267,7 @@ struct GameOverView: View {
|
|||||||
)
|
)
|
||||||
.shadow(color: .red.opacity(0.2), radius: Design.Shadow.radiusXXLarge)
|
.shadow(color: .red.opacity(0.2), radius: Design.Shadow.radiusXXLarge)
|
||||||
.padding(.horizontal, Design.Spacing.xxLarge)
|
.padding(.horizontal, Design.Spacing.xxLarge)
|
||||||
.scaleEffect(showContent ? 1.0 : 0.8)
|
.scaleEffect(showContent ? Design.Scale.normal : Design.Scale.slightShrink)
|
||||||
.opacity(showContent ? 1.0 : 0)
|
.opacity(showContent ? 1.0 : 0)
|
||||||
}
|
}
|
||||||
.onAppear {
|
.onAppear {
|
||||||
@ -366,11 +366,13 @@ struct CompactHandView: View {
|
|||||||
// Fixed size: cards have strict visual constraints
|
// Fixed size: cards have strict visual constraints
|
||||||
|
|
||||||
private let cardWidth: CGFloat = 45
|
private let cardWidth: CGFloat = 45
|
||||||
|
private let cardOverlap: CGFloat = -12
|
||||||
|
private let placeholderSpacing: CGFloat = 8
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
HStack(spacing: -12) {
|
HStack(spacing: cards.isEmpty ? placeholderSpacing : cardOverlap) {
|
||||||
if cards.isEmpty {
|
if cards.isEmpty {
|
||||||
// Placeholders
|
// Placeholders - no overlap, just side by side
|
||||||
ForEach(0..<2, id: \.self) { _ in
|
ForEach(0..<2, id: \.self) { _ in
|
||||||
CardPlaceholderView(width: cardWidth)
|
CardPlaceholderView(width: cardWidth)
|
||||||
}
|
}
|
||||||
@ -516,7 +518,7 @@ struct TopBarView: View {
|
|||||||
.contentTransition(.numericText())
|
.contentTransition(.numericText())
|
||||||
.animation(.spring(duration: Design.Animation.quick), value: balance)
|
.animation(.spring(duration: Design.Animation.quick), value: balance)
|
||||||
.lineLimit(1)
|
.lineLimit(1)
|
||||||
.minimumScaleFactor(0.5)
|
.minimumScaleFactor(Design.MinScaleFactor.tight)
|
||||||
}
|
}
|
||||||
.padding(.horizontal, Design.Spacing.medium)
|
.padding(.horizontal, Design.Spacing.medium)
|
||||||
.padding(.vertical, Design.Spacing.xSmall)
|
.padding(.vertical, Design.Spacing.xSmall)
|
||||||
@ -611,7 +613,7 @@ struct ActionButtonsView: View {
|
|||||||
.font(.system(size: statusFontSize, weight: .medium))
|
.font(.system(size: statusFontSize, weight: .medium))
|
||||||
.foregroundStyle(.white.opacity(Design.Opacity.heavy))
|
.foregroundStyle(.white.opacity(Design.Opacity.heavy))
|
||||||
.lineLimit(1)
|
.lineLimit(1)
|
||||||
.minimumScaleFactor(0.7)
|
.minimumScaleFactor(Design.MinScaleFactor.relaxed)
|
||||||
}
|
}
|
||||||
.padding(.horizontal, Design.Spacing.xLarge)
|
.padding(.horizontal, Design.Spacing.xLarge)
|
||||||
.padding(.vertical, Design.Spacing.medium)
|
.padding(.vertical, Design.Spacing.medium)
|
||||||
|
|||||||
@ -70,7 +70,7 @@ struct MiniBaccaratTableView: View {
|
|||||||
.foregroundStyle(.white.opacity(Design.Opacity.medium))
|
.foregroundStyle(.white.opacity(Design.Opacity.medium))
|
||||||
.tracking(1)
|
.tracking(1)
|
||||||
.lineLimit(1)
|
.lineLimit(1)
|
||||||
.minimumScaleFactor(0.6)
|
.minimumScaleFactor(Design.MinScaleFactor.comfortable)
|
||||||
|
|
||||||
ZStack {
|
ZStack {
|
||||||
// Table felt background with arc shape
|
// Table felt background with arc shape
|
||||||
@ -248,13 +248,13 @@ struct TieBettingZone: View {
|
|||||||
.font(.system(size: titleFontSize, weight: .black, design: .rounded))
|
.font(.system(size: titleFontSize, weight: .black, design: .rounded))
|
||||||
.tracking(2)
|
.tracking(2)
|
||||||
.lineLimit(1)
|
.lineLimit(1)
|
||||||
.minimumScaleFactor(0.5)
|
.minimumScaleFactor(Design.MinScaleFactor.tight)
|
||||||
|
|
||||||
Text("PAYS 8 TO 1")
|
Text("PAYS 8 TO 1")
|
||||||
.font(.system(size: subtitleFontSize, weight: .medium))
|
.font(.system(size: subtitleFontSize, weight: .medium))
|
||||||
.opacity(Design.Opacity.heavy)
|
.opacity(Design.Opacity.heavy)
|
||||||
.lineLimit(1)
|
.lineLimit(1)
|
||||||
.minimumScaleFactor(0.5)
|
.minimumScaleFactor(Design.MinScaleFactor.tight)
|
||||||
}
|
}
|
||||||
.foregroundStyle(.white)
|
.foregroundStyle(.white)
|
||||||
}
|
}
|
||||||
@ -338,13 +338,13 @@ struct BankerBettingZone: View {
|
|||||||
.font(.system(size: titleFontSize, weight: .black, design: .rounded))
|
.font(.system(size: titleFontSize, weight: .black, design: .rounded))
|
||||||
.tracking(3)
|
.tracking(3)
|
||||||
.lineLimit(1)
|
.lineLimit(1)
|
||||||
.minimumScaleFactor(0.5)
|
.minimumScaleFactor(Design.MinScaleFactor.tight)
|
||||||
|
|
||||||
Text("PAYS 0.95 TO 1")
|
Text("PAYS 0.95 TO 1")
|
||||||
.font(.system(size: subtitleFontSize, weight: .medium))
|
.font(.system(size: subtitleFontSize, weight: .medium))
|
||||||
.opacity(Design.Opacity.heavy)
|
.opacity(Design.Opacity.heavy)
|
||||||
.lineLimit(1)
|
.lineLimit(1)
|
||||||
.minimumScaleFactor(0.5)
|
.minimumScaleFactor(Design.MinScaleFactor.tight)
|
||||||
}
|
}
|
||||||
.foregroundStyle(.white)
|
.foregroundStyle(.white)
|
||||||
}
|
}
|
||||||
@ -428,13 +428,13 @@ struct PlayerBettingZone: View {
|
|||||||
.font(.system(size: titleFontSize, weight: .black, design: .rounded))
|
.font(.system(size: titleFontSize, weight: .black, design: .rounded))
|
||||||
.tracking(3)
|
.tracking(3)
|
||||||
.lineLimit(1)
|
.lineLimit(1)
|
||||||
.minimumScaleFactor(0.5)
|
.minimumScaleFactor(Design.MinScaleFactor.tight)
|
||||||
|
|
||||||
Text("PAYS 1 TO 1")
|
Text("PAYS 1 TO 1")
|
||||||
.font(.system(size: subtitleFontSize, weight: .medium))
|
.font(.system(size: subtitleFontSize, weight: .medium))
|
||||||
.opacity(Design.Opacity.heavy)
|
.opacity(Design.Opacity.heavy)
|
||||||
.lineLimit(1)
|
.lineLimit(1)
|
||||||
.minimumScaleFactor(0.5)
|
.minimumScaleFactor(Design.MinScaleFactor.tight)
|
||||||
}
|
}
|
||||||
.foregroundStyle(.white)
|
.foregroundStyle(.white)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,8 +41,8 @@ struct ResultBannerView: View {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
.shadow(color: result.color.opacity(Design.Opacity.heavy), radius: Design.Shadow.radiusLarge)
|
.shadow(color: result.color.opacity(Design.Opacity.heavy), radius: Design.Shadow.radiusLarge)
|
||||||
.scaleEffect(showText ? 1.0 : 0.5)
|
.scaleEffect(showText ? Design.Scale.normal : Design.Scale.shrunk)
|
||||||
.opacity(showText ? 1.0 : 0)
|
.opacity(showText ? Design.Scale.normal : 0)
|
||||||
|
|
||||||
// Winnings display
|
// Winnings display
|
||||||
if winnings != 0 {
|
if winnings != 0 {
|
||||||
@ -60,8 +60,8 @@ struct ResultBannerView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.font(.system(size: winningsFontSize, weight: .bold, design: .rounded))
|
.font(.system(size: winningsFontSize, weight: .bold, design: .rounded))
|
||||||
.scaleEffect(showWinnings ? 1.0 : 0.5)
|
.scaleEffect(showWinnings ? Design.Scale.normal : Design.Scale.shrunk)
|
||||||
.opacity(showWinnings ? 1.0 : 0)
|
.opacity(showWinnings ? Design.Scale.normal : 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding(Design.Spacing.xxxLarge + Design.Spacing.small)
|
.padding(Design.Spacing.xxxLarge + Design.Spacing.small)
|
||||||
@ -93,19 +93,19 @@ struct ResultBannerView: View {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
.shadow(color: result.color.opacity(Design.Opacity.light), radius: Design.Shadow.radiusXXLarge)
|
.shadow(color: result.color.opacity(Design.Opacity.light), radius: Design.Shadow.radiusXXLarge)
|
||||||
.scaleEffect(showBanner ? 1.0 : 0.8)
|
.scaleEffect(showBanner ? Design.Scale.normal : Design.Scale.slightShrink)
|
||||||
.opacity(showBanner ? 1.0 : 0)
|
.opacity(showBanner ? Design.Scale.normal : 0)
|
||||||
}
|
}
|
||||||
.onAppear {
|
.onAppear {
|
||||||
withAnimation(.spring(duration: Design.Animation.springDuration, bounce: Design.Animation.springBounce)) {
|
withAnimation(.spring(duration: Design.Animation.springDuration, bounce: Design.Animation.springBounce)) {
|
||||||
showBanner = true
|
showBanner = true
|
||||||
}
|
}
|
||||||
|
|
||||||
withAnimation(.spring(duration: Design.Animation.springDuration, bounce: Design.Animation.springBounce).delay(0.2)) {
|
withAnimation(.spring(duration: Design.Animation.springDuration, bounce: Design.Animation.springBounce).delay(Design.Animation.staggerDelay1)) {
|
||||||
showText = true
|
showText = true
|
||||||
}
|
}
|
||||||
|
|
||||||
withAnimation(.spring(duration: Design.Animation.springDuration, bounce: Design.Animation.springBounce).delay(0.4)) {
|
withAnimation(.spring(duration: Design.Animation.springDuration, bounce: Design.Animation.springBounce).delay(Design.Animation.staggerDelay2)) {
|
||||||
showWinnings = true
|
showWinnings = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -265,7 +265,7 @@ struct SettingsToggle: View {
|
|||||||
Toggle(isOn: $isOn) {
|
Toggle(isOn: $isOn) {
|
||||||
VStack(alignment: .leading, spacing: Design.Spacing.xxSmall) {
|
VStack(alignment: .leading, spacing: Design.Spacing.xxSmall) {
|
||||||
Text(title)
|
Text(title)
|
||||||
.font(.system(size: 15, weight: .medium))
|
.font(.system(size: Design.BaseFontSize.subheadline, weight: .medium))
|
||||||
.foregroundStyle(.white)
|
.foregroundStyle(.white)
|
||||||
|
|
||||||
Text(subtitle)
|
Text(subtitle)
|
||||||
@ -290,7 +290,7 @@ struct SpeedPicker: View {
|
|||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(alignment: .leading, spacing: Design.Spacing.small) {
|
VStack(alignment: .leading, spacing: Design.Spacing.small) {
|
||||||
Text("Dealing Speed")
|
Text("Dealing Speed")
|
||||||
.font(.system(size: 15, weight: .medium))
|
.font(.system(size: Design.BaseFontSize.subheadline, weight: .medium))
|
||||||
.foregroundStyle(.white)
|
.foregroundStyle(.white)
|
||||||
|
|
||||||
HStack(spacing: Design.Spacing.small) {
|
HStack(spacing: Design.Spacing.small) {
|
||||||
@ -299,7 +299,7 @@ struct SpeedPicker: View {
|
|||||||
speed = option.1
|
speed = option.1
|
||||||
} label: {
|
} label: {
|
||||||
Text(option.0)
|
Text(option.0)
|
||||||
.font(.system(size: 13, weight: .medium))
|
.font(.system(size: Design.BaseFontSize.callout, weight: .medium))
|
||||||
.foregroundStyle(speed == option.1 ? .black : .white.opacity(Design.Opacity.strong))
|
.foregroundStyle(speed == option.1 ? .black : .white.opacity(Design.Opacity.strong))
|
||||||
.padding(.vertical, Design.Spacing.small)
|
.padding(.vertical, Design.Spacing.small)
|
||||||
.frame(maxWidth: .infinity)
|
.frame(maxWidth: .infinity)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user