Published on

SwiftUI'da Arcs va Quad Curves yordamida shakllar yasash

Authors

Nima uchun yoy va burilishlar muhim?

Oldingi darsda biz uchburchak, trapetsiya kabi shakllarni yasadik. Biroq, zamonaviy dizaynlar ko'pincha to'lqinli fonlar, yarim aylanalar va noodatiy "Wave" (to'lqin) ko'rinishidagi shakllardan tashkil topadi. Bunday shakllarni yasash uchun bizga addArc va addQuadCurve yordamga keladi.

1. Yoy chizish (addArc)

Aylana yoki uning bir qismini (yoyni) chizish uchun addArc dan foydalanamiz. Keling, tepasi to'rtburchak, lekin pastki qismi yarim aylanadan iborat shakl chizamiz (macOS dagi Tab larga o'xshash):

import SwiftUI

struct ShapeWithArc: Shape {
    func path(in rect: CGRect) -> Path {
        var path = Path()

        // Tepadan boshlab pastga tushamiz (To'g'ri chiziqlar)
        path.move(to: CGPoint(x: rect.minX, y: rect.minY))
        path.addLine(to: CGPoint(x: rect.maxX, y: rect.minY))
        path.addLine(to: CGPoint(x: rect.maxX, y: rect.midY))

        // Pastki qismda yoy chizamiz
        // Markazini topamiz (O'rtaning markazi)
        path.addArc(
            center: CGPoint(x: rect.midX, y: rect.midY),
            radius: rect.height / 2, // Kengligining yarmi radiusi bo'ladi
            startAngle: Angle(degrees: 0), // O'ng tarafdan boshlanadi
            endAngle: Angle(degrees: 180), // Chap tarafga borib tugaydi
            clockwise: false
        )

        // Qolgan joyini yopamiz
        path.addLine(to: CGPoint(x: rect.minX, y: rect.minY))

        return path
    }
}

Bu kod yordamida siz tayyor Capsule qanday ishlashini ham bilib olishingiz mumkin. U ham aslida tepada bitta va pastda bitta addArc chizishdan iborat!

2. To'lqinlar yasash (addQuadCurve)

Endi yanada qiziqroq narsa: Kvadratning o'rtasidan oxirigacha silliq to'lqin (Wave) chizamiz. Buning uchun addQuadCurve kerak bo'ladi. Quad Curve bizdan 2 ta narsa so'raydi:

  1. Qayerga borib tugashi (to)
  2. Qaysi tomonga qarab tortilishi (control) — bu nuqta xuddi magnitdek chiziqni o'ziga tortadi.
struct WaterShape: Shape {
    func path(in rect: CGRect) -> Path {
        var path = Path()

        // Ekranning chap-o'rtasidan boshlaymiz
        path.move(to: CGPoint(x: rect.minX, y: rect.midY))

        // Birinchi to'lqin: Tepaga qarab qavariq
        path.addQuadCurve(
            to: CGPoint(x: rect.midX, y: rect.midY), // Ekranning qoq markaziga tortamiz
            control: CGPoint(x: rect.width * 0.25, y: rect.height * 0.40) // Magnit teparoqda
        )

        // Ikkinchi to'lqin: Pastga qarab botiq
        path.addQuadCurve(
            to: CGPoint(x: rect.maxX, y: rect.midY), // Ekranning o'ng-o'rtasiga tortamiz
            control: CGPoint(x: rect.width * 0.75, y: rect.height * 0.60) // Magnit pastroqda
        )

        // Shakl pastini to'ldiramiz (burchaklarni yopib chiqamiz)
        path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY))
        path.addLine(to: CGPoint(x: rect.minX, y: rect.maxY))

        return path
    }
}

To'lqinni ishlatish

Biz yozgan to'lqinni endi har qanday View orqasida orqa fon sifatida ishlatish mumkin.

struct CustomCurvesBootcamp: View {
    var body: some View {
        ZStack {
            WaterShape()
                .fill(
                    LinearGradient(
                        gradient: Gradient(colors: [Color.blue.opacity(0.8), Color.blue]),
                        startPoint: .topLeading,
                        endPoint: .bottomTrailing
                    )
                )
                .ignoresSafeArea()
        }
    }
}

Ko'rib turganingizdek, xuddi rassom kabi nuqtalarni birlashtirib ishlash orqali ajoyib vektor grafikalar yig'a olamiz. Ammo bu chiziqlar o'zi qanday qilib jonlanadi (animatsiya qilinadi)? Buning siri keyingi darsdagi AnimatableData konseptida o'rganiladi!

Buy mea coffee