尝试在UIView上屏蔽椭圆,以进行比例变换,保留在中心位置。
我找到了CALayer - CABasicAnimation not scaling around center/anchorPoint,然后向bounds
maskLayer
添加了CAShapeLayer
属性,但是,结果是掩码只位于左角1/4显示。我希望面具保持在屏幕的中心。
@synthesize maskedView;
- (void)viewDidLoad
{
[super viewDidLoad];
UIViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:@"Next"];
vc.view.frame = CGRectMake(0,0, self.view.frame.size.width, self.view.frame.size.height);
vc.view.layer.bounds = self.view.layer.bounds;
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
CGRect maskRect = CGRectMake((self.view.frame.size.width/2)-50, (self.view.frame.size.height/2)-50, 100, 100);
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddEllipseInRect(path, nil, maskRect);
[maskLayer setPath:path];
CGPathRelease(path);
vc.view.layer.mask = maskLayer;
[self.view addSubview:vc.view];
maskedView = vc.view;
[self startAnimation];
}
...动画
-(void)startAnimation
{
maskedView.layer.mask.bounds = CGRectMake((self.view.frame.size.width/2)-50, (self.view.frame.size.height/2)-50, 100, 100);
maskedView.layer.mask.anchorPoint = CGPointMake(.5,.5);
maskedView.layer.mask.contentsGravity = @"center";
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
animation.duration = 1.0f;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation.fromValue = [NSNumber numberWithFloat:1.0f];
animation.toValue = [NSNumber numberWithFloat:5.0f];
[maskedView.layer.mask addAnimation:animation forKey:@"animateMask"];
}
更新
我好像用position
键上的第二个动画修复了这个问题。这是正确的还是更好的方法呢?
CABasicAnimation *animation2 = [CABasicAnimation animationWithKeyPath:@"position"];
animation2.duration = 1.0f;
animation2.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation2.fromValue = [NSValue valueWithCGPoint:CGPointMake((self.view.frame.size.width/2), (self.view.frame.size.height/2))];
animation2.toValue = [NSValue valueWithCGPoint:CGPointMake((self.view.frame.size.width/2), (self.view.frame.size.height/2))];
[toBeMask.layer.mask addAnimation:animation2 forKey:@"animateMask2"];
答案 0 :(得分:18)
您可以围绕对象的中心创建缩放而不是(0,0),如下所示:
CABasicAnimation *scale = [CABasicAnimation animationWithKeyPath:@"transform"];
CATransform3D tr = CATransform3DIdentity;
tr = CATransform3DTranslate(tr, self.bounds.size.width/2, self.bounds.size.height/2, 0);
tr = CATransform3DScale(tr, 3, 3, 1);
tr = CATransform3DTranslate(tr, -self.bounds.size.width/2, -self.bounds.size.height/2, 0);
scale.toValue = [NSValue valueWithCATransform3D:tr];
所以我们从"身份"开始变换(意味着没有变换')。然后我们翻译(移动)到对象的中心。然后我们扩展。然后我们回到origo,所以我们回到了我们开始的地方(我们只想影响规模操作)。
答案 1 :(得分:5)
我不确定原因,但CAShapeLayer没有为图层设置bounds属性。就我而言,那就是问题所在。 尝试设置边界。这应该有用。
我做了类似的事情来构建初始圈
html, body {
height: 100%;
padding: 0;
margin: 0;
}
.container {
height: 100%;
background: url(link/to/image) center center;
background-size: cover;
// Use prefixes
}
.inner-container {
background-color: rgba(255, 255, 255, 0.6);
color: #000;
width: 500px;
margin: 60px auto;
}
以及缩放它的类似内容
self.circle = [CAShapeLayer layer];
CGRect roundedRect = CGRectMake(0, 0, width, width);
self.circle.bounds = roundedRect;
UIBezierPath *start = [UIBezierPath bezierPathWithRoundedRect:roundedRect cornerRadius:width/2];
[self.circle setPath:start.CGPath];
self.circle.position = CGPointMake(whatever suits you);
self.circleView.layer.mask = self.circle;
[self.circleView.layer.mask setValue: @(1) forKeyPath: @"transform.scale"];
PD:根据苹果文件,AnchorPoint默认为(.5,.5)......但我们都知道这并不意味着什么?
希望它有所帮助!!
答案 2 :(得分:4)
我好像用位置键上的第二个动画修复了这个问题。这是正确的还是更好的方法呢?
CABasicAnimation *animation2 = [CABasicAnimation animationWithKeyPath:@"position"];
animation2.duration = 1.0f;
animation2.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation2.fromValue = [NSValue valueWithCGPoint:CGPointMake((self.view.frame.size.width/2), (self.view.frame.size.height/2))];
animation2.toValue = [NSValue valueWithCGPoint:CGPointMake((self.view.frame.size.width/2), (self.view.frame.size.height/2))];
[toBeMask.layer.mask addAnimation:animation2 forKey:@"animateMask2"];
答案 3 :(得分:4)
我已经编写了以下函数,其中包含许多附加的调整和选项,对许多其他人都有用。
func layerScaleAnimation(layer: CALayer, duration: CFTimeInterval, fromValue: CGFloat, toValue: CGFloat) {
let timing = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)
let scaleAnimation: CABasicAnimation = CABasicAnimation(keyPath: "transform.scale")
CATransaction.begin()
CATransaction.setAnimationTimingFunction(timing)
scaleAnimation.duration = duration
scaleAnimation.fromValue = fromValue
scaleAnimation.toValue = toValue
layer.add(scaleAnimation, forKey: "scale")
CATransaction.commit()
}
注意:不要忘记在动画完成后更新尺寸,因为CATransaction会恢复到实际尺寸。