gpt4 book ai didi

iphone - 使用 CATransform3D 透视的折纸过渡

转载 作者:行者123 更新时间:2023-12-03 18:31:34 24 4
gpt4 key购买 nike

我正在尝试仅使用图层功能在两个 UIView 上实现一种折纸过渡。这个想法是折叠两个具有透视效果的 View 。两个 View 都有一个透视图,过渡是通过每个 View 上的旋转以及一个 View 上的平移来定义的,这样该 View 似乎附加到另一个 View 上。

问题在于 View 在转换过程中相互重叠。我不想使用 zPosition 在视觉上避免这种重叠,我真的希望这两个 View 表现得好像它们通过共享的一面绑定(bind)在一起。这是转换的代码。

有什么想法或其他解决方案吗?

Overlapping views during transition

- (void)animateWithPerspective
{
CGFloat rotationAngle = 90;
CATransform3D transform = CATransform3DIdentity;
UIView *topView;
UIView *bottomView;
UIView *mainView;
CGRect frame;
CGFloat size = 200;

mainView = [[UIView alloc] initWithFrame:CGRectMake(10,10, size, size*2)];
[self.view addSubview:mainView];
bottomView = [[UIView alloc] initWithFrame:CGRectZero];
bottomView.layer.anchorPoint = CGPointMake(0.5, 1);
bottomView.frame = CGRectMake(0, size, size, size);
bottomView.backgroundColor = [UIColor blueColor];
[mainView addSubview:bottomView];

topView = [[UIView alloc] initWithFrame:CGRectZero];
topView.layer.anchorPoint = CGPointMake(0.5, 0);
topView.frame = CGRectMake(0, 0, size, size);
topView.backgroundColor = [UIColor redColor];
[mainView addSubview:topView];

transform.m34 = 1.0/700.0;
topView.layer.transform = transform;
bottomView.layer.transform = transform;

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:2];
[UIView setAnimationRepeatAutoreverses:YES];
[UIView setAnimationRepeatCount:INFINITY];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
frame = bottomView.frame;
frame.origin.y = bottomView.frame.origin.y - bottomView.frame.size.height - topView.frame.size.height;
bottomView.frame = frame;
topView.layer.transform = CATransform3DRotate(transform, rotationAngle * M_PI/180, 1, 0, 0);
bottomView.layer.transform = CATransform3DRotate(transform, -rotationAngle * M_PI/180, 1, 0, 0);
[UIView commitAnimations];
}

- (void)viewDidLoad
{
[super viewDidLoad];
[self animate];
}

为了简化问题,让我们去掉任何透视变换。这是具有相同问题的更简单的代码:

- (void)animateWithoutPerspective
{
CGFloat rotationAngle = 90;
UIView *topView;
UIView *bottomView;
UIView *mainView;
CGRect frame;
CGFloat size = 200;

mainView = [[UIView alloc] initWithFrame:CGRectMake(10,10, size, size*2)];
[self.view addSubview:mainView];
bottomView = [[UIView alloc] initWithFrame:CGRectMake(0, size, size, size)];
bottomView.backgroundColor = [UIColor blueColor];
[mainView addSubview:bottomView];

topView = [[UIView alloc] initWithFrame:CGRectZero];
topView.layer.anchorPoint = CGPointMake(0.5, 0);
topView.frame = CGRectMake(10, 0, size-20, size);
topView.backgroundColor = [UIColor redColor];
[mainView addSubview:topView];

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:2];
[UIView setAnimationRepeatAutoreverses:YES];
[UIView setAnimationRepeatCount:INFINITY];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
frame = bottomView.frame;
frame.origin.y = bottomView.frame.origin.y - bottomView.frame.size.height;
bottomView.frame = frame;
topView.layer.transform = CATransform3DMakeRotation(rotationAngle * M_PI/180, 1, 0, 0);
[UIView commitAnimations];
}

最佳答案

最后,这是添加简单阴影的三袖动画的一些解决方案。解决这种动画的关键是使用几个组织良好的子图层以及一些CATransformLayer

