Curving/warping views with CoreAnimation or OpenGL for carousel effect

你离开我真会死。 提交于 2019-12-05 03:21:47

In my experience, it is a bit tricky to get the values right. The way to give a view perspective is by manipulating it's layer transform. I have used the following method to achieve the transfor for a similar effect:

-(CATransform3D)makeTransformForAngle:(CGFloat)angle from:(CATransform3D)start{

    CATransform3D transform = start;


    // the following two lines are the key to achieve the perspective effect
CATransform3D persp = CATransform3DIdentity;
    persp.m34 = 1.0 / -1000;

    transform = CATransform3DConcat(transform, persp);
        transform = CATransform3DRotate(transform,angle, 0.0, 1.0, 0.0);
    return transform;
}

This was done to create a "flip page" animation, so you may need to adapt. To use it, do the following:

flip_page.layer.transform = [self makeTransformForAngle:angle from:CATransform3DIdentity];

where flip_page is a UIView. Cheers!

If you want to warp the views, you'll either need OpenGL or you could use Core Animation's CAShapLayer which allows you to specify a bezier path which can have this curve in it. But keep in mind that this curving you're seeing is likely just an optical illusion (though in your image above it looks like an actual curve). If you get enough rectangles with the correct y axis rotation in a row, I think you can come up with the effect you're looking for with straight Core Animation. I'm pretty sure that's how things are implemented in the Core Animation demos Apple provided a couple years ago. Here's a screenshot from the video from that presentation:

I messed around with the transform of a view's layer a little bit and came up with this:

- (IBAction)sliderDidChange:(id)sender
{
  CGFloat value = [(UISlider*)sender value];
  CGFloat xOff = value - 0.5;

  CATransform3D trans = CATransform3DIdentity;
  trans.m34 = 1.0f / -1000.0f;

  trans = CATransform3DRotate(trans, degreesToRadians(xOff * -25.0f), 0.0f, 1.0f, 0.0f);
  trans = CATransform3DTranslate(trans, 0.0f, 0.0f, 900.0f * fabs(xOff));
  [[frameView layer] setTransform:trans];

  CGPoint center= [frameView center];
  [frameView setCenter:CGPointMake(1024.0 * value, center.y)];
}

I threw together a demo project that shows how the rotation works in response to a slider. It doesn't use a scroll view so you would have to adapt it, but I think you can track the current scroll offset and apply the transform accordingly. Not sure if it will help but there it is.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!