Swift - 如何使用 UIGraphics 混合模式?
Swift - How to use UIGraphics blend mode?
我想为AppleWatch开发一种进度条动画。
我决定用 UIGraphicContext 来完成这一切。
因为我是一个完全的初学者,所以我真的不明白如何将某种“globalCompositeOperation”应用到我的上下文中。
为了更好地说明我的想法,这里有一些图片:
到目前为止,这是我的源代码:
let size = CGSize(width: 300, height: 100)
UIGraphicsBeginImageContext(size)
let context = UIGraphicsGetCurrentContext()!
context.setFillColor(UIColor.red.cgColor)
context.fill(CGRect(x: 0.0, y: 0.0, width: size.width * 0.5, height: size.height))
context.setBlendMode(CGBlendMode.destinationOver)
let count = 5;
let padding = (size.width / CGFloat(count)) * 0.5
for i in 0...count {
let offsetX = size.width * (CGFloat(i) / CGFloat(count))
let rect = CGRect(x: offsetX + padding/2, y: 0, width: padding, height: size.height)
context.setFillColor(UIColor.green.cgColor)
context.fill(rect)
}
UIGraphicsEndImageContext()
我想这是一种错误的方法,因为结果更像这样:
任何帮助将不胜感激。提前致谢。
你想要.sourceAtop
。这是一个演示:
let green = UIImage(named:"green.png")! // your original 5 green rects
let sz = green.size
let red = UIGraphicsImageRenderer(size:sz).image {
ctx in
UIColor.red.setFill()
// width value determines how much we will fill
ctx.fill(CGRect(x: 0, y: 0, width: sz.width/2, height: sz.height))
}
let result = UIGraphicsImageRenderer(size:sz).image {
ctx in
green.draw(at: .zero)
red.draw(at: .zero, blendMode: .sourceAtop, alpha: 1)
}
只需针对不同的 "thermometer" 金额改变 width: sz.width/2
处的值。
根据@matt 使用.sourceAtop
的回答,我找到了适用于 WatchKit 的可行解决方案:
let size = CGSize(width: 300, height: 100)
UIGraphicsBeginImageContext(size)
let context = UIGraphicsGetCurrentContext()!
let count = 5;
let padding = (size.width / CGFloat(count)) * 0.5
for i in 0...count {
let offsetX = size.width * (CGFloat(i) / CGFloat(count))
let rect = CGRect(x: offsetX + padding/2, y: 0, width: padding, height: size.height)
context.setFillColor(UIColor.green.cgColor)
context.fill(rect)
}
context.setFillColor(UIColor.red.cgColor)
context.setBlendMode(CGBlendMode.sourceAtop)
context.fill(CGRect(x: 0.0, y: 0.0, width: size.width * 0.5, height: size.height))
UIGraphicsEndImageContext()
我想为AppleWatch开发一种进度条动画。 我决定用 UIGraphicContext 来完成这一切。
因为我是一个完全的初学者,所以我真的不明白如何将某种“globalCompositeOperation”应用到我的上下文中。
为了更好地说明我的想法,这里有一些图片:
到目前为止,这是我的源代码:
let size = CGSize(width: 300, height: 100)
UIGraphicsBeginImageContext(size)
let context = UIGraphicsGetCurrentContext()!
context.setFillColor(UIColor.red.cgColor)
context.fill(CGRect(x: 0.0, y: 0.0, width: size.width * 0.5, height: size.height))
context.setBlendMode(CGBlendMode.destinationOver)
let count = 5;
let padding = (size.width / CGFloat(count)) * 0.5
for i in 0...count {
let offsetX = size.width * (CGFloat(i) / CGFloat(count))
let rect = CGRect(x: offsetX + padding/2, y: 0, width: padding, height: size.height)
context.setFillColor(UIColor.green.cgColor)
context.fill(rect)
}
UIGraphicsEndImageContext()
我想这是一种错误的方法,因为结果更像这样:
任何帮助将不胜感激。提前致谢。
你想要.sourceAtop
。这是一个演示:
let green = UIImage(named:"green.png")! // your original 5 green rects
let sz = green.size
let red = UIGraphicsImageRenderer(size:sz).image {
ctx in
UIColor.red.setFill()
// width value determines how much we will fill
ctx.fill(CGRect(x: 0, y: 0, width: sz.width/2, height: sz.height))
}
let result = UIGraphicsImageRenderer(size:sz).image {
ctx in
green.draw(at: .zero)
red.draw(at: .zero, blendMode: .sourceAtop, alpha: 1)
}
只需针对不同的 "thermometer" 金额改变 width: sz.width/2
处的值。
根据@matt 使用.sourceAtop
的回答,我找到了适用于 WatchKit 的可行解决方案:
let size = CGSize(width: 300, height: 100)
UIGraphicsBeginImageContext(size)
let context = UIGraphicsGetCurrentContext()!
let count = 5;
let padding = (size.width / CGFloat(count)) * 0.5
for i in 0...count {
let offsetX = size.width * (CGFloat(i) / CGFloat(count))
let rect = CGRect(x: offsetX + padding/2, y: 0, width: padding, height: size.height)
context.setFillColor(UIColor.green.cgColor)
context.fill(rect)
}
context.setFillColor(UIColor.red.cgColor)
context.setBlendMode(CGBlendMode.sourceAtop)
context.fill(CGRect(x: 0.0, y: 0.0, width: size.width * 0.5, height: size.height))
UIGraphicsEndImageContext()