- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我正在尝试绘制圆形渐变。
let backgroundView:UIView = UIView()
let backgroundLayer:CAShapeLayer = CAShapeLayer()
let gradient:CAGradientLayer = CAGradientLayer()
...
backgroundLayer.frame = CGRectMake(0, 0, backgroundDiameter, backgroundDiameter)
backgroundLayer.backgroundColor = UIColor.clearColor().CGColor
backgroundLayer.strokeColor = backgroundStrokeColor
backgroundLayer.fillColor = backgroundFillColor
gradient.colors = [UIColor(red: 0.5, green: 0.5, blue: 0.9, alpha: 1.0).CGColor,
UIColor(red: 0.9, green: 0.9, blue: 0.3, alpha: 1.0).CGColor]
gradient.locations = [0.01, 0.8]
gradient.frame = backgroundLayer.frame
backgroundView.frame = CGRectMake(0, 0, backgroundDiameter, backgroundDiameter)
backgroundView.backgroundColor = UIColor.clearColor()
backgroundView.center = ringControlCenter
backgroundLayer.insertSublayer(gradient, atIndex: 1)
backgroundLayer.path = CGPathCreateWithEllipseInRect(backgroundLayer.frame, nil)
backgroundView.layer.addSublayer(backgroundLayer)
self.addSubview(backgroundView)
但是渐变似乎不受以下因素影响:
backgroundLayer.path = CGPathCreateWithEllipseInRect(backgroundLayer.frame, nil)
而且还保持着最初的形状。有没有一种方法可以在不使用 CGContext* 指令的情况下使用椭圆形图层来掩盖渐变?
谢谢,
镁
最佳答案
我翻译了Leo library's在 Swift 3.x 中,换句话说,用 objective-C 编写的良好的 WCGradientCircleLayer(它的工作方式与 aspected 完全一样)
import UIKit
class WCGraintCircleLayer: CALayer {
override init () {
super.init()
}
convenience init(bounds:CGRect,position:CGPoint,fromColor:UIColor,toColor:UIColor,linewidth:CGFloat,toValue:CGFloat) {
self.init()
self.bounds = bounds
self.position = position
let colors : [UIColor] = self.graint(fromColor: fromColor, toColor:toColor, count:4)
for i in 0..<colors.count-1 {
let graint = CAGradientLayer()
graint.bounds = CGRect(origin:CGPoint.zero, size: CGSize(width:bounds.width/2,height:bounds.height/2))
let valuePoint = self.positionArrayWith(bounds: self.bounds)[i]
graint.position = valuePoint
print("iesimo graint position: \(graint.position)")
let fromColor = colors[i]
let toColor = colors[i+1]
let colors : [CGColor] = [fromColor.cgColor,toColor.cgColor]
let stopOne: CGFloat = 0.0
let stopTwo: CGFloat = 1.0
let locations : [CGFloat] = [stopOne,stopTwo]
graint.colors = colors
graint.locations = locations as [NSNumber]? // with Swift 2 and Swift 3 you can cast directly a `CGFloat` value to `NSNumber` and back
graint.startPoint = self.startPoints()[i]
graint.endPoint = self.endPoints()[i]
self.addSublayer(graint)
//Set mask
let shapelayer = CAShapeLayer()
let rect = CGRect(origin:CGPoint.zero,size:CGSize(width:self.bounds.width - 2 * linewidth,height: self.bounds.height - 2 * linewidth))
shapelayer.bounds = rect
shapelayer.position = CGPoint(x:self.bounds.width/2,y: self.bounds.height/2)
shapelayer.strokeColor = UIColor.blue.cgColor
shapelayer.fillColor = UIColor.clear.cgColor
shapelayer.path = UIBezierPath(roundedRect: rect, cornerRadius: rect.width/2).cgPath
shapelayer.lineWidth = linewidth
shapelayer.lineCap = kCALineCapRound
shapelayer.strokeStart = 0.010
let finalValue = (toValue*0.99)
shapelayer.strokeEnd = finalValue//0.99;
self.mask = shapelayer
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func layerWithWithBounds(bounds:CGRect, position:CGPoint, fromColor:UIColor, toColor:UIColor, linewidth : CGFloat,toValue:CGFloat) -> WCGraintCircleLayer {
let layer = WCGraintCircleLayer(bounds: bounds,position: position,fromColor:fromColor, toColor: toColor,linewidth: linewidth,toValue:toValue )
return layer
}
func graint(fromColor:UIColor, toColor:UIColor, count:Int) -> [UIColor]{
var fromR:CGFloat = 0.0,fromG:CGFloat = 0.0,fromB:CGFloat = 0.0,fromAlpha:CGFloat = 0.0
fromColor.getRed(&fromR,green: &fromG,blue: &fromB,alpha: &fromAlpha)
var toR:CGFloat = 0.0,toG:CGFloat = 0.0,toB:CGFloat = 0.0,toAlpha:CGFloat = 0.0
toColor.getRed(&toR,green: &toG,blue: &toB,alpha: &toAlpha)
var result : [UIColor]! = [UIColor]()
for i in 0...count {
let oneR:CGFloat = fromR + (toR - fromR)/CGFloat(count) * CGFloat(i)
let oneG : CGFloat = fromG + (toG - fromG)/CGFloat(count) * CGFloat(i)
let oneB : CGFloat = fromB + (toB - fromB)/CGFloat(count) * CGFloat(i)
let oneAlpha : CGFloat = fromAlpha + (toAlpha - fromAlpha)/CGFloat(count) * CGFloat(i)
let oneColor = UIColor.init(red: oneR, green: oneG, blue: oneB, alpha: oneAlpha)
result.append(oneColor)
print(oneColor)
}
return result
}
func positionArrayWith(bounds:CGRect) -> [CGPoint]{
let first = CGPoint(x:(bounds.width/4)*3,y: (bounds.height/4)*1)
let second = CGPoint(x:(bounds.width/4)*3,y: (bounds.height/4)*3)
let third = CGPoint(x:(bounds.width/4)*1,y: (bounds.height/4)*3)
let fourth = CGPoint(x:(bounds.width/4)*1,y: (bounds.height/4)*1)
print([first,second,third,fourth])
return [first,second,third,fourth]
}
func startPoints() -> [CGPoint] {
return [CGPoint.zero,CGPoint(x:1,y:0),CGPoint(x:1,y:1),CGPoint(x:0,y:1)]
}
func endPoints() -> [CGPoint] {
return [CGPoint(x:1,y:1),CGPoint(x:0,y:1),CGPoint.zero,CGPoint(x:1,y:0)]
}
func midColorWithFromColor(fromColor:UIColor, toColor:UIColor, progress:CGFloat) -> UIColor {
var fromR:CGFloat = 0.0,fromG:CGFloat = 0.0,fromB:CGFloat = 0.0,fromAlpha:CGFloat = 0.0
fromColor.getRed(&fromR,green: &fromG,blue: &fromB,alpha: &fromAlpha)
var toR:CGFloat = 0.0,toG:CGFloat = 0.0,toB:CGFloat = 0.0,toAlpha:CGFloat = 0.0
toColor.getRed(&toR,green: &toG,blue: &toB,alpha: &toAlpha)
let oneR = fromR + (toR - fromR) * progress
let oneG = fromG + (toG - fromG) * progress
let oneB = fromB + (toB - fromB) * progress
let oneAlpha = fromAlpha + (toAlpha - fromAlpha) * progress
let oneColor = UIColor.init(red: oneR, green: oneG, blue: oneB, alpha: oneAlpha)
return oneColor
}
// This is what you call if you want to draw a full circle.
func animateCircle(duration: TimeInterval) {
animateCircleTo(duration: duration, fromValue: 0.010, toValue: 0.99)
}
// This is what you call to draw a partial circle.
func animateCircleTo(duration: TimeInterval, fromValue: CGFloat, toValue: CGFloat){
// We want to animate the strokeEnd property of the circleLayer
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.isRemovedOnCompletion = true
// Set the animation duration appropriately
animation.duration = duration
// Animate from 0.010 (no circle) to 0.99 (full circle)
animation.fromValue = 0.010
animation.toValue = toValue
// Do an easeout. Don't know how to do a spring instead
//animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
// Set the circleLayer's strokeEnd property to 0.99 now so that it's the
// right value when the animation ends.
let circleMask = self.mask as! CAShapeLayer
circleMask.strokeEnd = toValue
// Do the actual animation
circleMask.removeAllAnimations()
circleMask.add(animation, forKey: "animateCircle")
}
}
这是一个小例子,如何在 Swift 3.x 中使用:
let gradientRingLayer = WCGraintCircleLayer(bounds: CGRect(origin: CGPoint.zero,size:CGSize(width: 150, height: 150)), position:CGPoint(x: 200, y: 300),fromColor:UIColor.blue, toColor:UIColor.white, linewidth:4.0, toValue:0)
self.view.layer.addSublayer(gradientRingLayer)
let duration = 3.0
gradientRingLayer.animateCircleTo(duration: duration, fromValue: 0, toValue: 0.99)
这是 Swift 2.x 中的代码:
import UIKit
class WCGraintCircleLayer: CALayer {
override init () {
super.init()
}
convenience init(bounds:CGRect,position:CGPoint,fromColor:UIColor,toColor:UIColor,linewidth:CGFloat,toValue:CGFloat) {
self.init()
self.bounds = bounds
self.position = position
let colors : [UIColor] = self.graintFromColor(fromColor, toColor:toColor, count:4)
for i in 0..<colors.count-1 {
let graint = CAGradientLayer()
graint.bounds = CGRectMake(0,0,CGRectGetWidth(bounds)/2,CGRectGetHeight(bounds)/2)
let valuePoint = self.positionArrayWithMainBounds(self.bounds)[i]
graint.position = valuePoint
print("iesimo graint position: \(graint.position)")
let fromColor = colors[i]
let toColor = colors[i+1]
let colors : [CGColorRef] = [fromColor.CGColor,toColor.CGColor]
let stopOne: CGFloat = 0.0
let stopTwo: CGFloat = 1.0
let locations : [CGFloat] = [stopOne,stopTwo]
graint.colors = colors
graint.locations = locations
graint.startPoint = self.startPoints()[i]
graint.endPoint = self.endPoints()[i]
self.addSublayer(graint)
//Set mask
let shapelayer = CAShapeLayer()
let rect = CGRectMake(0,0,CGRectGetWidth(self.bounds) - 2 * linewidth, CGRectGetHeight(self.bounds) - 2 * linewidth)
shapelayer.bounds = rect
shapelayer.position = CGPointMake(CGRectGetWidth(self.bounds)/2, CGRectGetHeight(self.bounds)/2)
shapelayer.strokeColor = UIColor.blueColor().CGColor
shapelayer.fillColor = UIColor.clearColor().CGColor
shapelayer.path = UIBezierPath(roundedRect: rect, cornerRadius: CGRectGetWidth(rect)/2).CGPath
shapelayer.lineWidth = linewidth
shapelayer.lineCap = kCALineCapRound
shapelayer.strokeStart = 0.010
let finalValue = (toValue*0.99)
shapelayer.strokeEnd = finalValue//0.99;
self.mask = shapelayer
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func layerWithWithBounds(bounds:CGRect, position:CGPoint, fromColor:UIColor, toColor:UIColor, linewidth : CGFloat,toValue:CGFloat) -> WCGraintCircleLayer {
let layer = WCGraintCircleLayer(bounds: bounds,position: position,fromColor:fromColor, toColor: toColor,linewidth: linewidth,toValue:toValue )
return layer
}
func graintFromColor(fromColor:UIColor, toColor:UIColor, count:Int) -> [UIColor]{
var fromR:CGFloat = 0.0,fromG:CGFloat = 0.0,fromB:CGFloat = 0.0,fromAlpha:CGFloat = 0.0
fromColor.getRed(&fromR,green: &fromG,blue: &fromB,alpha: &fromAlpha)
var toR:CGFloat = 0.0,toG:CGFloat = 0.0,toB:CGFloat = 0.0,toAlpha:CGFloat = 0.0
toColor.getRed(&toR,green: &toG,blue: &toB,alpha: &toAlpha)
var result : [UIColor]! = [UIColor]()
for i in 0...count {
let oneR:CGFloat = fromR + (toR - fromR)/CGFloat(count) * CGFloat(i)
let oneG : CGFloat = fromG + (toG - fromG)/CGFloat(count) * CGFloat(i)
let oneB : CGFloat = fromB + (toB - fromB)/CGFloat(count) * CGFloat(i)
let oneAlpha : CGFloat = fromAlpha + (toAlpha - fromAlpha)/CGFloat(count) * CGFloat(i)
let oneColor = UIColor.init(red: oneR, green: oneG, blue: oneB, alpha: oneAlpha)
result.append(oneColor)
print(oneColor)
}
return result
}
func positionArrayWithMainBounds(bounds:CGRect) -> [CGPoint]{
let first = CGPointMake((CGRectGetWidth(bounds)/4)*3, (CGRectGetHeight(bounds)/4)*1)
let second = CGPointMake((CGRectGetWidth(bounds)/4)*3, (CGRectGetHeight(bounds)/4)*3)
let third = CGPointMake((CGRectGetWidth(bounds)/4)*1, (CGRectGetHeight(bounds)/4)*3)
let fourth = CGPointMake((CGRectGetWidth(bounds)/4)*1, (CGRectGetHeight(bounds)/4)*1)
print([first,second,third,fourth])
return [first,second,third,fourth]
}
func startPoints() -> [CGPoint] {
return [CGPointMake(0,0),CGPointMake(1,0),CGPointMake(1,1),CGPointMake(0,1)]
}
func endPoints() -> [CGPoint] {
return [CGPointMake(1,1),CGPointMake(0,1),CGPointMake(0,0),CGPointMake(1,0)]
}
func midColorWithFromColor(fromColor:UIColor, toColor:UIColor, progress:CGFloat) -> UIColor {
var fromR:CGFloat = 0.0,fromG:CGFloat = 0.0,fromB:CGFloat = 0.0,fromAlpha:CGFloat = 0.0
fromColor.getRed(&fromR,green: &fromG,blue: &fromB,alpha: &fromAlpha)
var toR:CGFloat = 0.0,toG:CGFloat = 0.0,toB:CGFloat = 0.0,toAlpha:CGFloat = 0.0
toColor.getRed(&toR,green: &toG,blue: &toB,alpha: &toAlpha)
let oneR = fromR + (toR - fromR) * progress
let oneG = fromG + (toG - fromG) * progress
let oneB = fromB + (toB - fromB) * progress
let oneAlpha = fromAlpha + (toAlpha - fromAlpha) * progress
let oneColor = UIColor.init(red: oneR, green: oneG, blue: oneB, alpha: oneAlpha)
return oneColor
}
// This is what you call if you want to draw a full circle.
func animateCircle(duration: NSTimeInterval) {
animateCircleTo(duration, fromValue: 0.010, toValue: 0.99)
}
// This is what you call to draw a partial circle.
func animateCircleTo(duration: NSTimeInterval, fromValue: CGFloat, toValue: CGFloat){
// We want to animate the strokeEnd property of the circleLayer
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.removedOnCompletion = true
// Set the animation duration appropriately
animation.duration = duration
// Animate from 0.010 (no circle) to 0.99 (full circle)
animation.fromValue = 0.010
animation.toValue = toValue
// Do an easeout. Don't know how to do a spring instead
//animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
// Set the circleLayer's strokeEnd property to 0.99 now so that it's the
// right value when the animation ends.
let circleMask = self.mask as! CAShapeLayer
circleMask.strokeEnd = toValue
// Do the actual animation
circleMask.removeAllAnimations()
circleMask.addAnimation(animation, forKey: "animateCircle")
}
这是一个小例子,如何在 Swift 2.x 中使用:
let gradientRingLayer = WCGraintCircleLayer(bounds: CGRectMake(0, 0, 150, 150), position:CGPointMake(200,300) ,fromColor:UIColor.blueColor(), toColor:UIColor.whiteColor(),linewidth:4.0, toValue:0)
self.view.layer.addSublayer(gradientRingLayer)
let duration = 3.0
gradientRingLayer.animateCircleTo(duration, fromValue: 0, toValue: 0.99)
这是远程快速复制/粘贴 pastebin code
也可用于动画:
关于iOS - 圆形渐变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24657090/
我使用 jQuery 已经有一段时间了,但我不知道如何从一个渐变渐变到另一个渐变。我一直在用 http://www.colorzilla.com/gradient-editor/对于我的渐变。例如 b
为了使用 jni 帮助程序库运行测试,我将这样的代码添加到 build.gradle 中: def jniLibDir = "xxx" tasks.withType(Test) { syste
我正在从命令行运行 wsimport 以从 WSDL 生成 java 类,如下所示。 wsimport -J-Djavax.xml.accessExternalDTD=all -J-
我们有一个重复使用第3方 war 的项目(如果有人要求,则为shindig-server-2.0.2.war :)。这场 war 目前位于项目根目录中,当前的ant任务将其解压缩到temp文件夹中,进
我有一个边界框,其坐标由(x,y,w,h)给出,其中x和y是框的左上角坐标。我想在盒子外面应用模糊或渐变。如何使用上面的坐标创建蒙版,并使用类似于下图的PIL或cv2在蒙版之外应用此效果? 最佳答案
考虑情况http://codepen.io/anon/pen/JdGYBN 我需要在拖动元素时动态更改卡片“可拖动”的背景颜色。 但是卡片的背景应该根据线条的渐变颜色而变化。 background:
我现在有这种情况:JSFIDDLE 我想实现这种效果,但我希望文本可以在渐变后面选择,并且即使我将鼠标放在文本上也可以滚动文本。 是否有任何解决方法可以使用 javascript 来改变滚动时文本的不
这段代码是我从css graident generator得到的,渐变底部是透明的 background: -moz-linear-gradient(top, rgba(248,246,247,1)
我必须使用 CSS 完成以下图像: 这是一张包含主导航的图像。所以我为此写了一些 CSS(我知道不是正确的颜色代码): #menu-block { background: #730868; b
是否可以使用渐变作为渐变中的一种颜色? 为了我的特定目的,我有一个从左到右的初始渐变: linear-gradient(to right, red, darkgray); 但我希望深灰色部分实际上是从
我这辈子都想不通为什么 transition 属性在我的 CSS 中不起作用。这是代码: #header #menu-top-nav ul li a { -webkit-transition:
我一直在寻找像下图中那样的多组件日期选择器,但在 Github 或其他地方找不到任何东西。 所以我决定做一个。我在实现 CSS 时遇到问题,它在顶部和底部淡出。 我想过在容器中使用:before和:a
我正在寻找与下图等效的 css。我正在使用多个停止点,但很难获得硬停止点 solid 2px white 边框。如果我添加它,它看起来像是一个渐变而不是硬边。任何帮助都会很棒,谢谢! .stripes
我的广告部门给了我一些图像,将其放在网站上的选项卡等。但是我确信这会减慢页面的呈现速度。所以我想我会用 css 来做。然而,经过几次试验,我无法接近以下图像。对于这两张图片,我将不胜感激。 请删除这个
我试图在将鼠标悬停在 div (id="above") 上时更改 body 的背景图像/渐变,我按照他们在另一篇文章 (http://stackoverflow.com/questions/14623
我正在测试所有浏览器的渐变兼容性,我发现渐变在 FireFox 上有不同的效果。请允许我演示测试。 代码 body{
当我使用渐变时,当内容很少时,渐变会重复出现,我该如何防止这种情况发生? http://jsfiddle.net/mcqpP/1/ 我可以尝试使用 html { height: 100%; },但是当
我有一个导航栏,它的背景颜色略深。我想要一个从中心到左右两侧的渐变,以便导航栏最右边和最左边的位达到背景颜色。这可能吗? -->
我在 Firefox 中使用了这个 CSS 线性渐变,但在 Safari 和其他浏览器中似乎无法获得相同的结果。它是联系字段的纸状背景。我试过整个 body 和一个特定的元素,这种风格似乎只适用于 F
我有这行代码 背景:线性渐变(341deg, #8a8a8a 0%, #8a8a8a 31.9%, #000 32.1%, #000 100%); 如您所见,它一半是灰色一半是黑色。有没有办法让它的灰
我是一名优秀的程序员,十分优秀!