微信小视频下拉时眼睛动画:WeChatEye
jopen
9年前
微信小视频下拉时眼睛动画
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; } } }