mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
215 lines
6.7 KiB
Objective-C
215 lines
6.7 KiB
Objective-C
#import "TGVideoMessageRingView.h"
|
|
|
|
#import "TGColor.h"
|
|
|
|
#import "LegacyComponentsInternal.h"
|
|
|
|
@interface TGVideoMessageShimmerEffectForegroundView : UIView
|
|
{
|
|
UIView *_imageContainerView;
|
|
UIView *_imageView;
|
|
|
|
CGFloat _size;
|
|
bool _hasContainerSize;
|
|
CGRect _absoluteRect;
|
|
CGSize _containerSize;
|
|
}
|
|
|
|
- (instancetype)initWithSize:(CGFloat)size alpha:(CGFloat)alpha;
|
|
|
|
@end
|
|
|
|
@implementation TGVideoMessageShimmerEffectForegroundView
|
|
|
|
- (instancetype)initWithSize:(CGFloat)size alpha:(CGFloat)alpha {
|
|
self = [super initWithFrame:CGRectZero];
|
|
if (self != nil) {
|
|
_size = size;
|
|
|
|
_imageContainerView = [[UIView alloc] init];
|
|
_imageView = [[UIView alloc] init];
|
|
|
|
self.clipsToBounds = true;
|
|
|
|
[_imageContainerView addSubview:_imageView];
|
|
[self addSubview:_imageContainerView];
|
|
|
|
UIGraphicsBeginImageContextWithOptions(CGSizeMake(size, 16), false, 0.0f);
|
|
CGContextRef context = UIGraphicsGetCurrentContext();
|
|
|
|
CGRect bounds = CGRectMake(0, 0, size, 16);
|
|
CGContextClearRect(context, bounds);
|
|
CGContextClipToRect(context, bounds);
|
|
|
|
UIColor *transparentColor = [UIColor colorWithWhite:1.0 alpha:0.0];
|
|
UIColor *peakColor = [UIColor colorWithWhite:1.0 alpha:alpha];
|
|
|
|
CGColorRef colors[3] = {
|
|
CGColorRetain(transparentColor.CGColor),
|
|
CGColorRetain(peakColor.CGColor),
|
|
CGColorRetain(transparentColor.CGColor)
|
|
};
|
|
|
|
CFArrayRef colorsArray = CFArrayCreate(kCFAllocatorDefault, (const void **)&colors, 3, NULL);
|
|
CGFloat locations[3] = {0.0f, 0.5, 1.0};
|
|
|
|
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
|
|
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, colorsArray, (CGFloat const *)&locations);
|
|
|
|
CGContextDrawLinearGradient(context, gradient, CGPointMake(0, 0), CGPointMake(size, 0), kNilOptions);
|
|
|
|
CFRelease(colorsArray);
|
|
CFRelease(colors[0]);
|
|
CFRelease(colors[1]);
|
|
|
|
CGColorSpaceRelease(colorSpace);
|
|
CFRelease(gradient);
|
|
|
|
UIImage *image = [UIGraphicsGetImageFromCurrentImageContext() stretchableImageWithLeftCapWidth:25 topCapHeight:25];
|
|
UIGraphicsEndImageContext();
|
|
|
|
_imageView.backgroundColor = [UIColor colorWithPatternImage:image];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)updateAbsoluteRect:(CGRect)absoluteRect containerSize:(CGSize)containerSize {
|
|
_hasContainerSize = true;
|
|
|
|
CGRect previousAbsoluteRect = _absoluteRect;
|
|
CGSize previousContainerSize = _containerSize;
|
|
_absoluteRect = absoluteRect;
|
|
_containerSize = containerSize;
|
|
|
|
if (!CGSizeEqualToSize(previousContainerSize, containerSize)) {
|
|
[self setupAnimation];
|
|
}
|
|
|
|
if (!CGRectEqualToRect(previousAbsoluteRect, absoluteRect)) {
|
|
_imageContainerView.frame = CGRectMake(-absoluteRect.origin.x, -absoluteRect.origin.y, containerSize.width, containerSize.height);
|
|
}
|
|
}
|
|
|
|
|
|
- (void)setupAnimation {
|
|
if (!_hasContainerSize) {
|
|
return;
|
|
}
|
|
|
|
CGFloat gradientHeight = _size;
|
|
_imageView.frame = CGRectMake(-gradientHeight, 0, gradientHeight, _containerSize.height);
|
|
|
|
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position.x"];
|
|
animation.fromValue = @(_imageView.center.x);
|
|
animation.toValue = @(_imageView.center.x + _containerSize.width + gradientHeight);
|
|
animation.duration = 1.3f;
|
|
animation.repeatCount = INFINITY;
|
|
animation.beginTime = 1.0;
|
|
[_imageView.layer addAnimation:animation forKey:@"position"];
|
|
}
|
|
|
|
@end
|
|
|
|
@interface TGVideoMessageShimmerView ()
|
|
{
|
|
TGVideoMessageShimmerEffectForegroundView *_effectView;
|
|
UIImageView *_imageView;
|
|
|
|
UIView *_borderView;
|
|
UIView *_borderMaskView;
|
|
TGVideoMessageShimmerEffectForegroundView *_borderEffectView;
|
|
}
|
|
@end
|
|
|
|
@implementation TGVideoMessageShimmerView
|
|
|
|
- (instancetype)initWithFrame:(CGRect)frame {
|
|
self = [super initWithFrame:frame];
|
|
if (self != nil) {
|
|
self.clipsToBounds = true;
|
|
self.layer.cornerRadius = frame.size.width / 2.0f;
|
|
if (@available(iOS 13.0, *)) {
|
|
self.layer.cornerCurve = kCACornerCurveCircular;
|
|
}
|
|
|
|
_effectView = [[TGVideoMessageShimmerEffectForegroundView alloc] initWithSize:320 alpha:0.3];
|
|
_effectView.layer.compositingFilter = @"screenBlendMode";
|
|
_effectView.frame = self.bounds;
|
|
|
|
_borderView = [[UIView alloc] initWithFrame:self.bounds];
|
|
_borderMaskView = [[UIView alloc] initWithFrame:self.bounds];
|
|
_borderMaskView.layer.borderWidth = 1.0;
|
|
_borderMaskView.layer.borderColor = [UIColor whiteColor].CGColor;
|
|
_borderMaskView.layer.cornerRadius = frame.size.width / 2.0f;
|
|
if (@available(iOS 13.0, *)) {
|
|
_borderMaskView.layer.cornerCurve = kCACornerCurveCircular;
|
|
}
|
|
_borderView.maskView = _borderMaskView;
|
|
|
|
_borderEffectView = [[TGVideoMessageShimmerEffectForegroundView alloc] initWithSize:400 alpha:0.45];
|
|
_borderEffectView.layer.compositingFilter = @"screenBlendMode";
|
|
_borderEffectView.frame = self.bounds;
|
|
|
|
[self addSubview:_effectView];
|
|
[self addSubview:_borderView];
|
|
[_borderView addSubview:_borderEffectView];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)updateAbsoluteRect:(CGRect)absoluteRect containerSize:(CGSize)containerSize {
|
|
[_effectView updateAbsoluteRect:absoluteRect containerSize:containerSize];
|
|
[_borderEffectView updateAbsoluteRect:absoluteRect containerSize:containerSize];
|
|
}
|
|
|
|
@end
|
|
|
|
@interface TGVideoMessageRingView ()
|
|
{
|
|
CGFloat _value;
|
|
}
|
|
@end
|
|
|
|
@implementation TGVideoMessageRingView
|
|
|
|
- (instancetype)initWithFrame:(CGRect)frame
|
|
{
|
|
self = [super initWithFrame:frame];
|
|
if (self != nil)
|
|
{
|
|
self.backgroundColor = [UIColor clearColor];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)setValue:(CGFloat)value
|
|
{
|
|
_value = value;
|
|
[self setNeedsDisplay];
|
|
}
|
|
|
|
- (void)drawRect:(CGRect)rect
|
|
{
|
|
if (_value < DBL_EPSILON)
|
|
return;
|
|
|
|
CGContextRef context = UIGraphicsGetCurrentContext();
|
|
CGContextSetFillColorWithColor(context, self.accentColor.CGColor);
|
|
|
|
CGMutablePathRef path = CGPathCreateMutable();
|
|
CGPoint centerPoint = CGPointMake(rect.size.width / 2.0f, rect.size.height / 2.0f);
|
|
CGFloat lineWidth = 4.0f;
|
|
|
|
CGPathAddArc(path, NULL, centerPoint.x, centerPoint.y, rect.size.width / 2.0f - lineWidth / 2.0f, -M_PI_2, -M_PI_2 + 2 * M_PI * _value, false);
|
|
|
|
CGPathRef strokedArc = CGPathCreateCopyByStrokingPath(path, NULL, lineWidth, kCGLineCapRound, kCGLineJoinMiter, 10);
|
|
CGPathRelease(path);
|
|
|
|
CGContextAddPath(context, strokedArc);
|
|
CGPathRelease(strokedArc);
|
|
|
|
CGContextFillPath(context);
|
|
}
|
|
|
|
@end
|