Dra*_*lex 6 colors color-blending sprite-kit skspritenode swift
我有两个SKSpriteNode,它们的颜色定义如下:
colorNode[0].color = UIColor(red: 255, green: 0, blue: 0, alpha: 1)
colorNode[1].color = UIColor(red: 0, green: 255, blue: 0, alpha: 1)
Run Code Online (Sandbox Code Playgroud)
我想让第三个SKSpriteNode用前两个的混合着色,结果应该是这样的:
colorNode[2].color = UIColor(red: 255, green: 255, blue: 0, alpha: 1)
Run Code Online (Sandbox Code Playgroud)
但有没有办法添加两个UIColors?像这样 :
colorNode[2].color = colorNode[0].color + colorNode[1].color
Run Code Online (Sandbox Code Playgroud)
这样的事情怎么样:
func addColor(_ color1: UIColor, with color2: UIColor) -> UIColor {
var (r1, g1, b1, a1) = (CGFloat(0), CGFloat(0), CGFloat(0), CGFloat(0))
var (r2, g2, b2, a2) = (CGFloat(0), CGFloat(0), CGFloat(0), CGFloat(0))
color1.getRed(&r1, green: &g1, blue: &b1, alpha: &a1)
color2.getRed(&r2, green: &g2, blue: &b2, alpha: &a2)
// add the components, but don't let them go above 1.0
return UIColor(red: min(r1 + r2, 1), green: min(g1 + g2, 1), blue: min(b1 + b2, 1), alpha: (a1 + a2) / 2)
}
func multiplyColor(_ color: UIColor, by multiplier: CGFloat) -> UIColor {
var (r, g, b, a) = (CGFloat(0), CGFloat(0), CGFloat(0), CGFloat(0))
color.getRed(&r, green: &g, blue: &b, alpha: &a)
return UIColor(red: r * multiplier, green: g * multiplier, blue: b * multiplier, alpha: a)
}
Run Code Online (Sandbox Code Playgroud)
定义运算符以添加颜色并将颜色乘以Double:
func +(color1: UIColor, color2: UIColor) -> UIColor {
return addColor(color1, with: color2)
}
func *(color: UIColor, multiplier: Double) -> UIColor {
return multiplyColor(color, by: CGFloat(multiplier))
}
Run Code Online (Sandbox Code Playgroud)
然后你可以混合这样的颜色:
// Make orange with 50% red and 50% yellow
let orange = .red * 0.5 + .yellow * 0.5
// Make light gray with 25% black and 75% white
let lightGray = .black * 0.25 + .white * 0.75
// Make sky blue by lightening a combination of 25% blue and 75% cyan
let skyBlue = (.blue * 0.25 + .cyan * 0.75) * 0.25 + .white * 0.75
// Make dark red by combining 50% red and 50% black
let darkRed = .red * 0.50 + .black * 0.50
// Make purple from 60% blue and 40% red
let purple = (.blue * 0.60 + .red * 0.40)
// Then make lavender from 25% purple and 75% white
let lavender = purple * 0.25 + .white * 0.75
Run Code Online (Sandbox Code Playgroud)
Swift3版本,具有更多防护和细粒度调整功能的扩展:
extension UIColor {
static func blend(color1: UIColor, intensity1: CGFloat = 0.5, color2: UIColor, intensity2: CGFloat = 0.5) -> UIColor {
let total = intensity1 + intensity2
let l1 = intensity1/total
let l2 = intensity2/total
guard l1 > 0 else { return color2}
guard l2 > 0 else { return color1}
var (r1, g1, b1, a1): (CGFloat, CGFloat, CGFloat, CGFloat) = (0, 0, 0, 0)
var (r2, g2, b2, a2): (CGFloat, CGFloat, CGFloat, CGFloat) = (0, 0, 0, 0)
color1.getRed(&r1, green: &g1, blue: &b1, alpha: &a1)
color2.getRed(&r2, green: &g2, blue: &b2, alpha: &a2)
return UIColor(red: l1*r1 + l2*r2, green: l1*g1 + l2*g2, blue: l1*b1 + l2*b2, alpha: l1*a1 + l2*a2)
}
}
Run Code Online (Sandbox Code Playgroud)
小智 6
代码已经实现了photoshop的所有图层混合。如果对你有用,别忘了给我一个开始。玩得开心~
\n\nGitHub: https: //github.com/Orange-W/PhotoshopBending
\n\nimport Foundation\nimport UIKit\n\nextension UIColor {\n // MARK: - \xe5\xb8\xb8\xe7\x94\xa8\xe5\x8f\xa0\xe5\x9b\xbe\n // Alpha Blending \xe5\x89\x8d\xe6\x99\xaf\xe8\x89\xb2\xe5\x8f\xa0\xe5\x9b\xbe\n func blendAlpha(coverColor: UIColor) -> UIColor {\n let c1 = coverColor.rgbaTuple()\n let c2 = self.rgbaTuple()\n\n let c1r = CGFloat(c1.r)\n let c1g = CGFloat(c1.g)\n let c1b = CGFloat(c1.b)\n\n let c2r = CGFloat(c2.r)\n let c2g = CGFloat(c2.g)\n let c2b = CGFloat(c2.b)\n\n // \xe5\x89\x8d\xe6\x99\xaf\xe8\x89\xb2\xe5\x8f\xa0\xe5\x9b\xbe\xe5\x85\xac\xe5\xbc\x8f\n let r = c1r * c1.a + c2r * (1 - c1.a)\n let g = c1g * c1.a + c2g * (1 - c1.a)\n let b = c1b * c1.a + c2b * (1 - c1.a)\n\n return UIColor.init(red: r/255.0, green: g/255.0, blue: b/255.0, alpha: 1.0)\n }\n\n\n // MARK: - \xe5\x8e\xbb\xe4\xba\xae\xe5\xba\xa6\xe5\x9e\x8b\n /// Darken \xe5\x8f\x98\xe6\x9a\x97 B<=A: C=B; B>=A: C=A\n func blendDarken(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {\n return blendProcedure(coverColor: coverColor, alpha: alpha) { return ($0 <= $1) ? $0 : $1 }\n }\n\n /// Multiply \xe6\xad\xa3\xe7\x89\x87\xe5\x8f\xa0\xe5\xba\x95 C = A*B\n func blendMultiply(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {\n return blendProcedure(coverColor: coverColor, alpha: alpha) { return $0 * $1 }\n }\n\n /// Color Burn \xe9\xa2\x9c\xe8\x89\xb2\xe5\x8a\xa0\xe6\xb7\xb1 C=1-(1-B)/A\n func blendColorBurn(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {\n return blendProcedure(coverColor: coverColor, alpha: alpha) { return 1 - (1 - $0) / $1 }\n }\n\n /// Linear Burn \xe7\xba\xbf\xe6\x80\xa7\xe5\x8a\xa0\xe6\xb7\xb1 C=A+B-1\n func blendLinearBurn(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {\n return blendProcedure(coverColor: coverColor, alpha: alpha) { return ($1 + $0) - 1.0 }\n }\n\n // MARK: - \xe5\x8e\xbb\xe6\x9a\x97\xe5\x9e\x8b\n /// Lighten \xe5\x8f\x98\xe4\xba\xae B>=A: C=B; B<=A: C=A\n func blendLighten(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {\n return blendProcedure(coverColor: coverColor, alpha: alpha) { return ($0 >= $1) ? $0 : $1 }\n }\n\n /// Screen \xe6\xbb\xa4\xe8\x89\xb2 C=1-(1-A)*(1-B), \xe4\xb9\x9f\xe5\x8f\xaf\xe4\xbb\xa5\xe5\x86\x99\xe6\x88\x90 1-C=(1-A)*(1-B)\n func blendScreen(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {\n return blendProcedure(coverColor: coverColor, alpha: alpha) { return 1 - (1 - $1) * (1 - $0) }\n }\n\n /// Color Dodge \xe9\xa2\x9c\xe8\x89\xb2\xe5\x87\x8f\xe6\xb7\xa1 C=B/(1-A)\n func blendColorDodge(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {\n return blendProcedure(coverColor: coverColor, alpha: alpha) {\n if $1 >= 1.0 { return $1 }\n else { return min(1.0, $0 / (1 - $1)) }\n }\n }\n\n /// Linear Dodge \xe7\xba\xbf\xe6\x80\xa7\xe5\x87\x8f\xe6\xb7\xa1 C=A+B\n func blendLinearDodge(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {\n return blendProcedure(coverColor: coverColor, alpha: alpha) { return min(1, $1 + $0) }\n }\n\n\n // MARK: - \xe6\xba\xb6\xe5\x90\x88\xe5\x9e\x8b\n /// Overlay \xe5\x8f\xa0\xe5\x8a\xa0 B<=0.5: C=2*A*B; B>0.5: C=1-2*(1-A)*(1-B)\n func blendOverlay(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {\n return blendProcedure(coverColor: coverColor, alpha: alpha) {\n if $0 <= 0.5 { return 2 * $1 * $0 }\n else { return 1 - 2 * (1 - $1) * (1 - $0) }\n }\n }\n\n /// Soft Light \xe6\x9f\x94\xe5\x85\x89 A<=0.5: C=(2*A-1)*(B-B*B)+B; A>0.5: C=(2*A-1)*(sqrt(B)-B)+B\n func blendSoftLight(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {\n return blendProcedure(coverColor: coverColor, alpha: alpha) {\n if $1 <= 0.5 { return (2 * $1 - 1) * ($0 - $0 * $0) + $0 }\n else { return (2 * $1 - 1)*( sqrt($0) - $0) + $0 }\n }\n }\n\n /// Hard Light \xe5\xbc\xba\xe5\x85\x89 A<=0.5: C=2*A*B; A>0.5: C=1-2*(1-A)*(1-B)\n func blendHardLight(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {\n return blendProcedure(coverColor: coverColor, alpha: alpha) {\n if $1 <= 0.5 { return 2 * $1 * $0 }\n else { return 1 - 2 * (1 - $1) * (1 - $0) }\n }\n }\n\n /// Vivid Light \xe4\xba\xae\xe5\x85\x89 A<=0.5: C=1-(1-B)/(2*A); A>0.5: C=B/(2*(1-A))\n func blendVividLight(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {\n return blendProcedure(coverColor: coverColor, alpha: alpha) {\n if $1 <= 0.5 { return self.fitIn((1 - (1 - $0) / (2 * $1)), ceil: 1.0) }\n else { return self.fitIn($0 / (2 * (1 - $1)), ceil: 1.0) }\n }\n }\n\n /// Linear Light \xe7\xba\xbf\xe6\x80\xa7\xe5\x85\x89 C=B+2*A-1\n func blendLinearLight(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {\n return blendProcedure(coverColor: coverColor, alpha: alpha) { return self.fitIn($0 + 2 * $1 - 1, ceil: 1.0) }\n }\n\n /// Pin Light \xe7\x82\xb9\xe5\x85\x89\n /// B<2*A-1: C=2*A-1\n /// 2*A-1<B<2*A: C=B\n /// B>2*A: C=2*A\n func blendPinLight(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {\n return blendProcedure(coverColor: coverColor, alpha: alpha) {\n if $0 <= 2 * $1 - 1 { return 2 * $1 - 1 }\n else if (2 * $1 - 1 < $0) && ($0 < 2 * $1) { return $0}\n else { return 2 * $1 }\n }\n }\n\n /// Hard Mix \xe5\xae\x9e\xe8\x89\xb2\xe6\xb7\xb7\xe5\x90\x88A<1-B: C=0; A>1-B: C=1\n func blendHardMix(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {\n return blendProcedure(coverColor: coverColor, alpha: alpha) {\n if $1 <= 1 - $0 { return 0 }\n else { return 1 }\n }\n }\n\n // MARK: - \xe8\x89\xb2\xe5\xb7\xae\xe5\x9e\x8b\n /// Difference \xe5\xb7\xae\xe5\x80\xbc C=|A-B|\n func blendDifference(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {\n return blendProcedure(coverColor: coverColor, alpha: alpha) { fabs($1 - $0) }\n }\n\n /// Exclusion \xe6\x8e\x92\xe9\x99\xa4 C = A+B-2*A*B\n func blendExclusion(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {\n return blendProcedure(coverColor: coverColor, alpha: alpha) { $1 + $0 - 2 * $1 * $0 }\n }\n\n /// \xe5\x87\x8f\xe5\x8e\xbb C=A-B\n func blendMinus(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {\n return blendProcedure(coverColor: coverColor, alpha: alpha) { $1 - $0 }\n }\n\n /// \xe5\x88\x92\xe5\x88\x86 C=A/B\n func blendDivision(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {\n return blendProcedure(coverColor: coverColor, alpha: alpha) {\n if $0 == 0{\n return 1.0\n }else {\n return self.fitIn($1 / $0, ceil: 1.0)\n }\n }\n }\n\n // MARK: \xe5\xa4\x84\xe7\x90\x86\xe5\x87\xbd\xe6\x95\xb0\n func blendProcedure(\n coverColor: UIColor,\n alpha: CGFloat,\n procedureBlock: ((_ baseValue: CGFloat,_ topValue: CGFloat) -> CGFloat)?\n ) -> UIColor {\n let baseCompoment = self.rgbaTuple()\n let topCompoment = coverColor.rgbaTuple()\n\n // \xe8\xaf\xa5\xe5\xb1\x82\xe9\x80\x8f\xe6\x98\x8e\xe5\xba\xa6\n let mixAlpha = alpha * topCompoment.a + (1.0 - alpha) * baseCompoment.a\n\n // RGB \xe5\x80\xbc\n let mixR = procedureBlock?(\n baseCompoment.r / 255.0,\n topCompoment.r / 255.0)\n ?? (baseCompoment.r) / 255.0\n\n let mixG = procedureBlock?(\n baseCompoment.g / 255.0,\n topCompoment.g / 255.0)\n ?? (baseCompoment.g) / 255.0\n\n let mixB = procedureBlock?(\n baseCompoment.b / 255.0,\n topCompoment.b / 255.0)\n ?? baseCompoment.b / 255.0\n\n\n return UIColor.init(red: fitIn(mixR),\n green: fitIn(mixG),\n blue: fitIn(mixB),\n alpha: mixAlpha)\n }\n\n // \xe9\x98\xb2\xe6\xad\xa2\xe8\xb6\x8a\xe7\x95\x8c\n func fitIn(_ value: CGFloat, ceil: CGFloat = 255) -> CGFloat { return max(min(value,ceil),0) }\n func fitIn(_ value: Double, ceil: CGFloat = 255) -> CGFloat { return fitIn(CGFloat(value), ceil: ceil) }\n\n // \xe8\xbf\x94\xe5\x9b\x9e RBGA\n func rgbaTuple() -> (r: CGFloat, g: CGFloat, b: CGFloat,a: CGFloat) {\n var r: CGFloat = 0\n var g: CGFloat = 0\n var b: CGFloat = 0\n var a: CGFloat = 0\n self.getRed(&r, green: &g, blue: &b, alpha: &a)\n r = r * 255\n g = g * 255\n b = b * 255\n\n return ((r),(g),(b),a)\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
6131 次 |
| 最近记录: |