iOS的纸折(折纸/手风琴)效果动画,具有手动控制 [英] iOS Paper fold (origami / accordion) effect animation, with manual control

查看:1147
本文介绍了iOS的纸折(折纸/手风琴)效果动画,具有手动控制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找关于如何实现流行的折纸/折纸在我的iOS项目效果的提示。

I'm looking for tips on how to implement the popular 'paper folding / origami' effect in my iOS project.

我所知道的项目,如:
https://github.com/xyfeng/XYOrigami
但他们只提供了动画的效果,比开场动画没有手动控制。

I'm aware of projects such as: https://github.com/xyfeng/XYOrigami but they only offer the 'animated' effect, with no manual control over the opening animation.

我一直在努力剖析该项目,并拿出我后。

I've struggled to dissect that project and come up with what I'm after.

要更准确,我正在寻找关于如何实现这里显示的效果: http://vimeo.com/41495357 其中,折叠动画不是简单动画打开,但用户控制所述开口折

To be more exact, I'm looking on how to implement the effect shown here: http://vimeo.com/41495357 where the folding animation is not simply animated open, but the user controls the opening folds.

任何帮助将是非常美联社preciated,在此先感谢!

Any help would be much appreciated, thanks in advance!

编辑:

好吧,这里的一些例子code更好地说明什么,我挣扎:

Okay, here's some example code to better illustrate what I'm struggling with:

此方法触发折纸效果动画:

This method triggers the origami effect animation:

- (void)showOrigamiTransitionWith:(UIView *)view 
                NumberOfFolds:(NSInteger)folds 
                     Duration:(CGFloat)duration
                    Direction:(XYOrigamiDirection)direction
                   completion:(void (^)(BOOL finished))completion
{

if (XY_Origami_Current_State != XYOrigamiTransitionStateIdle) {
    return;
}
XY_Origami_Current_State = XYOrigamiTransitionStateUpdate;

//add view as parent subview
if (![view superview]) {
    [[self superview] insertSubview:view belowSubview:self];
}


//set frame
CGRect selfFrame = self.frame;
CGPoint anchorPoint;
if (direction == XYOrigamiDirectionFromRight) {

    selfFrame.origin.x = self.frame.origin.x - view.bounds.size.width;

    view.frame = CGRectMake(self.frame.origin.x+self.frame.size.width-view.frame.size.width, self.frame.origin.y, view.frame.size.width, view.frame.size.height);

    anchorPoint = CGPointMake(1, 0.5);
}
else {
    selfFrame.origin.x = self.frame.origin.x + view.bounds.size.width;
    view.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, view.frame.size.width, view.frame.size.height);

    anchorPoint = CGPointMake(0, 0.5);
}

UIGraphicsBeginImageContext(view.frame.size);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewSnapShot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

//set 3D depth
CATransform3D transform = CATransform3DIdentity;
transform.m34 = -1.0/800.0;
CALayer *origamiLayer = [CALayer layer];
origamiLayer.frame = view.bounds;
origamiLayer.backgroundColor = [UIColor colorWithWhite:0.2 alpha:1].CGColor;
origamiLayer.sublayerTransform = transform;
[view.layer addSublayer:origamiLayer];






//setup rotation angle
double startAngle;
CGFloat frameWidth = view.bounds.size.width;
CGFloat frameHeight = view.bounds.size.height;
CGFloat foldWidth = frameWidth/(folds*2);
CALayer *prevLayer = origamiLayer;
for (int b=0; b < folds*2; b++) {
    CGRect imageFrame;
    if (direction == XYOrigamiDirectionFromRight) {
        if(b == 0)
            startAngle = -M_PI_2;
        else {
            if (b%2)
                startAngle = M_PI;
            else
                startAngle = -M_PI;
        }
        imageFrame = CGRectMake(frameWidth-(b+1)*foldWidth, 0, foldWidth, frameHeight);
    }
    else {
        if(b == 0)
            startAngle = M_PI_2;
        else {
            if (b%2)
                startAngle = -M_PI;
            else
                startAngle = M_PI;
        }
        imageFrame = CGRectMake(b*foldWidth, 0, foldWidth, frameHeight);
    }
    CATransformLayer *transLayer = [self transformLayerFromImage:viewSnapShot Frame:imageFrame Duration:duration AnchorPiont:anchorPoint StartAngle:startAngle EndAngle:0];
    [prevLayer addSublayer:transLayer];
    prevLayer = transLayer;
}

[CATransaction begin];
[CATransaction setCompletionBlock:^{
    self.frame = selfFrame;
    [origamiLayer removeFromSuperlayer];
    XY_Origami_Current_State = XYOrigamiTransitionStateShow;

    if (completion)
        completion(YES);
}];