- (void)animate
{
CATransform3D transform = CATransform3DIdentity;
CALayer *topSleeve;
CALayer *middleSleeve;
CALayer *bottomSleeve;
CALayer *topShadow;
CALayer *middleShadow;
UIView *mainView;
CGFloat width = 300;
CGFloat height = 150;
CALayer *firstJointLayer;
CALayer *secondJointLayer;
CALayer *perspectiveLayer;

mainView = [[UIView alloc] initWithFrame:CGRectMake(50, 50, width, height*3)];
mainView.backgroundColor = [UIColor yellowColor];
[self.view addSubview:mainView];

perspectiveLayer = [CALayer layer];
perspectiveLayer.frame = CGRectMake(0, 0, width, height*2);
[mainView.layer addSublayer:perspectiveLayer];

firstJointLayer = [CATransformLayer layer];
firstJointLayer.frame = mainView.bounds;
[perspectiveLayer addSublayer:firstJointLayer];

topSleeve = [CALayer layer];
topSleeve.frame = CGRectMake(0, 0, width, height);
topSleeve.anchorPoint = CGPointMake(0.5, 0);
topSleeve.backgroundColor = [UIColor redColor].CGColor;
topSleeve.position = CGPointMake(width/2, 0);
[firstJointLayer addSublayer:topSleeve];
topSleeve.masksToBounds = YES;

secondJointLayer = [CATransformLayer layer];
secondJointLayer.frame = mainView.bounds;
secondJointLayer.frame = CGRectMake(0, 0, width, height*2);
secondJointLayer.anchorPoint = CGPointMake(0.5, 0);
secondJointLayer.position = CGPointMake(width/2, height);
[firstJointLayer addSublayer:secondJointLayer];

middleSleeve = [CALayer layer];
middleSleeve.frame = CGRectMake(0, 0, width, height);
middleSleeve.anchorPoint = CGPointMake(0.5, 0);
middleSleeve.backgroundColor = [UIColor blueColor].CGColor;
middleSleeve.position = CGPointMake(width/2, 0);
[secondJointLayer addSublayer:middleSleeve];
middleSleeve.masksToBounds = YES;

bottomSleeve = [CALayer layer];
bottomSleeve.frame = CGRectMake(0, height, width, height);
bottomSleeve.anchorPoint = CGPointMake(0.5, 0);
bottomSleeve.backgroundColor = [UIColor grayColor].CGColor;
bottomSleeve.position = CGPointMake(width/2, height);
[secondJointLayer addSublayer:bottomSleeve];

firstJointLayer.anchorPoint = CGPointMake(0.5, 0);
firstJointLayer.position = CGPointMake(width/2, 0);

topShadow = [CALayer layer];
[topSleeve addSublayer:topShadow];
topShadow.frame = topSleeve.bounds;
topShadow.backgroundColor = [UIColor blackColor].CGColor;
topShadow.opacity = 0;

middleShadow = [CALayer layer];
[middleSleeve addSublayer:middleShadow];
middleShadow.frame = middleSleeve.bounds;
middleShadow.backgroundColor = [UIColor blackColor].CGColor;
middleShadow.opacity = 0;

transform.m34 = -1.0/700.0;
perspectiveLayer.sublayerTransform = transform;

CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.x"];
[animation setDuration:2];
[animation setAutoreverses:YES];
[animation setRepeatCount:INFINITY];
[animation setFromValue:[NSNumber numberWithDouble:0]];
[animation setToValue:[NSNumber numberWithDouble:-90*M_PI/180]];
[firstJointLayer addAnimation:animation forKey:nil];

animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.x"];
[animation setDuration:2];
[animation setAutoreverses:YES];
[animation setRepeatCount:INFINITY];
[animation setFromValue:[NSNumber numberWithDouble:0]];
[animation setToValue:[NSNumber numberWithDouble:180*M_PI/180]];
[secondJointLayer addAnimation:animation forKey:nil];

animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.x"];
[animation setDuration:2];
[animation setAutoreverses:YES];
[animation setRepeatCount:INFINITY];
[animation setFromValue:[NSNumber numberWithDouble:0]];
[animation setToValue:[NSNumber numberWithDouble:-90*M_PI/180]];
[bottomSleeve addAnimation:animation forKey:nil];

animation = [CABasicAnimation animationWithKeyPath:@"bounds.size.height"];
[animation setDuration:2];
[animation setAutoreverses:YES];
[animation setRepeatCount:INFINITY];
[animation setFromValue:[NSNumber numberWithDouble:perspectiveLayer.bounds.size.height]];
[animation setToValue:[NSNumber numberWithDouble:0]];
[perspectiveLayer addAnimation:animation forKey:nil];

animation = [CABasicAnimation animationWithKeyPath:@"position.y"];
[animation setDuration:2];
[animation setAutoreverses:YES];
[animation setRepeatCount:INFINITY];
[animation setFromValue:[NSNumber numberWithDouble:perspectiveLayer.position.y]];
[animation setToValue:[NSNumber numberWithDouble:0]];
[perspectiveLayer addAnimation:animation forKey:nil];

animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
[animation setDuration:2];
[animation setAutoreverses:YES];
[animation setRepeatCount:INFINITY];
[animation setFromValue:[NSNumber numberWithDouble:0]];
[animation setToValue:[NSNumber numberWithDouble:0.5]];
[topShadow addAnimation:animation forKey:nil];

animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
[animation setDuration:2];
[animation setAutoreverses:YES];
[animation setRepeatCount:INFINITY];
[animation setFromValue:[NSNumber numberWithDouble:0]];
[animation setToValue:[NSNumber numberWithDouble:0.5]];
[middleShadow addAnimation:animation forKey:nil];
}

关于iphone - 使用 CATransform3D 透视的折纸过渡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5456642/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com