我有一个来自形状的 Rect 视图。为了最终完成,我需要在添加自定义路径时使用 CGAffineTransform。当我使用 CGAffineTransform 时,需要在形状内计算和更新参数a和tx以保持整个最终路径可见。目前,我不知道在更改视图大小时让a和tx自行更新的确切方法。我必须使用滑块手动调整它们,滑块不是应用或程序的一部分 - 它只是一个调试工具。正如您在视频中看到的,通过更改a和tx的值,我可以将整个路径保持在框架内,但用户需要这自动发生。那么,如何才能让a和tx自动更新,同时将整个路径保持在框架内?
第 1 部分:
第 2 部分:
代码:
import SwiftUI
struct ContentView: View {
@State private var a: Double = 0.8
@State private var b: Double = 0
@State private var c: Double = -0.17
@State private var d: Double = 1
@State private var tx: Double = 100
@State private var ty: Double = 0
var body: some View {
FinalShape(a: a, b: b, c: c, d: d, tx: tx, ty: ty)
.strokeBorder(style: StrokeStyle(lineWidth: 5.0, lineCap: .round, lineJoin: .round))
.background(Color.purple)
.cornerRadius(5.0)
.padding()
VStack {
HStack {
Text("a:")
Slider(value: $a, in: -1...1)
}
HStack {
Text("b:")
Slider(value: $b, in: -1...1)
}
HStack {
Text("c:")
Slider(value: $c, in: -1...1)
}
HStack {
Text("d:")
Slider(value: $d, in: -1...1)
}
HStack {
Text("tx:")
Slider(value: $tx, in: -200...200)
}
HStack {
Text("ty:")
Slider(value: $ty, in: -200...200)
}
}
.padding()
HStack {
VStack(alignment: .leading) {
Text("a:" + String(describing: a))
Text("b:" + String(describing: b))
Text("c:" + String(describing: c))
Text("d:" + String(describing: d))
Text("tx:" + String(describing: tx))
Text("ty:" + String(describing: ty))
}
Spacer()
}
.padding()
}
}
struct FinalShape: InsettableShape {
var a: Double
var b: Double
var c: Double
var d: Double
var tx: Double
var ty: Double
var insetAmount: CGFloat = CGFloat.zero
func path(in rect: CGRect) -> Path {
return Path { path in
let transform = CGAffineTransform(a: a, b: b, c: c, d: d, tx: tx, ty: ty)
path.addPath(RecShape(insetAmount: insetAmount).path(in: CGRect(origin: CGPoint(x: rect.minX, y: rect.minY), size: rect.size)), transform: transform)
}
}
func inset(by amount: CGFloat) -> some InsettableShape {
var myShape: Self = self
myShape.insetAmount += amount
return myShape
}
}
struct RecShape: InsettableShape {
var insetAmount: CGFloat = CGFloat.zero
func path(in rect: CGRect) -> Path {
return Path { path in
path.addRect(CGRect(origin: CGPoint(x: rect.minX + insetAmount, y: rect.minY + insetAmount), size: CGSize(width: rect.width - 2*insetAmount, height: rect.height - 2*insetAmount)))
}
}
func inset(by amount: CGFloat) -> some InsettableShape {
var myShape: Self = self
myShape.insetAmount += amount
return myShape
}
}
我假设
b
,c
,d
,ty
都是固定的。回想一下描述一个点如何通过仿射变换进行变换的方程。
根据您的 gif,您似乎希望矩形的
minX
和maxX
在应用变换后不会发生变化。我们可以建立两个方程并找到两个未知数a
和tx
。这里我考虑了两个点 (minX, maxY) 和 (maxX, minY)。解决这些问题后,你可以写下:
对于此形状,“插入”的含义值得怀疑。这里我只是插入了给定的
rect
,但我建议根本不要将其设置为可插入。使用示例:
请注意,仍然可以传入
d
和的值,ty
使得形状垂直a
超出矩形。和的值tx
无法帮助您实现这一点,因为a
和tx
控制水平轴上的变换。以下是完整代码及可接受的答案: