iOS贝赛尔曲线全集 之商品加入购物车过程动画
当物品加入购物车时,为了更好地用户体验,我们需要将整个过程呈现到用户眼前。有更酷更有趣的效果;这其中我们需要用到UIBezierPath(贝赛尔曲线)。通过UIBezierPath可以生动的展示出运动轨迹。
下面我们将通过代码进行讲解整个实现过程用到的iOS的技术点:
UIBezierPath的简介
可以先定义一个全局的UIBezierPath。
@interface BKAnimationGoods ()
@property (nonatomic,strong) UIBezierPath *path;
@end
UIBezierPath对象是CGPathRef数据类型的封装。path如果是基于矢量形状的,都用直线和曲线段去创建。我们使用直线段去创建矩形和多边形,使用曲线段去创建弧(arc),圆或者其他复杂的曲线形状。每一段都包括一个或者多个点,绘图命令定义如何去诠释这些点。每一个直线段或者曲线段的结束的地方是下一个的开始的地方。每一个连接的直线或者曲线段的集合成为subpath。一个UIBezierPath对象定义一个完整的路径包括一个或者多个subpaths。
创建和使用一个path对象的过程是分开的。创建path是第一步,包含一下步骤:
(1)创建一个Bezier path对象。
(2)使用方法moveToPoint:去设置初始线段的起点。
(3)添加line或者curve去定义一个或者多个subpaths。
(4)改变UIBezierPath对象跟绘图相关的属性。
//用法一:
self.path = [UIBezierPath bezierPath];
//开始动画的点;
[_path moveToPoint:self.fromPoint];
[_path addQuadCurveToPoint:self.toPoint controlPoint:CGPointMake(self.fromPoint.x,self.toPoint.y)];
//用法二:
self.path = [UIBezierPath bezierPath];
self.path.lineWidth = 5.0;
self.path.lineCapStyle = kCGLineCapRound; //线条拐角
self.path.lineJoinStyle = kCGLineCapRound; //终点处理
// Set the starting point of the shape.
[self.path moveToPoint:CGPointMake(100.0, 0.0)];
// Draw the lines
[self.path addLineToPoint:CGPointMake(200.0, 40.0)];
[self.path addLineToPoint:CGPointMake(160, 140)];
[self.path addLineToPoint:CGPointMake(40.0, 140)];
[self.path addLineToPoint:CGPointMake(0.0, 40.0)];
[self.path closePath];//第五条线通过调用closePath方法得到的
[self.path stroke];//Draws line 根据坐标点连线
[self.path fill];//根据坐标填充颜色;
方法解释
- (void)addCurveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2
Parameters
切线图解.jpeg
参考博客
- (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint;
图片解释.png
添加动画
- CAKeyframeAnimation简单介绍
CAKeyframeAnimation是CApropertyAnimation的子类,跟CABasicAnimation的区别是:CABasicAnimation只能从一个数值(fromValue)变到另一个数值(toValue),而CAKeyframeAnimation会使用一个NSArray保存这些数值
-
属性解析:
-
values:就是上述的NSArray对象。里面的元素称为”关键帧”(keyframe)。动画对象会在指定的时间(duration)内,依次显示values数组中的每一个关键帧
-
path:可以设置一个CGPathRef\CGMutablePathRef,让层跟着路径移动。path只对CALayer的anchorPoint和position起作用。如果你设置了path,那么values将被忽略
-
keyTimes:可以为对应的关键帧指定对应的时间点,其取值范围为0到1.0,keyTimes中的每一个时间值都对应values中的每一帧.当keyTimes没有设置的时候,各个关键帧的时间是平分的
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
//将路径添加到动画中
animation.path = _path.CGPath;
animation.rotationMode = kCAAnimationRotateAuto;
- transform.rotation.x 围绕x轴翻转 参数:角度 angle2Radian(4)
transform.rotation.y 围绕y轴翻转 参数:同上
transform.rotation.z 围绕z轴翻转 参数:同上
transform.rotation 默认围绕z轴
transform.scale.x x方向缩放 参数:缩放比例 1.5
transform.scale.y y方向缩放 参数:同上
transform.scale.z z方向缩放 参数:同上
transform.scale 所有方向缩放 参数:同上
transform.translation.x x方向移动 参数:x轴上的坐标 100
transform.translation.y x方向移动 参数:y轴上的坐标
transform.translation.z x方向移动 参数:z轴上的坐标
transform.translation 移动 参数:移动到的点 (100,100)
opacity 透明度 参数:透明度 0.5
backgroundColor 背景颜色 参数:颜色 (id)[[UIColor redColor] CGColor]
cornerRadius 圆角 参数:圆角半径 5
borderWidth 边框宽度 参数:边框宽度 5
bounds 大小 参数:CGRect
contents 内容 参数:CGImage
contentsRect 可视内容 参数:CGRect 值是0~1之间的小数
hidden 是否隐藏
//旋转动画
CABasicAnimation* rotationAnimation =
[CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];//"z"还可以是“x”“y”,表示沿z轴旋转
rotationAnimation.toValue = [NSNumber numberWithFloat:(2 * M_PI) * 10];
rotationAnimation.duration = 1.3f;
rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
//抖动动画 即大小变化
CABasicAnimation *buyCarAnimation_1 = [CABasicAnimation animationWithKeyPath:@"transform"];
buyCarAnimation_1.beginTime =CACurrentMediaTime() + 1.1f;
//是否恢复
buyCarAnimation_1.autoreverses = YES;
buyCarAnimation_1.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.5, 1.5, 1)];
buyCarAnimation_1.delegate = self;
// 1 kCAMediaTimingFunctionLinear//线性
// 2 kCAMediaTimingFunctionEaseIn//淡入
// 3 kCAMediaTimingFunctionEaseOut//淡出
// 4 kCAMediaTimingFunctionEaseInEaseOut//淡入淡出
// 5 kCAMediaTimingFunctionDefault//默认
[buyCarAnimation_1 setTimingFunction:[CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseInEaseOut]];
buyCarAnimation_1.removedOnCompletion = YES;
// 重复次数
buyCarAnimation_1.repeatCount = 1;
buyCarAnimation_1.duration = 0.2f;
[_buyCarButton.layer addAnimation:buyCarAnimation_1 forKey:@"groups_buyCar"];
/// 可能用到的
// 1 const kCAAnimationLinear//线性,默认
// 2 const kCAAnimationDiscrete//离散,无中间过程,但keyTimes设置的时间依旧生效,物体跳跃地出现在各个关键帧上
// 3 const kCAAnimationPaced//平均,keyTimes跟timeFunctions失效
// 4 const kCAAnimationCubic//平均,同上
// 5 const kCAAnimationCubicPaced//平均,同上
///当多组动画需组合出现时可用:
CAAnimationGroup *groups = [CAAnimationGroup animation];
groups.animations = @[animation,expandAnimation,narrowAnimation,rotationAnimation];
groups.duration = 1.3f;
groups.removedOnCompletion=NO;
groups.fillMode=kCAFillModeForwards;
groups.delegate = self;
[_layer addAnimation:groups forKey:@"group"];
扫尾工作
//动画的代理方法
-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
if (anim == [_layer animationForKey:@"group"]) {
[_layer removeFromSuperlayer];
_layer = nil;
_clickButton.userInteractionEnabled = YES;
}
if (anim == [_buyCarButton.layer animationForKey:@"groups_buyCar"]) {
[_buyCarButton.layer removeFromSuperlayer];
}
}
补充:物理仿真行为(添加仿真元素)-->吸附行为UISnapBehavior
实现了动画的物理抖动效果(按钮的抖动动画),以后有时间将把物理iOS仿真进行详尽的解说🔥
// 2 创建物理仿真行为(添加仿真元素)-->吸附行为
UISnapBehavior *snap = [[UISnapBehavior alloc] initWithItem:self.Button snapToPoint:point];
// 常用属性
// 防抖系数 0到1 抖动效果逐渐变弱;
snap.damping = 0.1f;
// 3 将仿真元素添加到仿真器中
[self.animator removeAllBehaviors];
[self.animator addBehavior:snap];
点我点我点我哦.png
扫码技术交流🔥
等你来哦.jpg