Skip to content

Instantly share code, notes, and snippets.

@mao-test-h
Created July 19, 2020 22:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mao-test-h/07cf0f9014e7d213938ce18c22f4b195 to your computer and use it in GitHub Desktop.
Save mao-test-h/07cf0f9014e7d213938ce18c22f4b195 to your computer and use it in GitHub Desktop.
ファイナルソードの「LEVEL Up」演出っぽい挙動をSwiftUIで再現
import SwiftUI
struct ContentView: View {
// Font
let fontSize: CGFloat = 90
// Animation
let startScale: CGFloat = 0.3
let endScale: CGFloat = 1.0
let scaleAnimDuration = 0.3
@State private var showingToggle = false
@State private var currentScale: CGFloat = 0
init() {
currentScale = startScale
}
var body: some View {
VStack(alignment: .center, spacing: 0) {
// レベルアップ表示用のトグル
Toggle(isOn: $showingToggle) {
Text("レベルアップする")
}
Spacer()
// デッデレー♪
if (showingToggle) {
LevelUpView(fontSize: fontSize)
.scaleEffect(currentScale)
.animation(.easeIn(duration: scaleAnimDuration))
.onAppear() {
self.currentScale = self.endScale
}
.onDisappear() {
self.currentScale = self.startScale
}
}
Spacer()
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
// MARK:- UIパーツ
/// 「LEVEL Up」表示用
private struct LevelUpView: View {
// グラデーション
let gradientTop = Color(red: 217.1 / 255.0, green: 190.7 / 255.0, blue: 69.9 / 255.0)
let gradientBottom = Color(red: 193.5 / 255.0, green: 49.5 / 255.0, blue: 22.7 / 255.0)
// Font
let defaultFontSize: CGFloat
let minFontSize: CGFloat
let shadowRadius: CGFloat
let shadowOffset: CGFloat
init(fontSize size: CGFloat, shadowRadius rad: CGFloat = 1, shadowOffset offset: CGFloat = 3) {
defaultFontSize = size
// NOTE: 「LEVEL」の頭文字以外の文字サイズは少し小さめなので、これくらいの倍率で減らしておく
minFontSize = defaultFontSize * 0.83;
shadowRadius = rad
shadowOffset = offset
}
var body: some View {
// "L" + "EVEL" + " Up"を下揃えで並べていく
HStack(alignment: .bottom, spacing: CGFloat(0)) {
Text("L")
.font(.system(size: defaultFontSize, weight: .black, design: .default))
.foregroundColor(makeGradient())
.shadow(
color: gradientTop,
radius: shadowRadius, x: shadowOffset, y: shadowOffset)
Text("EVEL")
.font(.system(size: minFontSize, weight: .black, design: .default))
.foregroundColor(makeGradient())
.offset(x: 0, y: shadowOffset * -1)
.shadow(
color: gradientTop,
radius: shadowRadius, x: shadowOffset, y: shadowOffset)
Text(" Up")
.font(.system(size: defaultFontSize, weight: .black, design: .default))
.foregroundColor(makeGradient())
.shadow(
color: gradientTop,
radius: shadowRadius, x: shadowOffset, y: shadowOffset)
}
}
func makeGradient() -> some View {
LinearGradient(
gradient: Gradient(stops: [
.init(color: gradientTop, location: 0.4),
.init(color: gradientBottom, location: 1.0)
]),
startPoint: .top,
endPoint: .bottom)
}
}
// MARK:- Extensions
// グラデーション用
// ref: https://stackoverflow.com/questions/58991311/gradient-as-foreground-color-of-text-in-swiftui
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
fileprivate extension View {
func foregroundColor<Overlay: View>(_ overlay: Overlay) -> some View {
self.overlay(overlay).mask(self)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment