LoginSignup
9
3

【SwiftUI】力技でTo Be Continued作った

Last updated at Posted at 2023-12-11

この記事はDeNA 24 新卒 Advent Calendar 2023の11日目の記事です。

はじめに

画像など使わず完全にSwiftUIのみでTo Be Continuedを再現します。

サンプルアプリ

Simulator Screen Recording - iPhone 15 - 2023-12-11 at 18.55.40.gif

使用するフォント

それっぽいGoogleFontにあったのでそちらを使用します

実装

まずは死ぬ気でToBeContinuedViewを作ります

import SwiftUI

struct ToBeContinuedView: Shape {
    func path(in rect: CGRect) -> Path {
        var path = Path()
        let width = rect.size.width
        let height = rect.size.height
        path.move(to: CGPoint(x: 0.12117*width, y: 0.24103*height))
        path.addCurve(to: CGPoint(x: 0.12175*width, y: 0.24662*height), control1: CGPoint(x: 0.12119*width, y: 0.24316*height), control2: CGPoint(x: 0.1214*width, y: 0.24516*height))
        path.addCurve(to: CGPoint(x: 0.12303*width, y: 0.24882*height), control1: CGPoint(x: 0.1221*width, y: 0.24807*height), control2: CGPoint(x: 0.12256*width, y: 0.24886*height))
        path.addLine(to: CGPoint(x: 0.37395*width, y: 0.24794*height))
        path.addCurve(to: CGPoint(x: 0.79457*width, y: 0.25015*height), control1: CGPoint(x: 0.51208*width, y: 0.24833*height), control2: CGPoint(x: 0.65868*width, y: 0.25044*height))
        path.addCurve(to: CGPoint(x: 0.8072*width, y: 0.2675*height), control1: CGPoint(x: 0.79886*width, y: 0.25015*height), control2: CGPoint(x: 0.80307*width, y: 0.25593*height))
        path.addCurve(to: CGPoint(x: 0.80887*width, y: 0.27882*height), control1: CGPoint(x: 0.80816*width, y: 0.27015*height), control2: CGPoint(x: 0.80871*width, y: 0.27392*height))
        path.addCurve(to: CGPoint(x: 0.81*width, y: 0.34588*height), control1: CGPoint(x: 0.80953*width, y: 0.30127*height), control2: CGPoint(x: 0.80991*width, y: 0.32363*height))
        path.addCurve(to: CGPoint(x: 0.81013*width, y: 0.71603*height), control1: CGPoint(x: 0.8104*width, y: 0.47206*height), control2: CGPoint(x: 0.81044*width, y: 0.59544*height))
        path.addCurve(to: CGPoint(x: 0.7973*width, y: 0.77309*height), control1: CGPoint(x: 0.81002*width, y: 0.75338*height), control2: CGPoint(x: 0.80574*width, y: 0.7724*height))
        path.addCurve(to: CGPoint(x: 0.75103*width, y: 0.77294*height), control1: CGPoint(x: 0.78194*width, y: 0.77446*height), control2: CGPoint(x: 0.76652*width, y: 0.77441*height))
        path.addCurve(to: CGPoint(x: 0.73117*width, y: 0.79103*height), control1: CGPoint(x: 0.74363*width, y: 0.77235*height), control2: CGPoint(x: 0.73843*width, y: 0.79103*height))
        path.addCurve(to: CGPoint(x: 0.1625*width, y: 0.79118*height), control1: CGPoint(x: 0.54161*width, y: 0.79083*height), control2: CGPoint(x: 0.35206*width, y: 0.79088*height))
        path.addCurve(to: CGPoint(x: 0.1235*width, y: 0.79279*height), control1: CGPoint(x: 0.14986*width, y: 0.79127*height), control2: CGPoint(x: 0.13686*width, y: 0.79181*height))
        path.addCurve(to: CGPoint(x: 0.1208*width, y: 0.80485*height), control1: CGPoint(x: 0.1217*width, y: 0.79289*height), control2: CGPoint(x: 0.1208*width, y: 0.79691*height))
        path.addLine(to: CGPoint(x: 0.12087*width, y: 0.98118*height))
        path.addCurve(to: CGPoint(x: 0.11867*width, y: 0.98765*height), control1: CGPoint(x: 0.12087*width, y: 0.98814*height), control2: CGPoint(x: 0.12013*width, y: 0.99029*height))
        path.addCurve(to: CGPoint(x: 0.11123*width, y: 0.98103*height), control1: CGPoint(x: 0.11627*width, y: 0.98324*height), control2: CGPoint(x: 0.11379*width, y: 0.98103*height))
        path.addCurve(to: CGPoint(x: 0.10733*width, y: 0.97515*height), control1: CGPoint(x: 0.10977*width, y: 0.98103*height), control2: CGPoint(x: 0.10847*width, y: 0.97907*height))
        path.addCurve(to: CGPoint(x: 0.08857*width, y: 0.90529*height), control1: CGPoint(x: 0.10077*width, y: 0.95294*height), control2: CGPoint(x: 0.0943*width, y: 0.93147*height))
        path.addCurve(to: CGPoint(x: 0.04327*width, y: 0.70338*height), control1: CGPoint(x: 0.07366*width, y: 0.83706*height), control2: CGPoint(x: 0.05856*width, y: 0.76975*height))
        path.addCurve(to: CGPoint(x: 0.0048*width, y: 0.55059*height), control1: CGPoint(x: 0.03113*width, y: 0.65074*height), control2: CGPoint(x: 0.01643*width, y: 0.60882*height))
        path.addCurve(to: CGPoint(x: 0.003*width, y: 0.50382*height), control1: CGPoint(x: 0.00198*width, y: 0.53637*height), control2: CGPoint(x: 0.00138*width, y: 0.52078*height))
        path.addCurve(to: CGPoint(x: 0.0124*width, y: 0.43985*height), control1: CGPoint(x: 0.00507*width, y: 0.48196*height), control2: CGPoint(x: 0.0082*width, y: 0.46064*height))
        path.addCurve(to: CGPoint(x: 0.02507*width, y: 0.38926*height), control1: CGPoint(x: 0.01618*width, y: 0.42123*height), control2: CGPoint(x: 0.0204*width, y: 0.40436*height))
        path.addCurve(to: CGPoint(x: 0.05333*width, y: 0.27176*height), control1: CGPoint(x: 0.03493*width, y: 0.3573*height), control2: CGPoint(x: 0.04436*width, y: 0.31814*height))
        path.addCurve(to: CGPoint(x: 0.0723*width, y: 0.18235*height), control1: CGPoint(x: 0.0594*width, y: 0.24044*height), control2: CGPoint(x: 0.06627*width, y: 0.21382*height))
        path.addCurve(to: CGPoint(x: 0.0858*width, y: 0.13162*height), control1: CGPoint(x: 0.07617*width, y: 0.16191*height), control2: CGPoint(x: 0.08143*width, y: 0.15059*height))
        path.addCurve(to: CGPoint(x: 0.10523*width, y: 0.03*height), control1: CGPoint(x: 0.09313*width, y: 0.09975*height), control2: CGPoint(x: 0.09961*width, y: 0.06588*height))
        path.addCurve(to: CGPoint(x: 0.11667*width, y: 0.00735*height), control1: CGPoint(x: 0.10766*width, y: 0.01451*height), control2: CGPoint(x: 0.11333*width, y: 0.00735*height))
        path.addCurve(to: CGPoint(x: 0.11833*width, y: 0.00735*height), control1: CGPoint(x: 0.11833*width, y: 0.00735*height), control2: CGPoint(x: 0.11767*width, y: 0.00725*height))
        path.addCurve(to: CGPoint(x: 0.1224*width, y: 0.03456*height), control1: CGPoint(x: 0.12169*width, y: 0.00794*height), control2: CGPoint(x: 0.12271*width, y: 0.02034*height))
        path.addCurve(to: CGPoint(x: 0.12117*width, y: 0.24103*height), control1: CGPoint(x: 0.12093*width, y: 0.10603*height), control2: CGPoint(x: 0.12052*width, y: 0.17485*height))
        path.closeSubpath()
        path.move(to: CGPoint(x: 0.8675*width, y: 0.44324*height))
        path.addCurve(to: CGPoint(x: 0.85973*width, y: 0.36221*height), control1: CGPoint(x: 0.86477*width, y: 0.41735*height), control2: CGPoint(x: 0.86218*width, y: 0.39034*height))
        path.addCurve(to: CGPoint(x: 0.85577*width, y: 0.33147*height), control1: CGPoint(x: 0.8588*width, y: 0.35142*height), control2: CGPoint(x: 0.85748*width, y: 0.34118*height))
        path.addCurve(to: CGPoint(x: 0.85201*width, y: 0.29855*height), control1: CGPoint(x: 0.85393*width, y: 0.32108*height), control2: CGPoint(x: 0.85298*width, y: 0.30987*height))
        path.addCurve(to: CGPoint(x: 0.8472*width, y: 0.25971*height), control1: CGPoint(x: 0.85088*width, y: 0.28537*height), control2: CGPoint(x: 0.84975*width, y: 0.27205*height))
        path.addCurve(to: CGPoint(x: 0.84661*width, y: 0.25517*height), control1: CGPoint(x: 0.84693*width, y: 0.2584*height), control2: CGPoint(x: 0.84673*width, y: 0.25686*height))
        path.addCurve(to: CGPoint(x: 0.84652*width, y: 0.24996*height), control1: CGPoint(x: 0.8465*width, y: 0.25349*height), control2: CGPoint(x: 0.84646*width, y: 0.25171*height))
        path.addCurve(to: CGPoint(x: 0.84694*width, y: 0.24508*height), control1: CGPoint(x: 0.84658*width, y: 0.24822*height), control2: CGPoint(x: 0.84672*width, y: 0.24655*height))
        path.addCurve(to: CGPoint(x: 0.8478*width, y: 0.24147*height), control1: CGPoint(x: 0.84717*width, y: 0.24361*height), control2: CGPoint(x: 0.84746*width, y: 0.24238*height))
        path.addCurve(to: CGPoint(x: 0.85083*width, y: 0.23779*height), control1: CGPoint(x: 0.84873*width, y: 0.23912*height), control2: CGPoint(x: 0.84974*width, y: 0.23789*height))
        path.addCurve(to: CGPoint(x: 0.91567*width, y: 0.24941*height), control1: CGPoint(x: 0.87397*width, y: 0.23711*height), control2: CGPoint(x: 0.89558*width, y: 0.24098*height))
        path.addCurve(to: CGPoint(x: 0.91743*width, y: 0.25706*height), control1: CGPoint(x: 0.91673*width, y: 0.2499*height), control2: CGPoint(x: 0.91732*width, y: 0.25245*height))
        path.addCurve(to: CGPoint(x: 0.9177*width, y: 0.30838*height), control1: CGPoint(x: 0.91781*width, y: 0.27343*height), control2: CGPoint(x: 0.9179*width, y: 0.29054*height))
        path.addCurve(to: CGPoint(x: 0.91843*width, y: 0.63412*height), control1: CGPoint(x: 0.91654*width, y: 0.41426*height), control2: CGPoint(x: 0.91679*width, y: 0.52284*height))
        path.addCurve(to: CGPoint(x: 0.91667*width, y: 0.66676*height), control1: CGPoint(x: 0.91861*width, y: 0.64578*height), control2: CGPoint(x: 0.91802*width, y: 0.65667*height))
        path.addCurve(to: CGPoint(x: 0.9158*width, y: 0.68044*height), control1: CGPoint(x: 0.91611*width, y: 0.67098*height), control2: CGPoint(x: 0.91582*width, y: 0.67554*height))
        path.addLine(to: CGPoint(x: 0.91517*width, y: 0.75588*height))
        path.addCurve(to: CGPoint(x: 0.91462*width, y: 0.76491*height), control1: CGPoint(x: 0.91514*width, y: 0.75904*height), control2: CGPoint(x: 0.91496*width, y: 0.76213*height))
        path.addCurve(to: CGPoint(x: 0.91321*width, y: 0.77191*height), control1: CGPoint(x: 0.91428*width, y: 0.76769*height), control2: CGPoint(x: 0.9138*width, y: 0.77009*height))
        path.addCurve(to: CGPoint(x: 0.91125*width, y: 0.77542*height), control1: CGPoint(x: 0.91263*width, y: 0.77374*height), control2: CGPoint(x: 0.91195*width, y: 0.77494*height))
        path.addCurve(to: CGPoint(x: 0.90913*width, y: 0.77471*height), control1: CGPoint(x: 0.91054*width, y: 0.77591*height), control2: CGPoint(x: 0.90982*width, y: 0.77566*height))
        path.addCurve(to: CGPoint(x: 0.90343*width, y: 0.75044*height), control1: CGPoint(x: 0.90636*width, y: 0.77088*height), control2: CGPoint(x: 0.90446*width, y: 0.76279*height))
        path.addCurve(to: CGPoint(x: 0.89337*width, y: 0.66365*height), control1: CGPoint(x: 0.90086*width, y: 0.71894*height), control2: CGPoint(x: 0.8971*width, y: 0.69117*height))
        path.addCurve(to: CGPoint(x: 0.88533*width, y: 0.59853*height), control1: CGPoint(x: 0.89048*width, y: 0.64234*height), control2: CGPoint(x: 0.88762*width, y: 0.62118*height))
        path.addCurve(to: CGPoint(x: 0.87697*width, y: 0.51265*height), control1: CGPoint(x: 0.88249*width, y: 0.57039*height), control2: CGPoint(x: 0.8797*width, y: 0.54176*height))
        path.addCurve(to: CGPoint(x: 0.87207*width, y: 0.47608*height), control1: CGPoint(x: 0.87572*width, y: 0.49921*height), control2: CGPoint(x: 0.8739*width, y: 0.4877*height))
        path.addCurve(to: CGPoint(x: 0.8675*width, y: 0.44324*height), control1: CGPoint(x: 0.87043*width, y: 0.4657*height), control2: CGPoint(x: 0.86877*width, y: 0.45524*height))
        path.closeSubpath()
        path.move(to: CGPoint(x: 0.8675*width, y: 0.44324*height))
        path.addCurve(to: CGPoint(x: 0.85973*width, y: 0.36221*height), control1: CGPoint(x: 0.86477*width, y: 0.41735*height), control2: CGPoint(x: 0.86218*width, y: 0.39034*height))
        path.addCurve(to: CGPoint(x: 0.85577*width, y: 0.33147*height), control1: CGPoint(x: 0.8588*width, y: 0.35142*height), control2: CGPoint(x: 0.85748*width, y: 0.34118*height))
        path.addCurve(to: CGPoint(x: 0.85201*width, y: 0.29855*height), control1: CGPoint(x: 0.85393*width, y: 0.32108*height), control2: CGPoint(x: 0.85298*width, y: 0.30987*height))
        path.addCurve(to: CGPoint(x: 0.8472*width, y: 0.25971*height), control1: CGPoint(x: 0.85088*width, y: 0.28537*height), control2: CGPoint(x: 0.84975*width, y: 0.27205*height))
        path.addCurve(to: CGPoint(x: 0.84661*width, y: 0.25517*height), control1: CGPoint(x: 0.84693*width, y: 0.2584*height), control2: CGPoint(x: 0.84673*width, y: 0.25686*height))
        path.addCurve(to: CGPoint(x: 0.84652*width, y: 0.24996*height), control1: CGPoint(x: 0.8465*width, y: 0.25349*height), control2: CGPoint(x: 0.84646*width, y: 0.25171*height))
        path.addCurve(to: CGPoint(x: 0.84694*width, y: 0.24508*height), control1: CGPoint(x: 0.84658*width, y: 0.24822*height), control2: CGPoint(x: 0.84672*width, y: 0.24655*height))
        path.addCurve(to: CGPoint(x: 0.8478*width, y: 0.24147*height), control1: CGPoint(x: 0.84717*width, y: 0.24361*height), control2: CGPoint(x: 0.84746*width, y: 0.24238*height))
        path.addCurve(to: CGPoint(x: 0.85083*width, y: 0.23779*height), control1: CGPoint(x: 0.84873*width, y: 0.23912*height), control2: CGPoint(x: 0.84974*width, y: 0.23789*height))
        path.addCurve(to: CGPoint(x: 0.91567*width, y: 0.24941*height), control1: CGPoint(x: 0.87397*width, y: 0.23711*height), control2: CGPoint(x: 0.89558*width, y: 0.24098*height))
        path.addCurve(to: CGPoint(x: 0.91743*width, y: 0.25706*height), control1: CGPoint(x: 0.91673*width, y: 0.2499*height), control2: CGPoint(x: 0.91732*width, y: 0.25245*height))
        path.addCurve(to: CGPoint(x: 0.9177*width, y: 0.30838*height), control1: CGPoint(x: 0.91781*width, y: 0.27343*height), control2: CGPoint(x: 0.9179*width, y: 0.29054*height))
        path.addCurve(to: CGPoint(x: 0.91843*width, y: 0.63412*height), control1: CGPoint(x: 0.91654*width, y: 0.41426*height), control2: CGPoint(x: 0.91679*width, y: 0.52284*height))
        path.addCurve(to: CGPoint(x: 0.91667*width, y: 0.66676*height), control1: CGPoint(x: 0.91861*width, y: 0.64578*height), control2: CGPoint(x: 0.91802*width, y: 0.65667*height))
        path.addCurve(to: CGPoint(x: 0.9158*width, y: 0.68044*height), control1: CGPoint(x: 0.91611*width, y: 0.67098*height), control2: CGPoint(x: 0.91582*width, y: 0.67554*height))
        path.addLine(to: CGPoint(x: 0.91517*width, y: 0.75588*height))
        path.addCurve(to: CGPoint(x: 0.91462*width, y: 0.76491*height), control1: CGPoint(x: 0.91514*width, y: 0.75904*height), control2: CGPoint(x: 0.91496*width, y: 0.76213*height))
        path.addCurve(to: CGPoint(x: 0.91321*width, y: 0.77191*height), control1: CGPoint(x: 0.91428*width, y: 0.76769*height), control2: CGPoint(x: 0.9138*width, y: 0.77009*height))
        path.addCurve(to: CGPoint(x: 0.91125*width, y: 0.77542*height), control1: CGPoint(x: 0.91263*width, y: 0.77374*height), control2: CGPoint(x: 0.91195*width, y: 0.77494*height))
        path.addCurve(to: CGPoint(x: 0.90913*width, y: 0.77471*height), control1: CGPoint(x: 0.91054*width, y: 0.77591*height), control2: CGPoint(x: 0.90982*width, y: 0.77566*height))
        path.addCurve(to: CGPoint(x: 0.90343*width, y: 0.75044*height), control1: CGPoint(x: 0.90636*width, y: 0.77088*height), control2: CGPoint(x: 0.90446*width, y: 0.76279*height))
        path.addCurve(to: CGPoint(x: 0.89337*width, y: 0.66365*height), control1: CGPoint(x: 0.90086*width, y: 0.71894*height), control2: CGPoint(x: 0.8971*width, y: 0.69117*height))
        path.addCurve(to: CGPoint(x: 0.88533*width, y: 0.59853*height), control1: CGPoint(x: 0.89048*width, y: 0.64234*height), control2: CGPoint(x: 0.88762*width, y: 0.62118*height))
        path.addCurve(to: CGPoint(x: 0.87697*width, y: 0.51265*height), control1: CGPoint(x: 0.88249*width, y: 0.57039*height), control2: CGPoint(x: 0.8797*width, y: 0.54176*height))
        path.addCurve(to: CGPoint(x: 0.87207*width, y: 0.47608*height), control1: CGPoint(x: 0.87572*width, y: 0.49921*height), control2: CGPoint(x: 0.8739*width, y: 0.4877*height))
        path.addCurve(to: CGPoint(x: 0.8675*width, y: 0.44324*height), control1: CGPoint(x: 0.87043*width, y: 0.4657*height), control2: CGPoint(x: 0.86877*width, y: 0.45524*height))
        path.closeSubpath()
        path.move(to: CGPoint(x: 0.99833*width, y: 0.27397*height))
        path.addLine(to: CGPoint(x: 0.99833*width, y: 0.28324*height))
        path.addCurve(to: CGPoint(x: 0.9912*width, y: 0.34412*height), control1: CGPoint(x: 0.99511*width, y: 0.30098*height), control2: CGPoint(x: 0.99273*width, y: 0.32127*height))
        path.addCurve(to: CGPoint(x: 0.98953*width, y: 0.35838*height), control1: CGPoint(x: 0.9909*width, y: 0.34872*height), control2: CGPoint(x: 0.99036*width, y: 0.35531*height))
        path.addCurve(to: CGPoint(x: 0.9862*width, y: 0.38044*height), control1: CGPoint(x: 0.98673*width, y: 0.36887*height), control2: CGPoint(x: 0.9862*width, y: 0.38044*height))
        path.addLine(to: CGPoint(x: 0.98333*width, y: 0.40441*height))
        path.addLine(to: CGPoint(x: 0.9812*width, y: 0.42456*height))
        path.addLine(to: CGPoint(x: 0.97787*width, y: 0.45397*height))
        path.addCurve(to: CGPoint(x: 0.96667*width, y: 0.53676*height), control1: CGPoint(x: 0.97787*width, y: 0.45397*height), control2: CGPoint(x: 0.9762*width, y: 0.49074*height))
        path.addCurve(to: CGPoint(x: 0.96*width, y: 0.58824*height), control1: CGPoint(x: 0.96667*width, y: 0.53676*height), control2: CGPoint(x: 0.96151*width, y: 0.57765*height))
        path.addCurve(to: CGPoint(x: 0.95667*width, y: 0.625*height), control1: CGPoint(x: 0.95849*width, y: 0.59882*height), control2: CGPoint(x: 0.95667*width, y: 0.625*height))
        path.addLine(to: CGPoint(x: 0.95437*width, y: 0.64706*height))
        path.addLine(to: CGPoint(x: 0.95433*width, y: 0.65125*height))
        path.addLine(to: CGPoint(x: 0.95386*width, y: 0.65865*height))
        path.addLine(to: CGPoint(x: 0.95167*width, y: 0.66926*height))
        path.addCurve(to: CGPoint(x: 0.94833*width, y: 0.69853*height), control1: CGPoint(x: 0.95167*width, y: 0.66934*height), control2: CGPoint(x: 0.94835*width, y: 0.69847*height))
        path.addCurve(to: CGPoint(x: 0.94643*width, y: 0.71801*height), control1: CGPoint(x: 0.94704*width, y: 0.70995*height), control2: CGPoint(x: 0.94668*width, y: 0.71471*height))
        path.addCurve(to: CGPoint(x: 0.94287*width, y: 0.74279*height), control1: CGPoint(x: 0.94604*width, y: 0.72319*height), control2: CGPoint(x: 0.94593*width, y: 0.72471*height))
        path.addCurve(to: CGPoint(x: 0.9406*width, y: 0.7575*height), control1: CGPoint(x: 0.94267*width, y: 0.74544*height), control2: CGPoint(x: 0.94107*width, y: 0.75642*height))
        path.addCurve(to: CGPoint(x: 0.9362*width, y: 0.75015*height), control1: CGPoint(x: 0.93953*width, y: 0.76005*height), control2: CGPoint(x: 0.9362*width, y: 0.7575*height))
        path.addCurve(to: CGPoint(x: 0.93616*width, y: 0.69137*height), control1: CGPoint(x: 0.93518*width, y: 0.73221*height), control2: CGPoint(x: 0.93568*width, y: 0.71149*height))
        path.addCurve(to: CGPoint(x: 0.93667*width, y: 0.65441*height), control1: CGPoint(x: 0.93647*width, y: 0.67851*height), control2: CGPoint(x: 0.93677*width, y: 0.66589*height))
        path.addCurve(to: CGPoint(x: 0.93667*width, y: 0.58088*height), control1: CGPoint(x: 0.93562*width, y: 0.61441*height), control2: CGPoint(x: 0.93667*width, y: 0.58088*height))
        path.addCurve(to: CGPoint(x: 0.93741*width, y: 0.3272*height), control1: CGPoint(x: 0.93562*width, y: 0.48901*height), control2: CGPoint(x: 0.9365*width, y: 0.40992*height))
        path.addCurve(to: CGPoint(x: 0.93787*width, y: 0.285*height), control1: CGPoint(x: 0.93756*width, y: 0.31326*height), control2: CGPoint(x: 0.93772*width, y: 0.29922*height))
        path.addCurve(to: CGPoint(x: 0.941*width, y: 0.27206*height), control1: CGPoint(x: 0.93796*width, y: 0.27627*height), control2: CGPoint(x: 0.939*width, y: 0.27196*height))
        path.addLine(to: CGPoint(x: 0.99833*width, y: 0.27397*height))
        path.closeSubpath()
        path.move(to: CGPoint(x: 0.99833*width, y: 0.27397*height))
        path.addLine(to: CGPoint(x: 0.99833*width, y: 0.28324*height))
        path.addCurve(to: CGPoint(x: 0.9912*width, y: 0.34412*height), control1: CGPoint(x: 0.99511*width, y: 0.30098*height), control2: CGPoint(x: 0.99273*width, y: 0.32127*height))
        path.addCurve(to: CGPoint(x: 0.98953*width, y: 0.35838*height), control1: CGPoint(x: 0.9909*width, y: 0.34872*height), control2: CGPoint(x: 0.99036*width, y: 0.35531*height))
        path.addCurve(to: CGPoint(x: 0.9862*width, y: 0.38044*height), control1: CGPoint(x: 0.98673*width, y: 0.36887*height), control2: CGPoint(x: 0.9862*width, y: 0.38044*height))
        path.addLine(to: CGPoint(x: 0.98333*width, y: 0.40441*height))
        path.addLine(to: CGPoint(x: 0.9812*width, y: 0.42456*height))
        path.addLine(to: CGPoint(x: 0.97787*width, y: 0.45397*height))
        path.addCurve(to: CGPoint(x: 0.96667*width, y: 0.53676*height), control1: CGPoint(x: 0.97787*width, y: 0.45397*height), control2: CGPoint(x: 0.9762*width, y: 0.49074*height))
        path.addCurve(to: CGPoint(x: 0.96*width, y: 0.58824*height), control1: CGPoint(x: 0.96667*width, y: 0.53676*height), control2: CGPoint(x: 0.96151*width, y: 0.57765*height))
        path.addCurve(to: CGPoint(x: 0.95667*width, y: 0.625*height), control1: CGPoint(x: 0.95849*width, y: 0.59882*height), control2: CGPoint(x: 0.95667*width, y: 0.625*height))
        path.addLine(to: CGPoint(x: 0.95437*width, y: 0.64706*height))
        path.addLine(to: CGPoint(x: 0.95433*width, y: 0.65125*height))
        path.addLine(to: CGPoint(x: 0.95386*width, y: 0.65865*height))
        path.addLine(to: CGPoint(x: 0.95167*width, y: 0.66926*height))
        path.addCurve(to: CGPoint(x: 0.94833*width, y: 0.69853*height), control1: CGPoint(x: 0.95167*width, y: 0.66934*height), control2: CGPoint(x: 0.94835*width, y: 0.69847*height))
        path.addCurve(to: CGPoint(x: 0.94643*width, y: 0.71801*height), control1: CGPoint(x: 0.94704*width, y: 0.70995*height), control2: CGPoint(x: 0.94668*width, y: 0.71471*height))
        path.addCurve(to: CGPoint(x: 0.94287*width, y: 0.74279*height), control1: CGPoint(x: 0.94604*width, y: 0.72319*height), control2: CGPoint(x: 0.94593*width, y: 0.72471*height))
        path.addCurve(to: CGPoint(x: 0.9406*width, y: 0.7575*height), control1: CGPoint(x: 0.94267*width, y: 0.74544*height), control2: CGPoint(x: 0.94107*width, y: 0.75642*height))
        path.addCurve(to: CGPoint(x: 0.9362*width, y: 0.75015*height), control1: CGPoint(x: 0.93953*width, y: 0.76005*height), control2: CGPoint(x: 0.9362*width, y: 0.7575*height))
        path.addCurve(to: CGPoint(x: 0.93616*width, y: 0.69137*height), control1: CGPoint(x: 0.93518*width, y: 0.73221*height), control2: CGPoint(x: 0.93568*width, y: 0.71149*height))
        path.addCurve(to: CGPoint(x: 0.93667*width, y: 0.65441*height), control1: CGPoint(x: 0.93647*width, y: 0.67851*height), control2: CGPoint(x: 0.93677*width, y: 0.66589*height))
        path.addCurve(to: CGPoint(x: 0.93667*width, y: 0.58088*height), control1: CGPoint(x: 0.93562*width, y: 0.61441*height), control2: CGPoint(x: 0.93667*width, y: 0.58088*height))
        path.addCurve(to: CGPoint(x: 0.93741*width, y: 0.3272*height), control1: CGPoint(x: 0.93562*width, y: 0.48901*height), control2: CGPoint(x: 0.9365*width, y: 0.40992*height))
        path.addCurve(to: CGPoint(x: 0.93787*width, y: 0.285*height), control1: CGPoint(x: 0.93756*width, y: 0.31326*height), control2: CGPoint(x: 0.93772*width, y: 0.29922*height))
        path.addCurve(to: CGPoint(x: 0.941*width, y: 0.27206*height), control1: CGPoint(x: 0.93796*width, y: 0.27627*height), control2: CGPoint(x: 0.939*width, y: 0.27196*height))
        path.addLine(to: CGPoint(x: 0.99833*width, y: 0.27397*height))
        path.closeSubpath()
        path.move(to: CGPoint(x: 0.8213*width, y: 0.64544*height))
        path.addCurve(to: CGPoint(x: 0.82347*width, y: 0.51279*height), control1: CGPoint(x: 0.82312*width, y: 0.60221*height), control2: CGPoint(x: 0.82384*width, y: 0.55799*height))
        path.addCurve(to: CGPoint(x: 0.82608*width, y: 0.36954*height), control1: CGPoint(x: 0.82305*width, y: 0.46289*height), control2: CGPoint(x: 0.82456*width, y: 0.41652*height))
        path.addCurve(to: CGPoint(x: 0.82827*width, y: 0.2925*height), control1: CGPoint(x: 0.8269*width, y: 0.34426*height), control2: CGPoint(x: 0.82773*width, y: 0.31879*height))
        path.addCurve(to: CGPoint(x: 0.82854*width, y: 0.28939*height), control1: CGPoint(x: 0.82829*width, y: 0.29137*height), control2: CGPoint(x: 0.82838*width, y: 0.29029*height))
        path.addCurve(to: CGPoint(x: 0.82916*width, y: 0.28744*height), control1: CGPoint(x: 0.8287*width, y: 0.28849*height), control2: CGPoint(x: 0.82891*width, y: 0.28782*height))
        path.addCurve(to: CGPoint(x: 0.82991*width, y: 0.28729*height), control1: CGPoint(x: 0.8294*width, y: 0.28707*height), control2: CGPoint(x: 0.82966*width, y: 0.28702*height))
        path.addCurve(to: CGPoint(x: 0.83057*width, y: 0.28897*height), control1: CGPoint(x: 0.83016*width, y: 0.28756*height), control2: CGPoint(x: 0.83039*width, y: 0.28814*height))
        path.addCurve(to: CGPoint(x: 0.83803*width, y: 0.34176*height), control1: CGPoint(x: 0.83388*width, y: 0.30407*height), control2: CGPoint(x: 0.83637*width, y: 0.32167*height))
        path.addCurve(to: CGPoint(x: 0.8417*width, y: 0.36382*height), control1: CGPoint(x: 0.83881*width, y: 0.35118*height), control2: CGPoint(x: 0.84003*width, y: 0.35853*height))
        path.addCurve(to: CGPoint(x: 0.84383*width, y: 0.37515*height), control1: CGPoint(x: 0.84266*width, y: 0.36676*height), control2: CGPoint(x: 0.84337*width, y: 0.37054*height))
        path.addCurve(to: CGPoint(x: 0.854*width, y: 0.47397*height), control1: CGPoint(x: 0.84746*width, y: 0.41005*height), control2: CGPoint(x: 0.85084*width, y: 0.44299*height))
        path.addCurve(to: CGPoint(x: 0.857*width, y: 0.49307*height), control1: CGPoint(x: 0.85476*width, y: 0.48149*height), control2: CGPoint(x: 0.85589*width, y: 0.48734*height))
        path.addCurve(to: CGPoint(x: 0.85997*width, y: 0.51265*height), control1: CGPoint(x: 0.85816*width, y: 0.49911*height), control2: CGPoint(x: 0.8593*width, y: 0.50503*height))
        path.addCurve(to: CGPoint(x: 0.87103*width, y: 0.61353*height), control1: CGPoint(x: 0.86288*width, y: 0.54637*height), control2: CGPoint(x: 0.86657*width, y: 0.58*height))
        path.addCurve(to: CGPoint(x: 0.88263*width, y: 0.73647*height), control1: CGPoint(x: 0.87643*width, y: 0.65441*height), control2: CGPoint(x: 0.8803*width, y: 0.69539*height))
        path.addCurve(to: CGPoint(x: 0.87963*width, y: 0.75794*height), control1: CGPoint(x: 0.88328*width, y: 0.74804*height), control2: CGPoint(x: 0.88228*width, y: 0.7552*height))
        path.addCurve(to: CGPoint(x: 0.84137*width, y: 0.77985*height), control1: CGPoint(x: 0.86641*width, y: 0.77176*height), control2: CGPoint(x: 0.85366*width, y: 0.77907*height))
        path.addCurve(to: CGPoint(x: 0.83475*width, y: 0.78493*height), control1: CGPoint(x: 0.839*width, y: 0.77998*height), control2: CGPoint(x: 0.83687*width, y: 0.78246*height))
        path.addCurve(to: CGPoint(x: 0.826*width, y: 0.78926*height), control1: CGPoint(x: 0.83199*width, y: 0.78815*height), control2: CGPoint(x: 0.82925*width, y: 0.79135*height))
        path.addCurve(to: CGPoint(x: 0.82383*width, y: 0.78103*height), control1: CGPoint(x: 0.82487*width, y: 0.78848*height), control2: CGPoint(x: 0.82414*width, y: 0.78574*height))
        path.addCurve(to: CGPoint(x: 0.8213*width, y: 0.64544*height), control1: CGPoint(x: 0.82041*width, y: 0.73172*height), control2: CGPoint(x: 0.81957*width, y: 0.68652*height))
        path.closeSubpath()
        path.move(to: CGPoint(x: 0.8213*width, y: 0.64544*height))
        path.addCurve(to: CGPoint(x: 0.82347*width, y: 0.51279*height), control1: CGPoint(x: 0.82312*width, y: 0.60221*height), control2: CGPoint(x: 0.82384*width, y: 0.55799*height))
        path.addCurve(to: CGPoint(x: 0.82608*width, y: 0.36954*height), control1: CGPoint(x: 0.82305*width, y: 0.46289*height), control2: CGPoint(x: 0.82456*width, y: 0.41652*height))
        path.addCurve(to: CGPoint(x: 0.82827*width, y: 0.2925*height), control1: CGPoint(x: 0.8269*width, y: 0.34426*height), control2: CGPoint(x: 0.82773*width, y: 0.31879*height))
        path.addCurve(to: CGPoint(x: 0.82854*width, y: 0.28939*height), control1: CGPoint(x: 0.82829*width, y: 0.29137*height), control2: CGPoint(x: 0.82838*width, y: 0.29029*height))
        path.addCurve(to: CGPoint(x: 0.82916*width, y: 0.28744*height), control1: CGPoint(x: 0.8287*width, y: 0.28849*height), control2: CGPoint(x: 0.82891*width, y: 0.28782*height))
        path.addCurve(to: CGPoint(x: 0.82991*width, y: 0.28729*height), control1: CGPoint(x: 0.8294*width, y: 0.28707*height), control2: CGPoint(x: 0.82966*width, y: 0.28702*height))
        path.addCurve(to: CGPoint(x: 0.83057*width, y: 0.28897*height), control1: CGPoint(x: 0.83016*width, y: 0.28756*height), control2: CGPoint(x: 0.83039*width, y: 0.28814*height))
        path.addCurve(to: CGPoint(x: 0.83803*width, y: 0.34176*height), control1: CGPoint(x: 0.83388*width, y: 0.30407*height), control2: CGPoint(x: 0.83637*width, y: 0.32167*height))
        path.addCurve(to: CGPoint(x: 0.8417*width, y: 0.36382*height), control1: CGPoint(x: 0.83881*width, y: 0.35118*height), control2: CGPoint(x: 0.84003*width, y: 0.35853*height))
        path.addCurve(to: CGPoint(x: 0.84383*width, y: 0.37515*height), control1: CGPoint(x: 0.84266*width, y: 0.36676*height), control2: CGPoint(x: 0.84337*width, y: 0.37054*height))
        path.addCurve(to: CGPoint(x: 0.854*width, y: 0.47397*height), control1: CGPoint(x: 0.84746*width, y: 0.41005*height), control2: CGPoint(x: 0.85084*width, y: 0.44299*height))
        path.addCurve(to: CGPoint(x: 0.857*width, y: 0.49307*height), control1: CGPoint(x: 0.85476*width, y: 0.48149*height), control2: CGPoint(x: 0.85589*width, y: 0.48734*height))
        path.addCurve(to: CGPoint(x: 0.85997*width, y: 0.51265*height), control1: CGPoint(x: 0.85816*width, y: 0.49911*height), control2: CGPoint(x: 0.8593*width, y: 0.50503*height))
        path.addCurve(to: CGPoint(x: 0.87103*width, y: 0.61353*height), control1: CGPoint(x: 0.86288*width, y: 0.54637*height), control2: CGPoint(x: 0.86657*width, y: 0.58*height))
        path.addCurve(to: CGPoint(x: 0.88263*width, y: 0.73647*height), control1: CGPoint(x: 0.87643*width, y: 0.65441*height), control2: CGPoint(x: 0.8803*width, y: 0.69539*height))
        path.addCurve(to: CGPoint(x: 0.87963*width, y: 0.75794*height), control1: CGPoint(x: 0.88328*width, y: 0.74804*height), control2: CGPoint(x: 0.88228*width, y: 0.7552*height))
        path.addCurve(to: CGPoint(x: 0.84137*width, y: 0.77985*height), control1: CGPoint(x: 0.86641*width, y: 0.77176*height), control2: CGPoint(x: 0.85366*width, y: 0.77907*height))
        path.addCurve(to: CGPoint(x: 0.83475*width, y: 0.78493*height), control1: CGPoint(x: 0.839*width, y: 0.77998*height), control2: CGPoint(x: 0.83687*width, y: 0.78246*height))
        path.addCurve(to: CGPoint(x: 0.826*width, y: 0.78926*height), control1: CGPoint(x: 0.83199*width, y: 0.78815*height), control2: CGPoint(x: 0.82925*width, y: 0.79135*height))
        path.addCurve(to: CGPoint(x: 0.82383*width, y: 0.78103*height), control1: CGPoint(x: 0.82487*width, y: 0.78848*height), control2: CGPoint(x: 0.82414*width, y: 0.78574*height))
        path.addCurve(to: CGPoint(x: 0.8213*width, y: 0.64544*height), control1: CGPoint(x: 0.82041*width, y: 0.73172*height), control2: CGPoint(x: 0.81957*width, y: 0.68652*height))
        path.closeSubpath()
        return path
    }
}

