Cœur
Cœur

Reputation: 38667

Achieve a trapezoid transform with CATransform3D

I'd like to change an UIView from:

         o---o
         |   |
         |   |
         |   |
         |   |
         |   |
         o---o

To:

            /o
           / |
         o/  |
         |   |
         o\  |
           \ |
            \o

Forgive my ascii art. I mean to change a rectangular background to a trapezoid background, with:

I tried this:

CATransform3D sublayerTransform = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, .005, 0, 0, 0, 1 };
self.backgroundView.layer.superlayer.sublayerTransform = sublayerTransform;
CATransform3D layerTransform = CATransform3DMakeRotation(M_PI/4., 0, 1, 0);
self.backgroundView.layer.transform = layerTransform;

The result is a trapezoid, but it has not the desired constraints.

Upvotes: 1

Views: 844

Answers (2)

Cœur
Cœur

Reputation: 38667

I was able to easily achieve the right CATransform3D using AGGeometryKit.

#import <AGGeometryKit/AGGeometryKit.h>

UIView *view = ...; // create a view

// setting anchorPoint to zero
view.layer.anchorPoint = CGPointZero;
view.layer.transform = CATransform3DMakeTranslation(-view.layer.bounds.size.width * .5, -view.layer.bounds.size.height * .5, 0);

// setting a trapezoid transform
AGKQuad quad = view.layer.quadrilateral;
quad.tl.y += 10; // shift top left y-value with 10 pixels
quad.bl.y -= 10; // shift bottom left y-value with 10 pixels
view.layer.quadrilateral = quad; // the quad is converted to CATransform3D and applied

Upvotes: 0

MDB983
MDB983

Reputation: 2454

Take a look at the CATrasnsform3D matrix, in your case, you really only need to set the .m34.

Keep in mind that CATransform3DRotate takes radians as one of it's argument which is defined as follows;

  float Degrees2Radians(float degrees) { return degrees * M_PI / 180; }

Try the following;

  CATransform3D transform = CATransform3DIdentity;
  transform.m34 = -1.0f /450.0f; 

  // set y to  negative for effect on left(as in your diagram), positive for effect on right
  transform = CATransform3DRotate(transform, Degrees2Radians(45) , 0.0f, -1.0f, 0.0f);

  // you'll need to do this translate to shift the layer to compensate for  the rotation
  transform = CATransform3DTranslate(transform, -70.0f, 0.0f, -50.0f);

then obviously set the target layers transform to the above transform

Upvotes: 2

Related Questions