在不提供透视图并保持高度和宽度的情况下倾斜 UIView
skew UIView without giving perspective and keeping heigh and width
嗨,
我正在尝试像图像中那样实现转换,但我使用 CGATransform3D 只获得了类似的转换,但具有透视(我不想要)。我如何使用 objective-c 实现此目的?转换后的图像应与原始图像具有相同的高度和宽度,但底部倾斜给定角度。
在此先感谢您的帮助。
这是一种“剪切”或“倾斜”变换。幸运的是,剪切变换是仿射变换,iOS 支持 UIView
和 CALayer
级别的仿射变换。但是,它没有构建剪切变换的便利函数,所以我们写一个:
static CGAffineTransform affineTransformMakeShear(CGFloat xShear, CGFloat yShear) {
return CGAffineTransformMake(1, yShear, xShear, 1, 0, 0);
}
xShear
和 yShear
的确切含义并不明显。 xShear
是y轴倾斜角度的正切,yShear
是x轴倾斜角度的正切。这可能看起来倒退,但它具有您期望的视觉效果:非零 xShear
使图形向左或向右倾斜,非零 yShear
使图形向上或向下倾斜。
因为 tan π/4 = 1(或者,如果您愿意,tan 45° = 1),affineTransformMakeShear(1, 0)
返回的变换将矩形变成左右边缘位于 π/ 的平行四边形4 弧度(或 45°)。
演示:
请注意,两个轴上的剪切可以等同于旋转和缩放的组合。
这是我的演示代码:
#import "ViewController.h"
@interface ViewController ()
@property (strong, nonatomic) IBOutlet UIView *shearedView;
@property (strong, nonatomic) IBOutlet UISlider *verticalShearSlider;
@property (strong, nonatomic) IBOutlet UISlider *horizontalShearSlider;
@property (strong, nonatomic) IBOutlet UILabel *verticalShearLabel;
@property (strong, nonatomic) IBOutlet UILabel *horizontalShearLabel;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self updateAppearance:nil];
}
static CGAffineTransform affineTransformMakeShear(CGFloat xShear, CGFloat yShear) {
return CGAffineTransformMake(1, yShear, xShear, 1, 0, 0);
}
- (IBAction)updateAppearance:(id)sender {
CGFloat xShear = self.horizontalShearSlider.value;
CGFloat yShear = self.verticalShearSlider.value;
self.shearedView.transform = affineTransformMakeShear(xShear, yShear);
self.horizontalShearLabel.text = [NSString stringWithFormat:@"%.2f", xShear];
self.verticalShearLabel.text = [NSString stringWithFormat:@"%.2f", yShear];
}
@end
我正在尝试像图像中那样实现转换,但我使用 CGATransform3D 只获得了类似的转换,但具有透视(我不想要)。我如何使用 objective-c 实现此目的?转换后的图像应与原始图像具有相同的高度和宽度,但底部倾斜给定角度。
在此先感谢您的帮助。
这是一种“剪切”或“倾斜”变换。幸运的是,剪切变换是仿射变换,iOS 支持 UIView
和 CALayer
级别的仿射变换。但是,它没有构建剪切变换的便利函数,所以我们写一个:
static CGAffineTransform affineTransformMakeShear(CGFloat xShear, CGFloat yShear) {
return CGAffineTransformMake(1, yShear, xShear, 1, 0, 0);
}
xShear
和 yShear
的确切含义并不明显。 xShear
是y轴倾斜角度的正切,yShear
是x轴倾斜角度的正切。这可能看起来倒退,但它具有您期望的视觉效果:非零 xShear
使图形向左或向右倾斜,非零 yShear
使图形向上或向下倾斜。
因为 tan π/4 = 1(或者,如果您愿意,tan 45° = 1),affineTransformMakeShear(1, 0)
返回的变换将矩形变成左右边缘位于 π/ 的平行四边形4 弧度(或 45°)。
演示:
请注意,两个轴上的剪切可以等同于旋转和缩放的组合。
这是我的演示代码:
#import "ViewController.h"
@interface ViewController ()
@property (strong, nonatomic) IBOutlet UIView *shearedView;
@property (strong, nonatomic) IBOutlet UISlider *verticalShearSlider;
@property (strong, nonatomic) IBOutlet UISlider *horizontalShearSlider;
@property (strong, nonatomic) IBOutlet UILabel *verticalShearLabel;
@property (strong, nonatomic) IBOutlet UILabel *horizontalShearLabel;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self updateAppearance:nil];
}
static CGAffineTransform affineTransformMakeShear(CGFloat xShear, CGFloat yShear) {
return CGAffineTransformMake(1, yShear, xShear, 1, 0, 0);
}
- (IBAction)updateAppearance:(id)sender {
CGFloat xShear = self.horizontalShearSlider.value;
CGFloat yShear = self.verticalShearSlider.value;
self.shearedView.transform = affineTransformMakeShear(xShear, yShear);
self.horizontalShearLabel.text = [NSString stringWithFormat:@"%.2f", xShear];
self.verticalShearLabel.text = [NSString stringWithFormat:@"%.2f", yShear];
}
@end