iOS-各種動畫特效
阿新 • • 發佈:2019-01-25
一、實現功能
-
1. 廣播跑馬燈
-
2. 彈幕動畫
-
3. 直播點贊動畫
-
4. 直播點贊圖片動畫
-
5. 煙花動畫
-
6. 雪花動畫
二、程式實現
1. 廣播動畫特效:
思路:
1. 初始化廣播檢視
2. 設定廣播公告廣告內容
3. 新增動畫效果
初始化廣播檢視, 廣播活動標題按鈕 與 廣播活動標題標籤 控制元件大小一樣
/** * 設定廣播檢視 */ - (void)setupBroadcastingView { // 設定廣播活動標題按鈕 UIButton *activityBtn = [UIButton buttonWithType:UIButtonTypeCustom]; activityBtn.frame = CGRectMake(0, 64, [UIScreen mainScreen].bounds.size.width, 30); activityBtn.backgroundColor = [UIColor clearColor]; [activityBtn addTarget:self action:@selector(activityDetail) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:activityBtn]; self.activityBtn = activityBtn; // 設定廣播活動標題文字 UILabel *activityLb = [[UILabel alloc] init]; activityLb.frame = activityBtn.bounds; [activityLb setFont:[UIFont boldSystemFontOfSize:14]]; [activityLb setTextColor:[UIColor colorWithRed:115/255.0 green:125/255.0 blue:134/255.0 alpha:1.0]]; [activityLb setBackgroundColor:[UIColor clearColor]]; [activityBtn addSubview:activityLb]; self.activityLb = activityLb; // 設定廣播logo UIImageView *speaker = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[NSString stringWithFormat:@"broadcasting"]]]; speaker.frame = CGRectMake(0, 5, 20, 20); speaker.backgroundColor = self.view.backgroundColor; [activityBtn addSubview:speaker]; // 設定廣播公告廣告內容 [self setActivityButtonTitle]; }
設定廣播公告廣告內容, 這裡是以假資料填充,一般需求會是後臺請求得來的活動內容.
新增動畫效果: 當文字內容超過顯示區域就滾動展示,未超過則居中展示.
/** * 設定廣播公告廣告內容 */ - (void)setActivityButtonTitle { // 廣播公告廣告內容(假資料) NSString *title = @"廣播公告廣告內容(ZL測試內容)廣播公告廣告內容(測試內容)\r\n廣播公告廣告內容(測試內容)廣播公告廣告內容(測試內容)廣播公告廣告內容(測試內容)"; title = [title stringByReplacingOccurrencesOfString:@"\r\n" withString:@" "]; [self.activityLb setText:title]; [self.activityLb sizeToFit]; if (self.activityLb.frame.size.width <= self.activityBtn.frame.size.width) { [self.activityLb setCenter:CGPointMake(self.activityBtn.frame.size.width/2, self.activityBtn.frame.size.height/2)]; } else { // 當文字內容超過顯示區域就滾動展示 CGRect frame = self.activityLb.frame; frame.origin.x = self.activityBtn.frame.size.width; frame.origin.y = self.activityBtn.frame.size.height * 0.5 - self.activityLb.bounds.size.height * 0.5; self.activityLb.frame = frame; [UIView beginAnimations:@"testAnimation" context:NULL]; [UIView setAnimationDuration:frame.size.width/55.f]; [UIView setAnimationCurve:UIViewAnimationCurveLinear]; [UIView setAnimationRepeatAutoreverses:NO]; [UIView setAnimationRepeatCount:INT_MAX]; frame = self.activityLb.frame; frame.origin.x = - frame.size.width; self.activityLb.frame = frame; [UIView commitAnimations]; } }
當有活動連結時,需要新增點選效果; 如果沒則不需要建立按鈕及點選效果.
// 展示活動詳情
- (void)activityDetail {
NSLog(@"點選了廣播活動公告詳情");
}
2. 彈幕動畫特效:
先自定義彈幕標籤ZLScrollLabelView:
.h 檔案露出開始/停止/暫停/恢復彈幕動畫
@interface ZLScrollLabelView : UIView // 代理協議 @property (nonatomic, weak) id <ZLScrollLabelViewDelegate> delegate; // 速度 @property (nonatomic) CGFloat speed; // 方向 @property (nonatomic) ScrollDirectionType barrageDirection; // 容器 - (void)addContentView:(UIView *)view; // 開始 - (void)startAnimation; // 停止 - (void)stopAnimation; // 暫停 - (void)pauseAnimation; // 恢復 - (void)resumeAnimation; @end
.m 檔案初始化:
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
_width = frame.size.width;
_height = frame.size.height;
self.speed = 1.f;
self.barrageDirection = FromLeftType;
self.layer.masksToBounds = YES;
self.animationView = [[UIView alloc] initWithFrame:CGRectMake(_width, 0, _width, _height)];
[self addSubview:self.animationView];
}
return self;
}
- (void)addContentView:(UIView *)view {
[_contentView removeFromSuperview];
view.frame = view.bounds;
_contentView = view;
self.animationView.frame = view.bounds;
[self.animationView addSubview:_contentView];
_animationViewWidth = self.animationView.frame.size.width;
_animationViewHeight = self.animationView.frame.size.height;
}
開始彈幕動畫:
- (void)startAnimation {
[self.animationView.layer removeAnimationForKey:@"animationViewPosition"];
_stoped = NO;
CGPoint pointRightCenter = CGPointMake(_width + _animationViewWidth / 2.f, _animationViewHeight / 2.f);
CGPoint pointLeftCenter = CGPointMake(-_animationViewWidth / 2, _animationViewHeight / 2.f);
CGPoint fromPoint = self.barrageDirection == FromLeftType ? pointRightCenter : pointLeftCenter;
CGPoint toPoint = self.barrageDirection == FromLeftType ? pointLeftCenter : pointRightCenter;
self.animationView.center = fromPoint;
UIBezierPath *movePath = [UIBezierPath bezierPath];
[movePath moveToPoint:fromPoint];
[movePath addLineToPoint:toPoint];
CAKeyframeAnimation *moveAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
moveAnimation.path = movePath.CGPath;
moveAnimation.removedOnCompletion = YES;
moveAnimation.duration = _animationViewWidth / 30.f * (1 / self.speed);
moveAnimation.delegate = self;
[self.animationView.layer addAnimation:moveAnimation forKey:@"animationViewPosition"];
}
停止彈幕動畫:
- (void)stopAnimation {
_stoped = YES;
[self.animationView.layer removeAnimationForKey:@"animationViewPosition"];
}
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
if (self.delegate && [self.delegate respondsToSelector:@selector(barrageView:animationDidStopFinished:)]) {
[self.delegate barrageView:self animationDidStopFinished:flag];
}
if (flag && !_stoped) {
[self startAnimation];
}
}
暫停彈幕動畫:
- (void)pauseAnimation {
[self pauseLayer:self.animationView.layer];
}
- (void)pauseLayer:(CALayer*)layer {
CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
layer.speed = 0.0;
layer.timeOffset = pausedTime;
}
恢復彈幕動畫:
- (void)resumeAnimation {
[self resumeLayer:self.animationView.layer];
}
- (void)resumeLayer:(CALayer*)layer {
CFTimeInterval pausedTime = layer.timeOffset;
layer.speed = 1.0;
layer.timeOffset = 0.0;
layer.beginTime = 0.0;
CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
layer.beginTime = timeSincePause;
}
在所需控制器裡, 新增代理ZLScrollLabelViewDelegate實現開始動畫方法
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.title = @"彈幕動畫";
self.view.backgroundColor = [UIColor grayColor];
ZLScrollLabelView *barrageView0 = [[ZLScrollLabelView alloc] initWithFrame:CGRectMake(0, 104, self.view.frame.size.width, 20)];
barrageView0.delegate = self;
// add
[self.view addSubview:barrageView0];
// text
[barrageView0 addContentView:[self createLabelWithText:@"超喜歡趙麗穎,只因她的踏實!"
textColor:[self randomColor]]];
// start
[barrageView0 startAnimation];
}
代理ZLScrollLabelViewDelegate:
- (UILabel *)createLabelWithText:(NSString *)text textColor:(UIColor *)textColor {
NSString *string = [NSString stringWithFormat:@" %@ ", text];
CGFloat width = [string widthWithStringAttribute:@{NSFontAttributeName : [UIFont systemFontOfSize:14.f]}];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, width, 20)];
label.font = [UIFont systemFontOfSize:14.f];
label.text = string;
label.textColor = textColor;
return label;
}
#pragma mark - ZLScrollLabelViewDelegate
- (void)barrageView:(ZLScrollLabelView *)barrageView animationDidStopFinished:(BOOL)finished {
[barrageView stopAnimation];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[barrageView addContentView:[self createLabelWithText:[self randomString]
textColor:[self randomColor]]];
[barrageView startAnimation];
});
}
- (NSString *)randomString {
NSArray *array = @[@"猜猜我是誰?",
@"哈哈",
@"猜不著吧",
@"我是程式媛",
@"嚕啦啦啦啦~"];
return array[arc4random() % array.count];
}
3. 直播點贊效果
先自定義ZLLiveHeartView,露出liveHeartAnimateInView方法:
- (void)liveHeartAnimateInView:(UIView *)view {
NSTimeInterval totalAnimationDuration = 8;
CGFloat heartSize = CGRectGetWidth(self.bounds);
CGFloat heartCenterX = self.center.x;
CGFloat viewHeight = CGRectGetHeight(view.bounds);
// Pre-Animation setup
self.transform = CGAffineTransformMakeScale(0, 0);
self.alpha = 0;
// Bloom
[UIView animateWithDuration:0.5 delay:0.0 usingSpringWithDamping:0.6 initialSpringVelocity:0.8 options:UIViewAnimationOptionCurveEaseOut animations:^{
self.transform = CGAffineTransformIdentity;
self.alpha = 0.9;
} completion:NULL];
NSInteger i = arc4random_uniform(2);
// -1 OR 1
NSInteger rotationDirection = 1 - (2 * i);
NSInteger rotationFraction = arc4random_uniform(10);
[UIView animateWithDuration:totalAnimationDuration animations:^{
self.transform = CGAffineTransformMakeRotation(rotationDirection * M_PI / (16 + rotationFraction * 0.2));
} completion:NULL];
UIBezierPath *heartTravelPath = [UIBezierPath bezierPath];
[heartTravelPath moveToPoint:self.center];
// random end point
CGPoint endPoint = CGPointMake(heartCenterX + (rotationDirection) * arc4random_uniform(2 * heartSize), viewHeight/6.0 + arc4random_uniform(viewHeight / 4.0));
// random Control Points
NSInteger j = arc4random_uniform(2);
NSInteger travelDirection = 1- (2*j);
// randomize x and y for control points
CGFloat xDelta = (heartSize/2.0 + arc4random_uniform(2*heartSize)) * travelDirection;
CGFloat yDelta = MAX(endPoint.y ,MAX(arc4random_uniform(8*heartSize), heartSize));
CGPoint controlPoint1 = CGPointMake(heartCenterX + xDelta, viewHeight - yDelta);
CGPoint controlPoint2 = CGPointMake(heartCenterX - 2*xDelta, yDelta);
[heartTravelPath addCurveToPoint:endPoint controlPoint1:controlPoint1 controlPoint2:controlPoint2];
CAKeyframeAnimation *keyFrameAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
keyFrameAnimation.path = heartTravelPath.CGPath;
keyFrameAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
keyFrameAnimation.duration = totalAnimationDuration + endPoint.y/viewHeight;
[self.layer addAnimation:keyFrameAnimation forKey:@"positionOnPath"];
// Alpha & remove from superview
[UIView animateWithDuration:totalAnimationDuration animations:^{
self.alpha = 0.0;
} completion:^(BOOL finished) {
[self removeFromSuperview];
}];
}
- (void)drawRect:(CGRect)rect {
[_strokeColor setStroke];
[_fillColor setFill];
CGFloat drawingPadding = 4.0;
CGFloat curveRadius = floor((CGRectGetWidth(rect) - 2*drawingPadding) / 4.0);
// Creat path
UIBezierPath *heartPath = [UIBezierPath bezierPath];
// Start at bottom heart tip
CGPoint tipLocation = CGPointMake(floor(CGRectGetWidth(rect) / 2.0), CGRectGetHeight(rect) - drawingPadding);
[heartPath moveToPoint:tipLocation];
// Move to top left start of curve
CGPoint topLeftCurveStart = CGPointMake(drawingPadding, floor(CGRectGetHeight(rect) / 2.4));
[heartPath addQuadCurveToPoint:topLeftCurveStart controlPoint:CGPointMake(topLeftCurveStart.x, topLeftCurveStart.y + curveRadius)];
// Create top left curve
[heartPath addArcWithCenter:CGPointMake(topLeftCurveStart.x + curveRadius, topLeftCurveStart.y) radius:curveRadius startAngle:M_PI endAngle:0 clockwise:YES];
// Create top right curve
CGPoint topRightCurveStart = CGPointMake(topLeftCurveStart.x + 2*curveRadius, topLeftCurveStart.y);
[heartPath addArcWithCenter:CGPointMake(topRightCurveStart.x + curveRadius, topRightCurveStart.y) radius:curveRadius startAngle:M_PI endAngle:0 clockwise:YES];
// Final curve to bottom heart tip
CGPoint topRightCurveEnd = CGPointMake(topLeftCurveStart.x + 4*curveRadius, topRightCurveStart.y);
[heartPath addQuadCurveToPoint:tipLocation controlPoint:CGPointMake(topRightCurveEnd.x, topRightCurveEnd.y + curveRadius)];
[heartPath fill];
heartPath.lineWidth = 1;
heartPath.lineCapStyle = kCGLineCapRound;
heartPath.lineJoinStyle = kCGLineCapRound;
[heartPath stroke];
}
再在所需控制器裡新增ZLLiveHeartView.
- (void)showLiveHeartView {
ZLLiveHeartView *heart = [[ZLLiveHeartView alloc]initWithFrame:CGRectMake(0, 0, 40, 40)];
[self.view addSubview:heart];
CGPoint fountainSource = CGPointMake(self.view.frame.size.width - 80, self.view.bounds.size.height - 30 / 2.0 - 10);
heart.center = fountainSource;
[heart liveHeartAnimateInView:self.view];
}
4. 直播圖片點贊動畫
先自定義ZLLikeAnimation,animatePictureInView方法:
- (void)animatePictureInView:(UIView *)view Image:(UIImage *)image {
self.imageView.image = image;
NSTimeInterval totalAnimationDuration = 8;
CGFloat heartSize = CGRectGetWidth(self.bounds);
CGFloat heartCenterX = self.center.x;
CGFloat viewHeight = CGRectGetHeight(view.bounds);
// Pre-Animation setup
self.transform = CGAffineTransformMakeScale(0, 0);
self.alpha = 0;
// Bloom
[UIView animateWithDuration:0.5 delay:0.0 usingSpringWithDamping:0.6 initialSpringVelocity:0.8 options:UIViewAnimationOptionCurveEaseOut animations:^{
self.transform = CGAffineTransformIdentity;
self.alpha = 0.9;
} completion:NULL];
NSInteger i = arc4random_uniform(2);
// -1 OR 1
NSInteger rotationDirection = 1 - (2 * i);
NSInteger rotationFraction = arc4random_uniform(10);
[UIView animateWithDuration:totalAnimationDuration animations:^{
self.transform = CGAffineTransformMakeRotation(rotationDirection * M_PI / (16 + rotationFraction * 0.2));
} completion:NULL];
UIBezierPath *heartTravelPath = [UIBezierPath bezierPath];
[heartTravelPath moveToPoint:self.center];
// random end point
CGPoint endPoint = CGPointMake(heartCenterX + (rotationDirection) * arc4random_uniform(2 * heartSize), viewHeight/6.0 + arc4random_uniform(viewHeight / 4.0));
// random Control Points
NSInteger j = arc4random_uniform(2);
NSInteger travelDirection = 1 - (2 * j);
// randomize x and y for control points
CGFloat xDelta = (heartSize / 2.0 + arc4random_uniform(2 * heartSize)) * travelDirection;
CGFloat yDelta = MAX(endPoint.y ,MAX(arc4random_uniform(8 * heartSize), heartSize));
CGPoint controlPoint1 = CGPointMake(heartCenterX + xDelta, viewHeight - yDelta);
CGPoint controlPoint2 = CGPointMake(heartCenterX - 2 * xDelta, yDelta);
[heartTravelPath addCurveToPoint:endPoint controlPoint1:controlPoint1 controlPoint2:controlPoint2];
CAKeyframeAnimation *keyFrameAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
keyFrameAnimation.path = heartTravelPath.CGPath;
keyFrameAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
keyFrameAnimation.duration = totalAnimationDuration + endPoint.y / viewHeight;
[self.layer addAnimation:keyFrameAnimation forKey:@"positionOnPath"];
// Alpha & remove from superview
[UIView animateWithDuration:totalAnimationDuration animations:^{
self.alpha = 0.0;
} completion:^(BOOL finished) {
[self removeFromSuperview];
}];
}
再在所需控制器裡新增ZLLikeAnimation.
- (void)showLikePictureView {
ZLLikeAnimation *heart = [[ZLLikeAnimation alloc]initWithFrame:CGRectMake(0, 0, 40, 40)];
[self.view addSubview:heart];
CGPoint fountainSource = CGPointMake(self.view.frame.size.width - 80, self.view.bounds.size.height - 30 / 2.0 - 10);
heart.center = fountainSource;
int count = round(random() % 12);
[heart animatePictureInView:self.view Image:[UIImage imageNamed:[NSString stringWithFormat:@"resource.bundle/heart%d.png",count]]];
}
5. 煙花特效:
設定煙花
- (void)setupFireworks {
self.caELayer = [CAEmitterLayer layer];
// 發射源
self.caELayer.emitterPosition = CGPointMake(self.view.frame.size.width / 2, self.view.frame.size.height - 50);
// 發射源尺寸大小
self.caELayer.emitterSize = CGSizeMake(50, 0);
// 發射源模式
self.caELayer.emitterMode = kCAEmitterLayerOutline;
// 發射源的形狀
self.caELayer.emitterShape = kCAEmitterLayerLine;
// 渲染模式
self.caELayer.renderMode = kCAEmitterLayerAdditive;
// 發射方向
self.caELayer.velocity = 1;
// 隨機產生粒子
self.caELayer.seed = (arc4random() % 100) + 1;
// cell
CAEmitterCell *cell = [CAEmitterCell emitterCell];
// 速率
cell.birthRate = 1.0;
// 發射的角度
cell.emissionRange = 0.11 * M_PI;
// 速度
cell.velocity = 300;
// 範圍
cell.velocityRange = 150;
// Y軸 加速度分量
cell.yAcceleration = 75;
// 宣告週期
cell.lifetime = 2.04;
// 是個CGImageRef的物件,既粒子要展現的圖片
cell.contents = (id)[[UIImage imageNamed:@"ring"] CGImage];
// 縮放比例
cell.scale = 0.2;
// 粒子的顏色
cell.color = [[UIColor colorWithRed:0.6 green:0.6 blue:0.6 alpha:1.0] CGColor];
// 一個粒子的顏色green 能改變的範圍
cell.greenRange = 1.0;
// 一個粒子的顏色red 能改變的範圍
cell.redRange = 1.0;
// 一個粒子的顏色blue 能改變的範圍
cell.blueRange = 1.0;
// 子旋轉角度範圍
cell.spinRange = M_PI;
// 爆炸
CAEmitterCell *burst = [CAEmitterCell emitterCell];
// 粒子產生係數
burst.birthRate = 1.0;
// 速度
burst.velocity = 0;
// 縮放比例
burst.scale = 2.5;
// shifting粒子red在生命週期內的改變速度
burst.redSpeed = -1.5;
// shifting粒子blue在生命週期內的改變速度
burst.blueSpeed= +1.5;
// shifting粒子green在生命週期內的改變速度
burst.greenSpeed = +1.0;
// 生命週期
burst.lifetime = 0.35;
// 火花 and finally, the sparks
CAEmitterCell *spark = [CAEmitterCell emitterCell];
// 粒子產生係數,預設為1.0
spark.birthRate = 400;
// 速度
spark.velocity = 125;
// 360 deg //周圍發射角度
spark.emissionRange = 2 * M_PI;
// gravity //y方向上的加速度分量
spark.yAcceleration = 75;
// 粒子生命週期
spark.lifetime = 3;
// 是個CGImageRef的物件,既粒子要展現的圖片
spark.contents = (id)
[[UIImage imageNamed:@"fireworks"] CGImage];
// 縮放比例速度
spark.scaleSpeed = -0.2;
// 粒子green在生命週期內的改變速度
spark.greenSpeed = -0.1;
// 粒子red在生命週期內的改變速度
spark.redSpeed = 0.4;
// 粒子blue在生命週期內的改變速度
spark.blueSpeed = -0.1;
// 粒子透明度在生命週期內的改變速度
spark.alphaSpeed = -0.25;
// 子旋轉角度
spark.spin = 2 * M_PI;
// 子旋轉角度範圍
spark.spinRange = 2 * M_PI;
self.caELayer.emitterCells = [NSArray arrayWithObject:cell];
cell.emitterCells = [NSArray arrayWithObjects:burst, nil];
burst.emitterCells = [NSArray arrayWithObject:spark];
[self.view.layer addSublayer:self.caELayer];
}
6. 雪花特效:
設定雪花
- (void)setupSnowflake {
// 建立粒子Layer
CAEmitterLayer *snowEmitter = [CAEmitterLayer layer];
// 粒子發射位置
snowEmitter.emitterPosition = CGPointMake(120,0);
// 發射源的尺寸大小
snowEmitter.emitterSize = self.view.bounds.size;
// 發射模式
snowEmitter.emitterMode = kCAEmitterLayerSurface;
// 發射源的形狀
snowEmitter.emitterShape = kCAEmitterLayerLine;
// 建立雪花型別的粒子
CAEmitterCell *snowflake = [CAEmitterCell emitterCell];
// 粒子的名字
snowflake.name = @"snow";
// 粒子引數的速度乘數因子
snowflake.birthRate = 20.0;
snowflake.lifetime = 120.0;
// 粒子速度
snowflake.velocity = 10.0;
// 粒子的速度範圍
snowflake.velocityRange = 10;
// 粒子y方向的加速度分量
snowflake.yAcceleration = 2;
// 周圍發射角度
snowflake.emissionRange = 0.5 * M_PI;
// 子旋轉角度範圍
snowflake.spinRange = 0.25 * M_PI;
snowflake.contents = (id)[[UIImage imageNamed:@"snow"] CGImage];
// 設定雪花形狀的粒子的顏色
snowflake.color = [[UIColor whiteColor] CGColor];
snowflake.redRange = 1.5f;
snowflake.greenRange = 2.2f;
snowflake.blueRange = 2.2f;
snowflake.scaleRange = 0.6f;
snowflake.scale = 0.7f;
snowEmitter.shadowOpacity = 1.0;
snowEmitter.shadowRadius = 0.0;
snowEmitter.shadowOffset = CGSizeMake(0.0, 0.0);
// 粒子邊緣的顏色
snowEmitter.shadowColor = [[UIColor whiteColor] CGColor];
// 新增粒子
snowEmitter.emitterCells = @[snowflake];
// 將粒子Layer新增進圖層中
[self.view.layer addSublayer:snowEmitter];
// 形成遮罩
UIImage *image = [UIImage imageNamed:@"alpha"];
_layer = [CALayer layer];
_layer.frame = (CGRect){CGPointZero, self.view.bounds.size};
_layer.contents = (__bridge id)(image.CGImage);
_layer.position = self.view.center;
snowEmitter.mask = _layer;
}
三、壓縮檔案截圖
1、壓縮檔案截圖
2.專案截圖:
四、其他補充
持續更新新增動畫特效~
介面性問題可以根據自己專案需求調整即可, 具體可參考程式碼, 專案能夠直接執行!