티스토리 뷰
웃는 입꼬리(?)를 그리고 싶어서 Curved Path 를 그려본 기록 (with Animation)
[1] Rectangle Path 그리기 (연습)
우선 가장 만만한 Rectangle 로 연습 먼저 해보겠습니다.
rounded rectangle 을 Path 로 그려보면 다음과 같습니다.
이렇게 라인을 그리고 path 를 닫아서 네모를 완성시켜주는 코드입니다.
그리고 Shape 의 trim(from:to:) 모디파이어를 사용해서 애니메이션을 줄 수 있습니다.
예를들어 trim(from:0, to: 0.5) - 처음부터 50%까지만 그린다.
trim(from: 0.5, to: 1) - 50%부터 끝까지 그린다.
from을 0으로 고정시키고 to 를 0 ~ 1 사이로 바꾸면서 애니메이션을 주면 됩니다.
코드 첨부.
import SwiftUI
struct ContentView: View {
@State private var progress = 0.0
private let timer = Timer.publish(every: 0.1, on: .main, in: .common).autoconnect()
var body: some View {
Path { path in
path.move(to: .zero)
path.addLine(to: .zero)
path.addLine(to: CGPoint(x: 0, y: 100))
path.addLine(to: CGPoint(x: 100, y: 100))
path.addLine(to: CGPoint(x: 100, y: 0))
path.closeSubpath()
}
.trim(from: 0, to: progress)
.stroke(.blue, style: StrokeStyle(lineWidth: 5, lineCap: .round, lineJoin: .round))
.padding()
.animation(.easeInOut, value: progress)
.onReceive(timer) { _ in
if progress >= 1 {
timer.upstream.connect().cancel()
}
progress += 0.1
}
}
}
[2] 입꼬리 그리기 (본론)
여러 방법으로 할 수 있습니다.
2.1 addCurve
addCurve(to:controlPoint1:controlPoint2:) 를 활용해서 그리는 방법.
문서에 있는 A cubic Bézier curve 사진 참고.
control point 를 하나만 잡았을 때
control point 를 두개 잡았을 때 (두개 잡아야하는군)
2.2 addQuadCurve
addQuadCurve(to:controlPoint:) 를 활용하는 방법.
문서에 있는 quadratic Bézier curve 참고.
addCurve 보다 control 포인트를 좀 더 멀리 잡아야 비슷하게 그려지는 것 같습니다.
2.3 addArc(withCenter~~)
addArc(withCenter:radius:startAngle:endAngle:clockwise:)
이것도 문서에 링킹되어있는 사진을 참고합니다.
clockwise 가 매우 헷갈리는데,,, flipped coordinate system 쓰고 있어서 일반적으로 생각하는 시계방향과 반대라고 합니다.
However, because SwiftUI by default uses a vertically-flipped coordinate system (with the origin in the top-left of the view), specifying a clockwise arc results in a counterclockwise arc after the transformation is applied.
자세한 설명은 Is clockwise of Path.addArc in SwiftUI wrong? 참고
이렇게 생각해야함.. @_@
이건 내가 원하는 덜 땡그란 스마일을 그릴 수 없는 것 같아 SKIP. (각도 계산을 별도로 하면 되려나?)
2.4 addArc(tangent~~)
addArc(tangent1End:tangent2End:radius:transform:) 도 있음.
여기 보면 끝까지 안그리고 적당한 곡선을 그리기 때문에 한번 호출해서 스마일을 다 그릴 수 없어보임. SKIP.
The red line is the path that the function will draw.
P1 is the the point that the path is at before the function is called, x1, y1, x2, y2 correspond to the values passed in by the function, and r is the radius value.
The function doesn’t line to the second point given, it stops at the end of the arc.
2.5 addEllipse + trim
addEllipse(in:) 와 trim 을 조합하는 방법.
타원을 반만 그려서 스마일을 표현할 수도 있습니다.
하지만 animation 을 입히면 반대방향으로 그려지기 때문에 SKIP
Path 말고 Circle 로도 테스트해봤는데 기본적으로 다 반대로 도형이 그려지는 듯..
문서에 계속해서 나오는 flipped coordinate system 때문인 것인 것 같음.
--------
가장 간단한 2.2 의 방식을 선택함. MouthShape 를 별도로 빼주고 이렇게 활용.
struct MouthShape: Shape {
func path(in rect: CGRect) -> Path {
Path { path in
path.move(to: CGPoint(x: rect.minX, y: rect.minY))
path.addQuadCurve(
to: CGPoint(x: rect.maxX, y: rect.minY),
control: CGPoint(x: rect.midX, y: rect.maxY)
)
}
}
}
[ Reference ]
https://betterprogramming.pub/drawing-with-swiftuis-path-1cb3e57b9ee5
https://www.devtechie.com/community/public/posts/153876-path-animation-in-swiftui
'🍏 > SwiftUI + Combine' 카테고리의 다른 글
[SwiftUI] Preferences (0) | 2024.05.23 |
---|---|
[SwiftUI] animation(_:body:) 로 돌발애니메이션 막기 (1) | 2023.11.30 |
[SwiftUI] @Observable 매크로 (2) (0) | 2023.07.31 |
[SwiftUI] @Observable 매크로 (1) (1) | 2023.07.31 |
[SwiftUI] GridItem - adaptive vs flexible (0) | 2023.06.09 |
- Total
- Today
- Yesterday
- Flutter 로딩
- drf custom error
- 플러터 얼럿
- ipad multitasking
- Django Firebase Cloud Messaging
- 플러터 싱글톤
- DRF APIException
- ribs
- flutter 앱 출시
- Flutter Spacer
- Django Heroku Scheduler
- 장고 URL querystring
- Flutter getter setter
- cocoapod
- Flutter Text Gradient
- flutter deep link
- METAL
- Django FCM
- PencilKit
- Watch App for iOS App vs Watch App
- 구글 Geocoding API
- flutter build mode
- 장고 Custom Management Command
- Python Type Hint
- Dart Factory
- Sketch 누끼
- SerializerMethodField
- github actions
- flutter dynamic link
- Flutter Clipboard
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |