Маска CAShapeLayer раскрывается снизу
Я пытаюсь создать эффект "раскрытия" из нижней части изображения. Я думал, что это будет так же просто, как установка anchorPoint для CGPointMake(0.5, 1.0) или contentGravity для kCAGravityTop, но ни один из этих вариантов не работает.
Текущий код у меня работает, но оживляет сверху вниз. вот идея раскрытия: http://giphy.com/gifs/xTiTnBzItdgaD1xHMc
Как бы я сделал это идти снизу вверх?
Вот код
let path = UIBezierPath(rect: CGRectMake(0, 0, imgEmptyBase.width, imgEmptyBase.height - 80))
let mask = CAShapeLayer()
mask.anchorPoint = CGPointMake(0.5, 1.0)
mask.path = path.CGPath
imgEmptyBase.layer.mask = mask
let anim = CABasicAnimation(keyPath: "path")
anim.fromValue = path.CGPath
anim.toValue = UIBezierPath(rect: imgEmptyBase.bounds).CGPath
anim.duration = 1.0
anim.fillMode = kCAFillModeForwards
anim.removedOnCompletion = false
imgEmptyBase.layer.mask.addAnimation(anim, forKey: "anim")
4 ответа
Это достигнет именно того эффекта, который вы ищете:
let path = UIBezierPath(rect: CGRectMake(0, imgEmptyBase.layer.frame.size.height, imgEmptyBase.layer.frame.size.width, imgEmptyBase.layer.frame.size.height))
let mask = CAShapeLayer()
mask.path = path.CGPath
imgEmptyBase.layer.mask = mask
let revealPath = UIBezierPath(rect: CGRectMake(0, 0, imgEmptyBase.layer.frame.size.width, imgEmptyBase.layer.frame.size.height))
let anim = CABasicAnimation(keyPath: "path")
anim.fromValue = path.CGPath
anim.toValue = revealPath.CGPath
anim.duration = 1.0
anim.fillMode = kCAFillModeForwards
anim.removedOnCompletion = false
imgEmptyBase.layer.mask.addAnimation(anim, forKey: "anim")
Это все об изменении пути маски, используя правильные значения "от" и "до". Например: установка начального пути маски CGRectMake(0, 0, imgEmptyBase.layer.frame.size.width, 0)
и revealPath
в CGRectMake(0, 0, imgEmptyBase.layer.frame.size.width, imgEmptyBase.layer.frame.size.height)
приведет к эффекту "сверху вниз".
Мое предложение состоит в том, чтобы использовать штрих пути вместо заливки.
Вы рисуете траекторию (синюю линию), которая начинается в нижней части вашего слоя и заканчивается вверху, по центру по горизонтали и с шириной линии, равной ширине слоя.
Красный контур представляет контур обводки.
Вы играете анимацию на strokeEnd
свойство от 0 до 1.
Я сделал игровую площадку, если вы хотите посмотреть, как мне удалось добиться такого эффекта.
Я обновил ссылку выше.
Я положил код на случай, если вы все еще не можете получить детскую площадку
let aView = UIView(frame:CGRect(x:0 y:0 width:200 height:200))
aView.backgroundColor = UIColor.redColor() // the view that needs to be masked
let shapeLayer = CAShapeLayer()
shapeLayer.bounds = aView.bounds
let bezierPath = UIBezierPath()
bezierPath.moveToPoint(CGPoint(x: shapeLayer.bounds.width/2, y: shapeLayer.bounds.height))
bezierPath.addLineToPoint(CGPoint(x: shapeLayer.bounds.width/2, y: 0))
shapeLayer.path = bezierPath.CGPath
shapeLayer.fillColor = UIColor.clearColor().CGColor
shapeLayer.strokeColor = UIColor.redColor().CGColor
shapeLayer.lineWidth = shapeLayer.bounds.width
shapeLayer.position = CGPoint(x: aView.frame.width/2, y: aView.frame.height/2)
shapeLayer.strokeEnd = 1
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.fromValue = 0
animation.toValue = 1
animation.duration = 4
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
shapeLayer.addAnimation(animation, forKey: "stroneAnimation")
shapeLayer.strokeEnd = 1
aView.layer.mask = shapeLayer
Проверь это!!
let path = UIBezierPath(rect: CGRectMake(0, denterImage.frame.origin.y, denterImage.bounds.size.width, denterImage.bounds.size.height - 200))
let mask = CAShapeLayer()
mask.anchorPoint = CGPointMake(0.5, 1.0)
mask.path = path.CGPath
denterImage.layer.mask = mask
let anim = CABasicAnimation(keyPath: "path")
anim.fromValue = path.CGPath
anim.toValue = UIBezierPath(rect: denterImage.bounds).CGPath
anim.duration = 1.5
anim.fillMode = kCAFillModeForwards
anim.removedOnCompletion = false
denterImage.layer.mask.addAnimation(anim, forKey: "anim")
Есть (2) варианты, которые приходят на ум.
Одним из них является просто переключение анимации с и на значения:
let path = UIBezierPath(rect: CGRectMake(0, 0, imgEmptyBase.width, imgEmptyBase.height - 80))
let mask = CAShapeLayer()
mask.anchorPoint = CGPointMake(0.5, 1.0)
mask.path = path.CGPath
imgEmptyBase.layer.mask = mask
let anim = CABasicAnimation(keyPath: "path")
anim.fromValue = UIBezierPath(rect: imgEmptyBase.bounds).CGPath
anim.toValue = path.CGPath
anim.duration = 1.0
anim.fillMode = kCAFillModeForwards
anim.removedOnCompletion = false
imgEmptyBase.layer.mask.addAnimation(anim, forKey: "anim")
Другой заключается в том, чтобы переключать сами объявления пути Безье:
let path = UIBezierPath(rect: imgEmptyBase.bounds).CGPath
let mask = CAShapeLayer()
mask.anchorPoint = CGPointMake(0.5, 1.0)
mask.path = path.CGPath
imgEmptyBase.layer.mask = mask
let anim = CABasicAnimation(keyPath: "path")
anim.fromValue = path.CGPath
anim.toValue = UIBezierPath(rect: CGRectMake(0, 0, imgEmptyBase.width, imgEmptyBase.height - 80))
anim.duration = 1.0
anim.fillMode = kCAFillModeForwards
anim.removedOnCompletion = false
imgEmptyBase.layer.mask.addAnimation(anim, forKey: "anim")