[CATransaction setValue:[NSNumber numberWithFloat:duration] forKey:kCATransactionAnimationDuration];
CAAnimation *openAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position.x" function:openFunction fromValue:self.frame.origin.x+self.frame.size.width/2 toValue:selfFrame.origin.x+self.frame.size.width/2];
openAnimation.fillMode = kCAFillModeForwards;
[openAnimation setRemovedOnCompletion:NO];
[self.layer addAnimation:openAnimation forKey:@"position"];
[CATransaction commit];
}

该方法从这个方法抓起CATransform层:

The method grabs a CATransform Layer from this method:

- (CATransformLayer *)transformLayerFromImage:(UIImage *)image Frame:(CGRect)frame Duration:(CGFloat)duration AnchorPiont:(CGPoint)anchorPoint StartAngle:(double)start EndAngle:(double)end;
{
CATransformLayer *jointLayer = [CATransformLayer layer];
jointLayer.anchorPoint = anchorPoint;
CGFloat layerWidth;
if (anchorPoint.x == 0) //from left to right
{
    layerWidth = image.size.width - frame.origin.x;
    jointLayer.frame = CGRectMake(0, 0, layerWidth, frame.size.height);
    if (frame.origin.x) {
        jointLayer.position = CGPointMake(frame.size.width, frame.size.height/2);
    }
    else {
        jointLayer.position = CGPointMake(0, frame.size.height/2);
    }
}
else 
{ //from right to left
    layerWidth = frame.origin.x + frame.size.width;
    jointLayer.frame = CGRectMake(0, 0, layerWidth, frame.size.height);
    jointLayer.position = CGPointMake(layerWidth, frame.size.height/2);
}

//map image onto transform layer
CALayer *imageLayer = [CALayer layer];
imageLayer.frame = CGRectMake(0, 0, frame.size.width, frame.size.height);
imageLayer.anchorPoint = anchorPoint;
imageLayer.position = CGPointMake(layerWidth*anchorPoint.x, frame.size.height/2);
[jointLayer addSublayer:imageLayer];
CGImageRef imageCrop = CGImageCreateWithImageInRect(image.CGImage, frame);
imageLayer.contents = (__bridge id)imageCrop;
imageLayer.backgroundColor = [UIColor clearColor].CGColor;

//add shadow
NSInteger index = frame.origin.x/frame.size.width;
double shadowAniOpacity;
CAGradientLayer *shadowLayer = [CAGradientLayer layer];
shadowLayer.frame = imageLayer.bounds;
shadowLayer.backgroundColor = [UIColor darkGrayColor].CGColor;
shadowLayer.opacity = 0.0;
shadowLayer.colors = [NSArray arrayWithObjects:(id)[UIColor blackColor].CGColor, (id)[UIColor clearColor].CGColor, nil];
if (index%2) {
    shadowLayer.startPoint = CGPointMake(0, 0.5);
    shadowLayer.endPoint = CGPointMake(1, 0.5);
    shadowAniOpacity = (anchorPoint.x)?0.24:0.32;
}
else {
    shadowLayer.startPoint = CGPointMake(1, 0.5);
    shadowLayer.endPoint = CGPointMake(0, 0.5);
    shadowAniOpacity = (anchorPoint.x)?0.32:0.24;
}
[imageLayer addSublayer:shadowLayer];


//animate open/close animation
CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
[animation setDuration:duration];
[animation setFromValue:[NSNumber numberWithDouble:start]];
[animation setToValue:[NSNumber numberWithDouble:end]];
[animation setRemovedOnCompletion:NO];
[jointLayer addAnimation:animation forKey:@"jointAnimation"];



//animate shadow opacity
animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
[animation setDuration:duration];
[animation setFromValue:[NSNumber numberWithDouble:(start)?shadowAniOpacity:0]];
[animation setToValue:[NSNumber numberWithDouble:(start)?0:shadowAniOpacity]];
[animation setRemovedOnCompletion:NO];
[shadowLayer addAnimation:animation forKey:nil];

return jointLayer;
}

基本上,我需要删除自动动画,并控制使用一些手动设定值影响的研究进展(例如:uislider值或内容偏移)。

Basically, I need to remove the automatic animation, and control the progress of the effect using some manually set value (e.g.: uislider value, or content offset).

再一次提供任何帮助是非常AP preciated!

Once again, any help provided is much appreciated!

推荐答案

我写的折叠过渡另一个库: https://github.com / geraldhuard / YFoldView

I write another library for folding transition : https://github.com/geraldhuard/YFoldView

希望它为你工作。

这篇关于iOS的纸折(折纸/手风琴)效果动画,具有手动控制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