線と図形描画 – Drawing paths and shapes
section 1 バッヂビューで描画データ生成 Create drawing data for a badge view
File > New > File Swift File作成 – HexagonParameters.swift
.
六角形のstruct作成
segment 区分、部分? struct
import CoreGraphics struct HexagonParameters { struct Segment { let line : CGPoint let curve : CGPoint let control : CGPoint } // 調整 static let adjustment : CGFloat = 0.085 // 状態保持 static let segments = [ Segment( line: CGPoint(x: 0.60, y: 0.05), curve: CGPoint(x: 0.40, y: 0.05), control: CGPoint(x: 0.50, y: 0.00) ), Segment( line: CGPoint(x: 0.05, y: 0.20 + adjustment), curve: CGPoint(x: 0.00, y: 0.30 + adjustment), control: CGPoint(x: 0.00, y: 0.25 + adjustment) ), Segment( line: CGPoint(x: 0.00, y: 0.70 - adjustment), curve: CGPoint(x: 0.05, y: 0.80 - adjustment), control: CGPoint(x: 0.00, y: 0.75 - adjustment) ), Segment( line: CGPoint(x: 0.40, y: 0.95), curve: CGPoint(x: 0.60, y: 0.95), control: CGPoint(x: 0.50, y: 1.00) ), Segment( line: CGPoint(x: 0.95, y: 0.80 - adjustment), curve: CGPoint(x: 1.00, y: 0.70 - adjustment), control: CGPoint(x: 1.00, y: 0.75 - adjustment) ), Segment( line: CGPoint(x: 1.00, y: 0.30 + adjustment), curve: CGPoint(x: 0.95, y: 0.20 + adjustment), control: CGPoint(x: 1.00, y: 0.25 + adjustment) ) ] }
六角形の頂点データですが、とりあえずという感じですね^^;
section 2 バッヂの背景描画
SwiftUI View を作成 BadgeBackground.swift
import SwiftUI struct BadgeBackground: View { var body: some View { Path { path in var width: CGFloat = 100.0 let height = width path.move(to: CGPoint( x: width * 0.95, y: height * 0.20 )) HexagonParameters.segments.forEach{ segment in path.addLine(to: CGPoint( x:width * segment.line.x, y:height * segment.line.y )) } } .fill(.black) } } #Preview { BadgeBackground() }
Pathって線っぽいイメージですが、道筋、軌道、「軌道」は線に方向があるイメージですね
100×100の中で、x, y,を順に頂点をつけて、七角形?が出来ているようです
addQuadCurve(to:control:) で Quadは四角形でしょうか?QuadCurve…
Appends a quadratic Bézier curve to the path. ベジェ曲線をパスに追加と
これだけだと右上が少しズレていて
最初の点に
y: height * (0.20 + HexagonParameters.adjustment)
とすると綺麗に揃いました…んーなかなか
イマイチピンときませんがとりあえず進めます^^
GeometryReader で geometry を使って 100指定していたサイズを画面の縦横の小さい方に設定されたようです
横幅を調整したようです
色グラデーションを付けたようです、中央へ
section 3 バッヂシンボル描画
サンプルプロジェクトファイルにある
Resources / landmark_app_icon_1024x1024.pngをAssets catalog の AppIconのところに入れる
SwiftUI View : BadgeSymbol.swift を生成
山の形を作るらしい
こちらはシンプルな描画なのでわかりやすいですね
struct BadgeSymbol: View { static let symbolColor = Color(red:79.0/255,green:79.0/255,blue:191.0/255) var body: some View { GeometryReader{ geometry in Path { path in let width = min(geometry.size.width, geometry.size.height) let height = width * 0.75 let spacing = width * 0.03 let middle = width * 0.5 let topWidth = width * 0.226 let topHeight = height * 0.488 path.addLines([ CGPoint(x:middle, y:spacing), CGPoint(x:middle - topWidth, y:topHeight - spacing), CGPoint(x:middle, y:topHeight/2 + spacing), CGPoint(x:middle+topWidth, y: topHeight - spacing), CGPoint(x: middle, y: spacing) ]) path.move(to: CGPoint(x:middle, y: topHeight/2 + spacing)) path.addLines([ CGPoint(x: middle - topWidth, y:topHeight + spacing), CGPoint(x:spacing, y: height - spacing), CGPoint(x:width - spacing, y: height - spacing), CGPoint(x: middle + topWidth, y:topHeight + spacing), CGPoint(x: middle, y: topHeight/2 + spacing*3) ]) } .fill(Self.symbolColor) } } }
SwiftUI View : RotatedBadgeSymbol.swift を作成し、傾ける
struct RotatedBadgeSymbol: View { let angle: Angle var body: some View { BadgeSymbol() .padding(-60) .rotationEffect(angle, anchor:.bottom) } } #Preview { RotatedBadgeSymbol(angle: Angle(degrees:5)) }
section 4 バッジの前景と背景をあわせる
foregroundって前景だけどなんか前景って馴染みないですね
SwiftUI View : Badge.swiftを作成
単純に、zstack で BadgeBackgroundとBadgeSymbolを重ねるとこんな感じ
BadgeSymbolをいくつか変形
角度を変更して8つ並べる
こんな感じで出来ました。
難しくはないけど、これ作ろう!と思ってこの手順で進めるのは慣れないと
Check Your Understanding
英語難しい^^;
グラフなど描画するのに使う感じですかね?
コメント