我试图通过设置 blendMode 修改器来擦除 Path 笔画,但不幸的是,没有像 UIGraphicsBeginImageContext 中那样可用的清晰模式是 setBlendMode(CGBlendMode.clear)。
我尝试了所有模式,但没有运气,它会增加颜色,产生一些新的图层颜色。 我认为会有一些机制可以清除底层颜色, 如果您知道请发布答案。 谢谢你。
我的代码:
struct Point : Hashable {
let x: CGFloat
let y: CGFloat
init(_ p:CGPoint) {
x = p.x
y = p.y
}
func toCGPoint() -> CGPoint {
CGPoint(x: x, y: y)
}
}
struct line:Hashable {
var line:[Point] = []
var color:Color
var eraseMode:Bool
}
struct editImage: View {
@State private var eraseMode = false
@State private var lines:[line] = [line(color: .red, eraseMode: false)]
var body: some View {
ZStack{
VStack{
Toggle(isOn: $eraseMode) {
Text("Erase Mode")
}.padding(.horizontal)
.onChange(of: eraseMode) {_eraseMode in
lines[lines.count-1].eraseMode = _eraseMode
}
Button(action: {
lines.removeAll()
lines.append(line(color: .green, eraseMode: eraseMode))
}, label: {
Text("Clear Canvas").padding()
})
ZStack{
ForEach(lines,id:\.self){line in
Path{p in
var f = true
line.line.forEach { point in
if f {
p.move(to: point.toCGPoint())
f = false
}else{
p.addLine(to: point.toCGPoint())
}
}
}.stroke(line.color,style: StrokeStyle(lineWidth: 14, lineCap: .round, lineJoin: .bevel, miterLimit: 0, dash: [], dashPhase: 0))
.blendMode(line.eraseMode ? BlendMode.hue : BlendMode.normal)
}
}.frame(width: 300, height: 300)
.background(Color.gray)
.gesture(DragGesture(minimumDistance: 0, coordinateSpace: .local).onChanged({ v in
lines[lines.count-1].line.append(.init(v.location))
}).onEnded({ _ in
lines.append(line(color: .red, eraseMode: eraseMode))
}))
}
}
}
}
可以将blendMode设置为clear,看Apple文档: 静态变量清除:GraphicsContext.BlendMode { get }
使用此模式,您可以像橡皮擦一样使用源图像。 此模式实现等式 R = 0,其中 R 是合成图像。
参见代码示例:
enum Mode {
case draw
case eraser
}
struct Line {
var color: Color
var points: [CGPoint]
var mode: Mode
}
struct ContentView: View {
@State var selectionModeIndex: Int = 0
@State var lines: [Line] = []
var body: some View {
VStack {
Picker("Mode:", selection: $selectionModeIndex) {
Text("Draw mode").tag(0)
Text("Eraser Mode").tag(1)
}.pickerStyle(.segmented)
Canvas { context, size in
for line in lines {
var path = Path()
path.addLines(line.points)
if line.mode == .draw {
context.blendMode = .normal
context.stroke(path, with: .color(line.color), style: StrokeStyle(lineWidth: 8))
} else {
context.blendMode = .clear
context.stroke(path, with: .color(line.color), style: StrokeStyle(lineWidth: 8))
}
}
}
.gesture(DragGesture().onChanged({ dragValue in
print("Changed")
if lines.isEmpty {
lines = [Line(color: .brown, points: [dragValue.startLocation], mode: Mode(rawValue: selectionModeIndex)!)]
} else {
var newLine = Line(color: .brown, points: [], mode: Mode(rawValue: selectionModeIndex)!)
if dragValue.startLocation != lines[lines.count - 1].points.first {
// Start a new line
newLine.points = [dragValue.startLocation]
lines.append(newLine)
print("Start new point")
} else {
print("Change point event")
let changedValue = dragValue.location
// Just append point to last line
lines[lines.count - 1].points.append(changedValue)
}
}
}))
}
}
}