ここまできたらほぼ終わりです

フォントを追加する

以下の記事の手順でこちらのフォントを追加します。

ContentViewを実装する

import SwiftUI

struct ContentView: View {
    @State private var isPresentedToBeContinued = false
    
    private let toBeContinuedViewWidth: CGFloat = 250
    
    var body: some View {
        GeometryReader { geometryProxy in
            VStack {
                Button {
                    withAnimation {
                        isPresentedToBeContinued.toggle()
                    }
                } label: {
                    Text("エンディング開始")
                }
                .buttonStyle(.borderedProminent)
            }
            .padding(20)
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .background(Color(red: 50 / 255, green: 50 / 255, blue: 50 / 255))
            .ignoresSafeArea()
            .overlay(alignment: .bottomLeading) {
                if isPresentedToBeContinued {
                    toBeContinuedView(proxy: geometryProxy)
                }
            }
        }
    }
    
    private func toBeContinuedView(proxy: GeometryProxy) -> some View {
        ToBeContinuedView()
            .fill(Color(red: 21 / 255, green: 22 / 255, blue: 16 / 255))
            .stroke(Color(red: 227 / 255, green: 227 / 255, blue: 227 / 255), lineWidth: 2.5)
            // 縦横比率を固定する
            .aspectRatio(300/68, contentMode: .fit)
            .frame(width: toBeContinuedViewWidth)
            .overlay(content: toBeContinuedTextView)
            // 画面の横幅のだけ左にずらして画面外からスタートさせる
            .transition(.move(edge: .trailing).combined(with: .offset(x: proxy.size.width)))
            .padding(20)
    }
    
    private func toBeContinuedTextView() -> some View {
        Text("To Be Continued")
            .font(.custom("Caveat-SemiBold", size: toBeContinuedViewWidth / 10))
            .foregroundStyle(Color(red: 227 / 255, green: 227 / 255, blue: 227 / 255))
            .offset(x: -15)
    }
}

ちょっと解説

なんかコードだけ紹介して終わるのもちょっとアレなんで、
ポイントをいくつか紹介

縦横比率の固定

aspectRatioの第一引数に比率を渡してあげれば縦横比率が固定されます。
今回みたいにwidthだけを指定したいときは便利です。

.aspectRatio(300/68, contentMode: .fit)

トランジションの合成

transitioncombinedで繋ぐと合成できます。
今回は「右からスライドしてくる」 & 「proxy.size.widthの位置から移動する」の組み合わせです。

.transition(.move(edge: .trailing).combined(with: .offset(x: proxy.size.width)))

カスタムフォントの使用

ここの記事に書いてあります。

おわり

割と完成度高くできたと思います。
曲は著作権関係でやめときましたが、曲があったらもっと楽しめそうですね

9
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
3