```
refactor: 重命名项目名称从"体己"到"康康" 将整个项目的目录结构从"体己"重命名为"康康",包括所有源代码文件、 资源文件、测试文件以及Xcode项目配置文件。此更改涉及项目中所有的 文件路径和应用入口点(App/TijiApp.swift → App/KangkangApp.swift)。 ```
This commit is contained in:
100
康康/Features/Quick/SmartFramer.swift
Normal file
100
康康/Features/Quick/SmartFramer.swift
Normal file
@@ -0,0 +1,100 @@
|
||||
import SwiftUI
|
||||
|
||||
struct SmartFramer: View {
|
||||
var radius: CGFloat = 10
|
||||
var height: CGFloat = 56
|
||||
@State private var breathing = false
|
||||
|
||||
var body: some View {
|
||||
GeometryReader { geo in
|
||||
ZStack {
|
||||
Color.black.opacity(0.32)
|
||||
.mask(
|
||||
Rectangle()
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: radius, style: .continuous)
|
||||
.frame(height: height)
|
||||
.padding(.horizontal, geo.size.width * 0.08)
|
||||
.blendMode(.destinationOut)
|
||||
)
|
||||
.compositingGroup()
|
||||
)
|
||||
|
||||
RoundedRectangle(cornerRadius: radius + 4, style: .continuous)
|
||||
.stroke(Color(red: 0.95, green: 0.78, blue: 0.45), lineWidth: 1.5)
|
||||
.shadow(color: Color(red: 0.95, green: 0.78, blue: 0.45).opacity(0.5), radius: 8)
|
||||
.frame(height: height + 8)
|
||||
.padding(.horizontal, geo.size.width * 0.08 - 4)
|
||||
.opacity(breathing ? 1 : 0.35)
|
||||
|
||||
cornerMarks(in: geo.size)
|
||||
}
|
||||
.frame(width: geo.size.width, height: geo.size.height)
|
||||
.onAppear {
|
||||
withAnimation(.easeInOut(duration: 2.2).repeatForever(autoreverses: true)) {
|
||||
breathing.toggle()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func cornerMarks(in size: CGSize) -> some View {
|
||||
let inset = size.width * 0.08
|
||||
return ZStack {
|
||||
ForEach(Corner.allCases, id: \.self) { corner in
|
||||
CornerMark(corner: corner, radius: radius)
|
||||
.frame(width: 18, height: 18)
|
||||
.position(corner.position(in: size, inset: inset, frameHeight: height))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private enum Corner: CaseIterable {
|
||||
case tl, tr, bl, br
|
||||
func position(in size: CGSize, inset: CGFloat, frameHeight: CGFloat) -> CGPoint {
|
||||
let centerY = size.height / 2
|
||||
let top = centerY - frameHeight / 2
|
||||
let bottom = centerY + frameHeight / 2
|
||||
switch self {
|
||||
case .tl: return CGPoint(x: inset, y: top)
|
||||
case .tr: return CGPoint(x: size.width - inset, y: top)
|
||||
case .bl: return CGPoint(x: inset, y: bottom)
|
||||
case .br: return CGPoint(x: size.width - inset, y: bottom)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private struct CornerMark: View {
|
||||
let corner: Corner
|
||||
let radius: CGFloat
|
||||
|
||||
var body: some View {
|
||||
Path { p in
|
||||
let r = min(radius, 8)
|
||||
switch corner {
|
||||
case .tl:
|
||||
p.move(to: CGPoint(x: 0, y: 18))
|
||||
p.addLine(to: CGPoint(x: 0, y: r))
|
||||
p.addQuadCurve(to: CGPoint(x: r, y: 0), control: CGPoint(x: 0, y: 0))
|
||||
p.addLine(to: CGPoint(x: 18, y: 0))
|
||||
case .tr:
|
||||
p.move(to: CGPoint(x: 0, y: 0))
|
||||
p.addLine(to: CGPoint(x: 18 - r, y: 0))
|
||||
p.addQuadCurve(to: CGPoint(x: 18, y: r), control: CGPoint(x: 18, y: 0))
|
||||
p.addLine(to: CGPoint(x: 18, y: 18))
|
||||
case .bl:
|
||||
p.move(to: CGPoint(x: 0, y: 0))
|
||||
p.addLine(to: CGPoint(x: 0, y: 18 - r))
|
||||
p.addQuadCurve(to: CGPoint(x: r, y: 18), control: CGPoint(x: 0, y: 18))
|
||||
p.addLine(to: CGPoint(x: 18, y: 18))
|
||||
case .br:
|
||||
p.move(to: CGPoint(x: 0, y: 18))
|
||||
p.addLine(to: CGPoint(x: 18 - r, y: 18))
|
||||
p.addQuadCurve(to: CGPoint(x: 18, y: 18 - r), control: CGPoint(x: 18, y: 18))
|
||||
p.addLine(to: CGPoint(x: 18, y: 0))
|
||||
}
|
||||
}
|
||||
.stroke(Tj.Palette.paper, style: StrokeStyle(lineWidth: 2.5, lineCap: .round))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user