仿抖音点赞按钮

阅读: 评论:0

仿抖音点赞按钮

仿抖音点赞按钮

每一个图形,都是通过一点点拼接到一起的,而每一个动画亦然,只需要将动画和图形进行拆解,就不难了。

模仿下抖音点赞按钮的动画效果。

拆解一下动画效果。

  • 红色爱心逐渐变大的过程,并伴随着有左右旋转的效果。
  • 与此同时,伴随着六个扇形块向外扩散的效果。
  • 再次点击时,红色爱心旋转45°,逐渐变小。

具体实现

1、通过 UIBezierPath 实现爱心的上半部分。

let rect = CGRect(x: 10, y: 10, width: frame.width - 20, height: frame.height - 20)
//距离左右两边的距离
let padding: CGFloat = 4
let radius = (rect.size.width - 2 * padding) / 2.0 / (cos(CGFloat.pi / 4) + 1)
let heartPath = UIBezierPath()
//左圆的圆心
let leftCurveCenter = CGPoint(x: padding + radius, y: rect.size.height / 2.8)
//画左圆
heartPath.addArc(withCenter: leftCurveCenter, radius: radius,startAngle: CGFloat.pi, endAngle: CGFloat.pi * -0.25,clockwise: true)
//右圆圆心
let rightCurveCenter = CGPoint(x: rect.width - padding - radius, y: leftCurveCenter.y)
//画右圆
heartPath.addArc(withCenter: rightCurveCenter, radius: radius,startAngle: CGFloat.pi * -0.75, endAngle: 0,clockwise: true)let shapeLayer = CAShapeLayer()
shapeLayer.path = Path
shapeLayer.frame = rect
复制代码

爱心的上半部分是由两个 3/4 圆, 圆半径的计算公式: (width - padding * 2) / 2 = radius + radius * cos45°,可得出 radius = (width - padding * 2) / 2 / (cos45° + 1),此公式是根据两个半圆交点的切线呈 90°

2、通过 UIBezierPath 完成爱心的下半部分。其中爱心尖的位置,为整个 UIButton 的底部中心点

//爱心尖的坐标点
let apexPoint = CGPoint(x: rect.width / 2, y: rect.height - padding)
//画右半边曲线
heartPath.addQuadCurve(to: apexPoint,controlPoint: CGPoint(x: heartPath.currentPoint.x,y: radius + rect.size.height / 2.8))
//画左半边曲线
heartPath.addQuadCurve(to: CGPoint(x: padding, y: leftCurveCenter.y),controlPoint: CGPoint(x: padding,y: radius + rect.size.height / 2.8))
复制代码

3、此处采用两个 layer 层,一个为白色的爱心,一个为红色的爱心。通过白色爱心隐藏,红色爱心逐渐变大,并伴随左右旋转。放大的动画执行完,旋转的动画还未执行完,所以放大的动画时间相对短一些

//放大动画
let animation = CABasicAnimation.init(keyPath: "transform.scale")
animation.duration = 1 * 0.8
animation.fromValue = 0.1
Value = 1//旋转动画
let keyAnimation = CAKeyframeAnimation.init(keyPath: &#ation.z")
keyAnimation.values = [CGFloat.pi * -0.25, 0, CGFloat.pi * 0.1, CGFloat.pi * -0.05, 0]
keyAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeOut)
keyAnimation.duration = 1//合成动画组
let groupAnimation = CAAnimationGroup()
groupAnimation.duration = 1
groupAnimation.delegate = self
groupAnimation.animations = [keyAnimation, animation]
redHeartLayer.isHidden = false
hollowHeartLayer.isHidden = true
redHeartLayer.add(groupAnimation, forKey: nil)
复制代码

4、显示白色的爱心,红色爱心向左旋转45°,并且伴随着缩小,其中旋转动画的时间比缩小动画的时间短

//缩小动画
let animation = CABasicAnimation(keyPath: "transform.scale")
animation.duration = 1
animation.fromValue = 1
Value = 0//旋转动画
let keyAnimation = CAKeyframeAnimation.init(keyPath: &#ation.z")
keyAnimation.values = [0, CGFloat.pi * -0.25]
keyAnimation.fillMode = .forwards
keyAnimation.duration = 1 * 0.4
let groupAnimation = CAAnimationGroup()//合成动画组
groupAnimation.duration = 1
groupAnimation.delegate = self
groupAnimation.animations = [keyAnimation, animation]
groupAnimation.fillMode = .forwards
groupAnimation.isRemovedOnCompletion = false
hollowHeartLayer.isHidden = false
redHeartLayer.add(groupAnimation, forKey: nil)
复制代码

4、六条扇形

 let fanCenter = CGPoint(x: frame.width / 2, y: frame.height / 2)for i in 0..<6 {let path = UIBezierPath()//添加扇形圆弧。path.addArc(withCenter: fanCenter,radius: frame.width / 2,startAngle: CGFloat.pi / 2 + (CGFloat.pi / 3) * CGFloat(i) - (CGFloat.pi / 72),endAngle: CGFloat.pi / 2 + CGFloat.pi / 3 * CGFloat(i) + CGFloat.pi / 72,clockwise: true)//与中心点相连path.addLine(to: fanCenter)path.close()let fanLayer = CAShapeLayer()fanLayer.path = PathfanLayer.fillColor = ColorfanLayer.frame = boundslayer.addSublayer(fanLayer)animationLayers.append(fanLayer)}
复制代码

勾画出六个扇形框,再设置 fillColor

5、扇形扩散动画 通过中心点位置位移到扇形圆弧位置,以达到扩散的效果

let fanAnimation = CABasicAnimation(keyPath: "position")
fanAnimation.duration = animationDuration
fanAnimation.fromValue = CGPoint(x: frame.width / 2, y: frame.height / 2)
Value = path.currentPoint
fanAnimation.isRemovedOnCompletion = false
fanAnimation.delegate = self
fanAnimation.fillMode = .both
fanLayer.add(lineAnimation, forKey: nil)
复制代码

6、看着效果有问题,需要给 UIButton加上蒙层,以达到扇形图层逐渐消失的感觉,并且在动画结束的时候将扇形图层移除

//移除扇形图层func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {for animationLayer in animationLayers {veFromSuperlayer()veAllAnimations()}veAll()}//添加蒙层fileprivate func configurationMaskLayer() {let maskPath = UIBezierPath(roundedRect: bounds,cornerRadius: frame.width / 2)let maskLayer = CAShapeLayer()maskLayer.path = Pathlayer.mask = maskLayer
}
复制代码

7、将爱心动画和扇形动画合在一起

下面附上 完整Demo

如果有更好的方法欢迎讨论。

本文发布于:2024-01-31 04:17:36,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170664585625393.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:按钮   仿抖音点赞
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23