资讯

精准传达 • 有效沟通

从品牌网站建设到网络营销策划,从策略到执行的一站式服务

ios开发图片旋转,ios如何旋转图片

iOS 图片的同时旋转缩放

最近项目中的一个小需求,要求图片同时进行旋转和缩放两种操作,做一个简单的总结,先看下效果图:

创新互联专注于固镇企业网站建设,响应式网站开发,商城建设。固镇网站建设公司,为固镇等地区提供建站服务。全流程按需求定制开发,专业设计,全程项目跟踪,创新互联专业和态度为您提供的服务

originalPoint 为旋转缩放的参考点比例,默认是按视图中心旋转,即

self.originalPoint = CGPointMake(0.5, 0.5)

然后就是正常的操作,注意,在缩放的时候,四个角的控制按钮要相反的放缩,保证大小不变,如果有其他元素,同理。

在控制按钮上添加平移手势,记录每一次平移的点 ctrlPoint ,以及上一个平移点,就是 self.lastCtrlPoint

旋转的角度,根据上一个平移点和视图中心点的角度,与当前平移点和视图中心点的角度偏差,进行transform处理。

缩放也是类似,计算上一个平移点与中心点的距离 preDistance ,以及当前平移点和中心点的距离 newDistance ,那么两次平移距离的比例,就是视图缩放的比例。这里做了一个判断,在缩小到一半时停止继续变小。

GitHub:

ios图片旋转

根据Orientation判断图片的方向,在把图片旋转回来

1:0°,

3:180°

6:顺时针90°,

8:逆时针90°

也可以利用 exif.js快速处理

iOS核心动画之图片旋转、脉冲动画、水波纹动画

下边有整体效果,希望能帮助到你!

定义一个视图

@property (weak, nonatomic) IBOutlet UIImageView *imageView;

一、图片旋转三种方式:

第一种:根据CGPathAddArc 绘画图片旋转路线:

/*

1、#CGMutablePathRef  _Nullable path# 路线

2、确定圆心#CGFloat x# #CGFloat y#

3、半径#CGFloat radius#

4、起点 #CGFloat startAngle# 结束 #CGFloat endAngle#

*/

CGPathAddArc(path, NULL, self.view.center.x, self.view.center.y, 0.1, 0, M_PI *2, 1);

CAKeyframeAnimation * frameAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];

frameAnimation.path= path;

CGPathRelease(path);

frameAnimation.delegate=self;

frameAnimation.duration=10;// 持续时间

frameAnimation.repeatCount = -1;// 重复次数 如果为0表示不执行,-1表示不限制次数,默认为0

frameAnimation.autoreverses=NO;

frameAnimation.rotationMode = kCAAnimationRotateAuto;// 样式

frameAnimation.fillMode = kCAFillModeForwards;

[self.imageView.layeraddAnimation:frameAnimationforKey:nil];

第二种:

[UIView animateWithDuration:20.0f animations:^{

    if (self.imageView) {

       self.imageView.transform = CGAffineTransformMakeRotation(M_PI*5);

 }

}];

第三种:

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];

//默认是顺时针效果,若将fromValue和toValue的值互换,则为逆时针效果

animation.fromValue = [NSNumber numberWithFloat:0.f];

animation.toValue = [NSNumber numberWithFloat: M_PI *2];

animation.duration=30;

animation.autoreverses=NO;

animation.fillMode = kCAFillModeForwards;

animation.repeatCount = MAXFLOAT; //如果这里想设置成一直自旋转,可以设置为MAXFLOAT,否则设置具体的数值则代表执行多少次

[self.imageView.layer addAnimation:animation forKey:nil];

持续旋转:

@property(nonatomic,assign) double angle;

CGAffineTransform endAngle = CGAffineTransformMakeRotation(self.angle * (M_PI / 180.0f));

[UIView animateWithDuration:0.01 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{

    self.imageView.transform= endAngle;

}completion:^(BOOLfinished) {

    self.angle+=10;

    [self startAnimation2];// 上边任意一种方法回调

}];

// 当视图停止转动时调用此方法重新转动

-(void)endAnimation {

self.angle+=4;

[self startAnimation2];

}

二、水波纹动画

属性定义:几个波纹定义几个X 宽度可以用一个 也可以分开定义

@property (weak, nonatomic) IBOutlet UIView *backView;

@property(nonatomic,strong) CAShapeLayer * waterLayer1;

@property(nonatomic,strong) CAShapeLayer * waterLayer2;

@property(nonatomic,assign) CGFloat x;

@property(nonatomic,assign) CGFloat y;

@property(nonatomic,assign) CGFloat waveHeight;

@property(nonatomic,assign) CGFloat waveWidth;

@property(nonatomic,assign) int speedWave;

@property(nonatomic,assign) CGFloat waveAmplitude;

@property(nonatomic,assign) int speed;

@property(nonatomic,assign) CGFloat speed_H;

@property(nonatomic,assign) CGFloat offsetXT;

-(instancetype)init {// 给个初始值,下边被除数不能为0

if (self == [super init]) {

self.speedWave = 3;

self.waveAmplitude = 3;

self.speed=3;

self.waveWidth = self.backView.frame.size.width;

self.waveHeight = self.backView.frame.size.height;

self.speed_H = self.backView.frame.size.height-20;

}

return self;

}

