Swift-Animate Cashapelayer Stroke Color

Swift-animate CAshapeLayer stroke color

Updated to Swift 5.

Found out the solution. Enjoy. After you create the CAShapeLayer of course :

    let animcolor = CABasicAnimation(keyPath: "strokeColor")
animcolor.fromValue = UIColor.green.cgColor
animcolor.toValue = UIColor.orange.cgColor
animcolor.duration = 1.0
animcolor.repeatCount = 0
animcolor.autoreverses = true
myLayer.add(animcolor, forKey: "strokeColor")

Swift- animate CAshapeLayer stroke color

Found out the solution. Enjoy. After you create the CAShapeLayer of course :

        let animcolor = CABasicAnimation(keyPath: "strokeColor")
animcolor.fromValue = UIColor.greenColor().CGColor
animcolor.toValue = UIColor.orangeColor().CGColor
animcolor.duration = 1.0;
animcolor.repeatCount = 0;
animcolor.autoreverses = true
circleLayer.addAnimation(animcolor, forKey: "strokeColor")

CAShapeLayer stroke issue

edit/update:

It would be easier to multiply the line width by 2 and add a mask to your shape:

class Triangle: NSView {
let shapeLayer = CAShapeLayer()
var lineWidth: CGFloat
var strokeColor: NSColor = .clear
var fillColor: NSColor = .clear
init(size: CGSize, lineWidth: CGFloat = 10, strokeColor: NSColor = .white, fillColor: NSColor = .black) {
self.lineWidth = lineWidth*2
self.strokeColor = strokeColor
self.fillColor = fillColor
super.init(frame: .init(origin: .zero, size: size))
wantsLayer = true
let path = NSBezierPath()
path.move(to: .zero)
path.line(to: .init(x: size.width/2 , y: size.height))
path.line(to: .init(x: size.width, y: .zero))
path.close()
let mask = CAShapeLayer()
mask.path = path.cgPath
shapeLayer.mask = mask
shapeLayer.path = path.cgPath
shapeLayer.lineWidth = self.lineWidth
shapeLayer.strokeColor = strokeColor.cgColor
shapeLayer.fillColor = fillColor.cgColor
// layer?.borderWidth = 1
// layer?.borderColor = NSColor.red.cgColor
layer?.addSublayer(shapeLayer)
}
convenience init(width: CGFloat, height: CGFloat, lineWidth: CGFloat = 10, strokeColor: NSColor = .white, fillColor: NSColor = .black) {
self.init(size: .init(width: width, height: height), lineWidth: lineWidth, strokeColor: strokeColor, fillColor: fillColor)
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}


extension NSBezierPath {
var cgPath: CGPath {
let path = CGMutablePath()
var points: [CGPoint] = .init(repeating: .zero, count: 3)
for i in 0..<elementCount {
switch element(at: i, associatedPoints: &points) {
case .moveTo: path.move(to: points[0])
case .lineTo: path.addLine(to: points[0])
case .curveTo: path.addCurve(to: points[2], control1: points[0], control2: points[1])
case .closePath: path.closeSubpath()
@unknown default: fatalError()
}
}
return path
}

}


class ViewController: NSViewController {

override func viewDidLoad() {
super.viewDidLoad()
let triangle = Triangle(width: 200, height: 200, lineWidth: 1)
view.addSubview(triangle)
}
}

Sample Image

How to set CAShapeLayer 's strokeColor in swift

Here is the code snippet:

        let path = UIBezierPath()
path.move(to: CGPoint.zero)
path.addLine(to: CGPoint(x: 50, y: 50))

let view = UIView(frame: CGRect(x: 100, y: 100, width: 50, height: 50))
view.backgroundColor = UIColor.green

let diagonal = CAShapeLayer()
diagonal.frame = view.bounds
diagonal.path = path.cgPath
diagonal.strokeColor = UIColor.orange.cgColor
diagonal.lineWidth = 15
diagonal.backgroundColor = UIColor.blue.cgColor
// view.layer.mask = mask

view.layer.addSublayer(diagonal)

self.view.addSubview(view)

This results in:

Sample Image

Animating CAShapeLayer's strokeColor with CABasicAnimation

The code below works great for me. What is the lineWidth of your shapeLayer stroke path? Could that be the issue?

- (void)viewDidLoad
{
[super viewDidLoad];

UIBezierPath * circle = [UIBezierPath bezierPathWithOvalInRect:self.view.bounds];

CAShapeLayer * shapeLayer = [CAShapeLayer layer];
shapeLayer.path = circle.CGPath;
shapeLayer.strokeColor =[UIColor blueColor].CGColor;
[shapeLayer setLineWidth:15.0];

[self.view.layer addSublayer:shapeLayer];

CABasicAnimation *strokeAnim = [CABasicAnimation animationWithKeyPath:@"strokeColor"];
strokeAnim.fromValue = (id) [UIColor redColor].CGColor;
strokeAnim.toValue = (id) [UIColor greenColor].CGColor;
strokeAnim.duration = 3.0;
strokeAnim.repeatCount = 0;
strokeAnim.autoreverses = YES;
[shapeLayer addAnimation:strokeAnim forKey:@"animateStrokeColor"];

}

Let me know if it works for you...

How to animate CAShapeLayer path and fillColor

To animate path

  //setup the CAShapeLayer
myShapeLayer.strokeColor = [[UIColor blueColor] CGColor];
myShapeLayer.lineWidth = 5;
myShapeLayer.fillColor = [[UIColor yellowColor] CGColor];

//Display it!
[self.view.layer addSublayer:myShapeLayer];

//Animate path
CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
pathAnimation.duration = 1.5f;
pathAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
pathAnimation.toValue = [NSNumber numberWithFloat:1.0f];
pathAnimation.repeatCount = 10;
pathAnimation.autoreverses = YES;
[myShapeLayer addAnimation:pathAnimation forKey:@"strokeEnd"];

//Animate colorFill
CABasicAnimation *fillColorAnimation = [CABasicAnimation animationWithKeyPath:@"fillColor"];
fillColorAnimation.duration = 1.5f;
fillColorAnimation.fromValue = (id)[[UIColor clearColor] CGColor];
fillColorAnimation.toValue = (id)[[UIColor yellowColor] CGColor];
fillColorAnimation.repeatCount = 10;
fillColorAnimation.autoreverses = YES;
[myShapeLayer addAnimation:fillColorAnimation forKey:@"fillColor"];

I hope this helps :)

2021 Update

Swift

    myShapeLayer.strokeColor = UIColor.blue.cgColor
myShapeLayer.lineWidth = 5
myShapeLayer.fillColor = UIColor.yellow.cgColor

//Display it!
view.layer.addSublayer(myShapeLayer)

//Animate path
let pathAnimation = CABasicAnimation(keyPath: "strokeEnd")
pathAnimation.duration = 1.5
pathAnimation.fromValue = NSNumber(value: 0.0)
pathAnimation.toValue = NSNumber(value: 1.0)
pathAnimation.repeatCount = 10
pathAnimation.autoreverses = true
myShapeLayer.add(pathAnimation, forKey: "strokeEnd")

//Animate colorFill
let fillColorAnimation = CABasicAnimation(keyPath: "fillColor")
fillColorAnimation.duration = 1.5
fillColorAnimation.fromValue = UIColor.clear.cgColor
fillColorAnimation.toValue = UIColor.yellow.cgColor
fillColorAnimation.repeatCount = 10
fillColorAnimation.autoreverses = true
myShapeLayer.add(fillColorAnimation, forKey: "fillColor")

the strokeColor of CAShapeLayer not work

You are adding your shape layer as a mask layer. That allows the brightness of the mask layer's pixels to determine the opacity of the layer it's masking. It sounds like that's not what you want.

Instead, add your shape layer as a sublayer of your view's layer. Change

self.layer.mask = shapeLayer;

to

[self.layer addSublayer: shapeLayer];

That will cause your shape layer to drawn on top of your view's layer.



Related Topics



Leave a reply



Submit