微信小视频下拉时眼睛动画:WeChatEye

jopen 8年前

微信小视频下拉时眼睛动画

Demo

Basic

首先你得画出这只眼睛,这是眼睛包括5个部分组成

@property (strong, nonatomic) CAShapeLayer *eyeFirstLightLayer;  @property (strong, nonatomic) CAShapeLayer *eyeSecondLightLayer;  @property (strong, nonatomic) CAShapeLayer *eyeballLayer;  @property (strong, nonatomic) CAShapeLayer *topEyesocketLayer;  @property (strong, nonatomic) CAShapeLayer *bottomEyesocketLayer;

然后,还是通过 UIBezierPath 和 CAShapeLayer 这样的老套路来画,代码较多

- (CAShapeLayer *)eyeFirstLightLayer {      if (!_eyeFirstLightLayer) {          _eyeFirstLightLayer = [CAShapeLayer layer];          CGPoint center = CGPointMake(CGRectGetWidth(self.frame) / 2, CGRectGetHeight(self.frame) / 2);          UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center                                                              radius:CGRectGetWidth(self.frame) * 0.2                                                          startAngle:(230.f / 180.f) * M_PI                                                            endAngle:(265.f / 180.f) * M_PI                                                           clockwise:YES];          _eyeFirstLightLayer.borderColor = [UIColor blackColor].CGColor;          _eyeFirstLightLayer.lineWidth = 5.f;          _eyeFirstLightLayer.path = path.CGPath;          _eyeFirstLightLayer.fillColor = [UIColor clearColor].CGColor;          _eyeFirstLightLayer.strokeColor = [UIColor whiteColor].CGColor;      }      return _eyeFirstLightLayer;  }    - (CAShapeLayer *)eyeSecondLightLayer {      if (!_eyeSecondLightLayer) {          _eyeSecondLightLayer = [CAShapeLayer layer];          CGPoint center = CGPointMake(CGRectGetWidth(self.frame) / 2, CGRectGetHeight(self.frame) / 2);          UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center                                                              radius:CGRectGetWidth(self.frame) * 0.2                                                          startAngle:(211.f / 180.f) * M_PI                                                            endAngle:(220.f / 180.f) * M_PI                                                           clockwise:YES];          _eyeSecondLightLayer.borderColor = [UIColor blackColor].CGColor;          _eyeSecondLightLayer.lineWidth = 5.f;          _eyeSecondLightLayer.path = path.CGPath;          _eyeSecondLightLayer.fillColor = [UIColor clearColor].CGColor;          _eyeSecondLightLayer.strokeColor = [UIColor whiteColor].CGColor;        }      return _eyeSecondLightLayer;  }    - (CAShapeLayer *)eyeballLayer {      if (!_eyeballLayer) {          _eyeballLayer = [CAShapeLayer layer];          CGPoint center = CGPointMake(CGRectGetWidth(self.frame) / 2, CGRectGetHeight(self.frame) / 2);          UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center                                                              radius:CGRectGetWidth(self.frame) * 0.3                                                          startAngle:(0.f / 180.f) * M_PI                                                            endAngle:(360.f / 180.f) * M_PI                                                           clockwise:YES];          _eyeballLayer.borderColor = [UIColor blackColor].CGColor;          _eyeballLayer.lineWidth = 1.f;          _eyeballLayer.path = path.CGPath;          _eyeballLayer.fillColor = [UIColor clearColor].CGColor;          _eyeballLayer.strokeColor = [UIColor whiteColor].CGColor;          _eyeballLayer.anchorPoint = CGPointMake(0.5, 0.5);        }      return _eyeballLayer;  }    - (CAShapeLayer *)topEyesocketLayer {      if (!_topEyesocketLayer) {          _topEyesocketLayer = [CAShapeLayer layer];          CGPoint center = CGPointMake(CGRectGetWidth(self.frame) / 2, CGRectGetHeight(self.frame) / 2);          UIBezierPath *path = [UIBezierPath bezierPath];          [path moveToPoint:CGPointMake(0, CGRectGetHeight(self.frame) / 2)];          [path addQuadCurveToPoint:CGPointMake(CGRectGetWidth(self.frame), CGRectGetHeight(self.frame) / 2)                       controlPoint:CGPointMake(CGRectGetWidth(self.frame) / 2, center.y - center.y - 20)];          _topEyesocketLayer.borderColor = [UIColor blackColor].CGColor;          _topEyesocketLayer.lineWidth = 1.f;          _topEyesocketLayer.path = path.CGPath;          _topEyesocketLayer.fillColor = [UIColor clearColor].CGColor;          _topEyesocketLayer.strokeColor = [UIColor whiteColor].CGColor;      }      return _topEyesocketLayer;  }    - (CAShapeLayer *)bottomEyesocketLayer {      if (!_bottomEyesocketLayer) {          _bottomEyesocketLayer = [CAShapeLayer layer];          CGPoint center = CGPointMake(CGRectGetWidth(self.frame) / 2, CGRectGetHeight(self.frame) / 2);          UIBezierPath *path = [UIBezierPath bezierPath];          [path moveToPoint:CGPointMake(0, CGRectGetHeight(self.frame) / 2)];          [path addQuadCurveToPoint:CGPointMake(CGRectGetWidth(self.frame), CGRectGetHeight(self.frame) / 2)                       controlPoint:CGPointMake(CGRectGetWidth(self.frame) / 2, center.y + center.y + 20)];          _bottomEyesocketLayer.borderColor = [UIColor blackColor].CGColor;          _bottomEyesocketLayer.lineWidth = 1.f;          _bottomEyesocketLayer.path = path.CGPath;          _bottomEyesocketLayer.fillColor = [UIColor clearColor].CGColor;          _bottomEyesocketLayer.strokeColor = [UIColor whiteColor].CGColor;        }      return _bottomEyesocketLayer;  }

