// // BlockView.swift // SwiftUI2048 // // Created by Hongyu on 6/5/19. // Copyright © 2019 Cyandev. All rights reserved. // import SwiftUI struct BlockView : View { fileprivate let colorScheme: [(Color, Color)] = [ // 2 (Color(red:0.91, green:0.87, blue:0.83, opacity:1.00), Color(red:0.42, green:0.39, blue:0.35, opacity:1.00)), // 4 (Color(red:0.90, green:0.86, blue:0.76, opacity:1.00), Color(red:0.42, green:0.39, blue:0.35, opacity:1.00)), // 8 (Color(red:0.93, green:0.67, blue:0.46, opacity:1.00), Color.white), // 16 (Color(red:0.94, green:0.57, blue:0.38, opacity:1.00), Color.white), // 32 (Color(red:0.95, green:0.46, blue:0.33, opacity:1.00), Color.white), // 64 (Color(red:0.94, green:0.35, blue:0.23, opacity:1.00), Color.white), // 128 (Color(red:0.91, green:0.78, blue:0.43, opacity:1.00), Color.white), // 256 (Color(red:0.91, green:0.78, blue:0.37, opacity:1.00), Color.white), // 512 (Color(red:0.90, green:0.77, blue:0.31, opacity:1.00), Color.white), // 1024 (Color(red:0.91, green:0.75, blue:0.24, opacity:1.00), Color.white), // 2048 (Color(red:0.91, green:0.74, blue:0.18, opacity:1.00), Color.white), ] fileprivate let number: Int? init(number: Int) { self.number = number } fileprivate init() { self.number = nil } static func blank() -> Self { return self.init() } fileprivate var numberText: String { guard let number = number else { return "" } return String(number) } fileprivate var fontSize: CGFloat { let textLength = numberText.count if textLength < 3 { return 32 } else if textLength < 4 { return 18 } else { return 12 } } fileprivate var colorPair: (Color, Color) { guard let number = number else { return (Color(red:0.78, green:0.73, blue:0.68, opacity:1.00), Color.black) } let index = Int(log2(Double(number))) - 1 if index < 0 || index >= colorScheme.count { fatalError("No color for such number") } return colorScheme[index] } // MARK: Body var body: some View { ZStack { Rectangle().fill(colorPair.0) Text(numberText) .font(Font.system(size: fontSize).bold()) .color(colorPair.1) .id(numberText) .transition(AnyTransition.scale(scale: 0.5, anchor: .center).combined(with: .opacity)) .animation(.fluidSpring()) } .clipped() .cornerRadius(6) } } // MARK: - Previews #if DEBUG struct BlockView_Previews : PreviewProvider { static var previews: some View { Group { ForEach((1...11).map { Int(pow(2, Double($0))) }) { i in BlockView(number: i) .previewLayout(.sizeThatFits) } BlockView.blank() .previewLayout(.sizeThatFits) } } } #endif