-(void)waterAnimation {

//    CGFloat y = _waveHeight*sinf(2.5*M_PI*i/_waveWidth + 3*_offset*M_PI/_waveWidth + M_PI/4) + _h;

self.waterLayer1 = [CAShapeLayer layer];

self.waterLayer1.fillColor = [UIColor yellowColor].CGColor;

[self.backView.layer addSublayer:self.waterLayer1];

self.waterLayer2 = [CAShapeLayer layer];

self.waterLayer2.fillColor = [UIColor redColor].CGColor;

[self.backView.layer addSublayer: self.waterLayer2];

//创建一个新的 CADisplayLink 对象,把它添加到一个runloop中,并给它提供一个 target 和selector 在屏幕刷新的时候调用

//CADispayLink相当于一个定时器 会一直绘制曲线波纹 看似在运动,其实是一直在绘画不同位置点的余弦函数曲线

CADisplayLink * waveDisplayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(getCurrentWave)];

[waveDisplayLinkaddToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];

}

-(void)getCurrentWave {

// x位置

self.x+=self.speed;

//声明第一条波曲线的路径

CGMutablePathRef path = CGPathCreateMutable();

//设置起始点

CGPathMoveToPoint(path,nil,0,self.waveHeight);

CGFloaty =0.f;

//第一个波纹的公式

for(floatx =0.f; x =self.waveWidth; x++) {

    y =self.waveAmplitude*sin((200/self.waveWidth) * (x *M_PI/70) -self.x*M_PI/170) +self.speed_H*1;

    CGPathAddLineToPoint(path,nil, x, y);

    x++;

}

//把绘图信息添加到路径里

CGPathAddLineToPoint(path, nil, self.waveWidth, self.backView.frame.size.height);

CGPathAddLineToPoint(path, nil, 0, self.backView.frame.size.height);

//结束绘图信息

CGPathCloseSubpath(path);

self.waterLayer1.path= path;

//释放绘图路径

CGPathRelease(path);

[self    X2];

}

/// 第二条水波

-(void)X2 {

self.offsetXT += self.speedWave;

CGMutablePathRef pathT = CGPathCreateMutable();

CGPathMoveToPoint(pathT,nil,0,self.waveHeight+50);

CGFloatyT =0.f;

for(floatx =0.f; x =self.waveWidth; x++) {

    yT =self.waveAmplitude*1.6*sin((200/self.waveWidth) * (x *M_PI/100) -self.offsetXT*M_PI/170) +self.waveHeight;

    CGPathAddLineToPoint(pathT,nil, x, yT-10);

}

CGPathAddLineToPoint(pathT, nil, self.waveWidth, self.backView.frame.size.height);

CGPathAddLineToPoint(pathT, nil, 0, self.backView.frame.size.height);

CGPathCloseSubpath(pathT);

self.waterLayer2.path= pathT;

CGPathRelease(pathT);

}

三、脉冲效果动画

@property (weak, nonatomic) IBOutlet UIView *pulseView;

@property(nonatomic,strong) CAShapeLayer * pulseLayer;

-(void)pulseAnimation {

CGFloat width = self.pulseView.bounds.size.width;

self.pulseLayer = [CAShapeLayer layer];

self.pulseLayer.bounds=CGRectMake(0,0, width, width);

self.pulseLayer.position=CGPointMake(width/2, width/2);

self.pulseLayer.backgroundColor = [UIColor clearColor].CGColor;

self.pulseLayer.path = [UIBezierPath bezierPathWithOvalInRect:self.pulseLayer.bounds].CGPath;

self.pulseLayer.fillColor = [UIColor colorWithRed: 0.3490196078 green:0.737254902 blue:0.8039215686 alpha:1].CGColor;

self.pulseLayer.opacity = 0.0;

CAReplicatorLayer * replicatorLayer = [CAReplicatorLayer layer];

replicatorLayer.bounds=CGRectMake(0,0, width, width);

replicatorLayer.position=CGPointMake(width/2, width/2);

replicatorLayer.instanceCount=4;// 复制层

replicatorLayer.instanceDelay=1;/// 频率

[replicatorLayeraddSublayer:self.pulseLayer];

[self.pulseView.layeraddSublayer:replicatorLayer];

[self.pulseView.layerinsertSublayer:replicatorLayeratIndex:0];

}

-(void)startPulseAnimation {

CABasicAnimation * opacityAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];

opacityAnimation.fromValue=@20;// 起始值 (strong 修饰的id值)

opacityAnimation.toValue=@30;// 结束值(strong 修饰的id值)

CABasicAnimation * scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];

scaleAnimation.fromValue = [NSValue valueWithCATransform3D:CATransform3DScale(CATransform3DIdentity, 0.0, 0.0, 0.0)];

scaleAnimation.toValue =[NSValue valueWithCATransform3D:CATransform3DScale(CATransform3DIdentity, 1.0, 1.0, 1.0)];

CAAnimationGroup * groupAnimation = [CAAnimationGroup animation];

groupAnimation.animations=@[opacityAnimation, scaleAnimation];

groupAnimation.duration=20;

groupAnimation.autoreverses=NO;

groupAnimation.repeatCount=HUGE;

[self.pulseLayeraddAnimation:groupAnimationforKey:nil];

}

在此附上效果:

听说有好得三方库,我还没有去找过,欢迎各位大佬推荐一个优质的三方。。。。。

喜欢的朋友点个赞呗!


当前名称:ios开发图片旋转,ios如何旋转图片
标题路径:http://cdkjz.cn/article/dsdcoed.html
多年建站经验

多一份参考,总有益处

联系快上网,免费获得专属《策划方案》及报价

咨询相关问题或预约面谈,可以通过以下方式与我们联系

大客户专线   成都:13518219792   座机:028-86922220