然后更改一下某些属性的值,方便稍后的动画
- (void)setupAnimation {      self.eyeFirstLightLayer.lineWidth = 0.f;      self.eyeSecondLightLayer.lineWidth = 0.f;      self.eyeballLayer.opacity = 0.f;      _bottomEyesocketLayer.strokeStart = 0.5f;      _bottomEyesocketLayer.strokeEnd = 0.5f;      _topEyesocketLayer.strokeStart = 0.5f;      _topEyesocketLayer.strokeEnd = 0.5f;  }

最后根据 UIScrollView 的 contentOffset 来控制各种属性,办法较笨,但管用。

- (void)animationWith:(CGFloat)y {      CGFloat flag = self.frame.origin.y * 2.f - 20.f;      if (y < flag) {          if (self.eyeFirstLightLayer.lineWidth < 5.f) {              self.eyeFirstLightLayer.lineWidth += 1.f;              self.eyeSecondLightLayer.lineWidth += 1.f;          }      }        if(y < flag - 20) {          if (self.eyeballLayer.opacity <= 1.0f) {              self.eyeballLayer.opacity += 0.1f;          }        }        if (y < flag - 40) {          if (self.topEyesocketLayer.strokeEnd < 1.f && self.topEyesocketLayer.strokeStart > 0.f) {              self.topEyesocketLayer.strokeEnd += 0.1f;              self.topEyesocketLayer.strokeStart -= 0.1f;              self.bottomEyesocketLayer.strokeEnd += 0.1f;              self.bottomEyesocketLayer.strokeStart -= 0.1f;          }      }        if (y > flag - 40) {          if (self.topEyesocketLayer.strokeEnd > 0.5f && self.topEyesocketLayer.strokeStart < 0.5f) {              self.topEyesocketLayer.strokeEnd -= 0.1f;              self.topEyesocketLayer.strokeStart += 0.1f;              self.bottomEyesocketLayer.strokeEnd -= 0.1f;              self.bottomEyesocketLayer.strokeStart += 0.1f;          }      }        if (y > flag - 20) {          if (self.eyeballLayer.opacity >= 0.0f) {              self.eyeballLayer.opacity -= 0.1f;          }      }        if (y > flag) {          if (self.eyeFirstLightLayer.lineWidth > 0.f) {              self.eyeFirstLightLayer.lineWidth -= 1.f;              self.eyeSecondLightLayer.lineWidth -= 1.f;          }      }  }

项目主页:http://www.open-open.com/lib/view/home/1449109352998