Shimmer扩展应用:创意加载动画设计
本文详细介绍了Shimmer框架在现代iOS应用中的高级应用技巧,包括手势识别交互、多视图组合动画、主流框架集成方案以及自定义闪烁效果的高级实现方法。文章通过丰富的代码示例和可视化图表,展示了如何创建复杂而精美的加载动画效果,提升用户体验。
结合手势识别实现交互式参数调整
在现代移动应用设计中,交互式动画参数调整已成为提升用户体验的重要手段。通过结合手势识别技术,我们可以让用户直观地控制Shimmer动画的各种参数,创造出更加个性化和动态的视觉效果。
手势识别基础实现
Shimmer项目通过UIGestureRecognizer类实现了两种基本手势交互:点击手势和拖动手势。点击手势用于切换动画的开启和关闭状态,而拖动手势则用于实时调整动画参数。
// 添加点击手势识别器
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(_tapped:)];
[self.view addGestureRecognizer:tapRecognizer];
// 添加拖动手势识别器
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc]
initWithTarget:self action:@selector(_panned:)];
[self.view addGestureRecognizer:panRecognizer];
智能方向检测机制
在拖动手势处理中,项目实现了一个智能的方向检测机制,能够根据用户手势的初始移动方向自动判断是垂直拖动还是水平拖动,从而分别控制不同的动画参数:
这种智能检测机制通过比较手势在X轴和Y轴方向的初始速度来实现:
// 方向检测逻辑
#if CGFLOAT_IS_DOUBLE
_panVertical = (fabs(velocity.y) > fabs(velocity.x));
#else
_panVertical = (fabsf(velocity.y) > fabsf(velocity.x));
#endif
实时参数映射算法
手势移动距离到动画参数的映射是整个交互系统的核心。项目采用了基于比例的映射算法,将手势在屏幕上的移动距离转换为具体的动画参数值:
| 手势类型 | 控制参数 | 映射范围 | 计算公式 |
|---|---|---|---|
| 垂直拖动 | 动画速度 | 0-1000 points/s | speed = max(0, min(1000, startValue + progress * 200)) |
| 水平拖动 | 不透明度 | 0-1.0 | opacity = max(0, min(1, startValue + progress * 0.5)) |
// 参数映射实现
CGFloat directional = (_panVertical ? translation.y : translation.x);
CGFloat possible = (_panVertical ? self.view.bounds.size.height : self.view.bounds.size.width);
CGFloat progress = (directional / possible);
if (_panVertical) {
_shimmeringView.shimmeringSpeed = fmaxf(0.0, fminf(1000.0,
_panStartValue + progress * 200.0));
} else {
_shimmeringView.shimmeringOpacity = fmaxf(0.0, fminf(1.0,
_panStartValue + progress * 0.5));
}
可视化反馈系统
为了提供更好的用户体验,项目还实现了一个实时的可视化反馈系统,在用户调整参数时显示当前的参数值:
// 显示参数值标签
if (_panVertical) {
_valueLabel.text = [NSString stringWithFormat:@"Speed\n%.1f",
_shimmeringView.shimmeringSpeed];
} else {
_valueLabel.text = [NSString stringWithFormat:@"Opacity\n%.2f",
_shimmeringView.shimmeringOpacity];
}
// 动画显示/隐藏标签
- (void)_animateValueLabelVisible:(BOOL)visible {
UIViewAnimationOptions options = UIViewAnimationOptionBeginFromCurrentState;
void (^animations)() = ^{
_valueLabel.alpha = (visible ? 1.0 : 0.0);
};
[UIView animateWithDuration:0.5 animations:animations];
}
扩展交互可能性
基于现有的手势识别框架,我们可以进一步扩展交互功能,实现更多动画参数的实时控制:
// 扩展示例:双指捏合控制高光长度
UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc]
initWithTarget:self action:@selector(_pinched:)];
[self.view addGestureRecognizer:pinchRecognizer];
// 扩展示例:旋转手势控制动画方向
UIRotationGestureRecognizer *rotationRecognizer = [[UIRotationGestureRecognizer alloc]
initWithTarget:self action:@selector(_rotated:)];
[self.view addGestureRecognizer:rotationRecognizer];
通过这种交互式参数调整方式,开发者可以为用户提供更加直观和有趣的动画定制体验,让加载动画不再是静态的等待指示,而是成为应用交互体验的一部分。
这种结合手势识别的交互式参数调整方案不仅提升了用户体验,还为动画效果的实时预览和微调提供了强大的工具支持。
多视图组合创建复杂加载动画
在现代iOS应用开发中,加载动画不仅仅是简单的进度指示器,更是用户体验的重要组成部分。通过FBShimmering框架的多视图组合技术,开发者可以创建出既美观又功能丰富的复杂加载动画效果。这种技术将多个独立的shimmering视图有机组合,形成层次分明、动态协调的加载界面。
多视图层级架构设计
多视图组合的核心在于建立清晰的层级结构。通过合理的视图层级安排,可以创造出深度感和动态层次:
// 创建主容器视图
UIView *containerView = [[UIView alloc] initWithFrame:self.view.bounds];
// 第一层:背景 shimmering 视图
FBShimmeringView *backgroundShimmer = [[FBShimmeringView alloc] initWithFrame:containerView.bounds];
backgroundShimmer.shimmeringSpeed = 150;
backgroundShimmer.shimmeringOpacity = 0.2;
// 第二层:内容 shimmering 视图
FBShimmeringView *contentShimmer = [[FBShimmeringView alloc] initWithFrame:CGRectInset(containerView.bounds, 20, 100)];
contentShimmer.shimmeringSpeed = 230;
contentShimmer.shimmeringOpacity = 0.5;
// 第三层:高亮 shimmering 视图
FBShimmeringView *highlightShimmer = [[FBShimmeringView alloc] initWithFrame:CGRectMake(0, 0, 100, containerView.bounds.size.height)];
highlightShimmer.shimmeringSpeed = 350;
highlightShimmer.shimmeringOpacity = 0.8;
这种三层架构的设计允许每个视图独立控制其shimmering参数,创造出丰富的视觉效果。
协调动画时序控制
多视图组合的关键在于时序的精确控制。通过调整各个视图的shimmeringBeginTime属性,可以创建出波浪式或序列式的动画效果:
// 设置时序错开的动画效果
CFTimeInterval currentTime = CACurrentMediaTime();
backgroundShimmer.shimmeringBeginTime = currentTime;
contentShimmer.shimmeringBeginTime = currentTime + 0.3;
highlightShimmer.shimmeringBeginTime = currentTime + 0.6;
// 启动所有shimmering效果
backgroundShimmer.shimmering = YES;
contentShimmer.shimmering = YES;
highlightShimmer.shimmering = YES;
多样化方向组合策略
通过组合不同方向的shimmering效果,可以创造出更加动态和吸引人的加载动画:
// 水平方向shimmering视图
FBShimmeringView *horizontalShimmer = [[FBShimmeringView alloc] initWithFrame:CGRectMake(0, 0, containerView.bounds.size.width, 50)];
horizontalShimmer.shimmeringDirection = FBShimmerDirectionRight;
// 垂直方向shimmering视图
FBShimmeringView *verticalShimmer = [[FBShimmeringView alloc] initWithFrame:CGRectMake(0, 50, 50, containerView.bounds.size.height - 100)];
verticalShimmer.shimmeringDirection = FBShimmerDirectionDown;
// 对角线方向shimmering视图
FBShimmeringView *diagonalShimmer = [[FBShimmeringView alloc] initWithFrame:CGRectMake(50, 100, containerView.bounds.size.width - 100, 2)];
diagonalShimmer.shimmeringDirection = FBShimmerDirectionRight;
diagonalShimmer.transform = CGAffineTransformMakeRotation(M_PI_4);
复杂内容视图集成
多视图组合不仅限于简单的几何形状,还可以集成复杂的UI组件:
// 创建模拟卡片布局
UIView *cardContentView = [[UIView alloc] initWithFrame:CGRectMake(20, 20, 280, 180)];
cardContentView.backgroundColor = [UIColor whiteColor];
cardContentView.layer.cornerRadius = 8;
// 添加模拟内容
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 20, 240, 24)];
titleLabel.text = @"加载中...";
titleLabel.font = [UIFont systemFontOfSize:18];
UILabel *descriptionLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 60, 240, 60)];
descriptionLabel.text = @"正在获取数据,请稍候";
descriptionLabel.numberOfLines = 0;
[cardContentView addSubview:titleLabel];
[cardContentView addSubview:descriptionLabel];
// 创建shimmering视图包装复杂内容
FBShimmeringView *cardShimmer = [[FBShimmeringView alloc] initWithFrame:CGRectMake(40, 100, 300, 220)];
cardShimmer.contentView = cardContentView;
性能优化与内存管理
多视图组合时需要注意性能优化,特别是在低端设备上:
| 优化策略 | 实施方法 | 效果 |
|---|---|---|
| 视图复用 | 使用重用池管理shimmering视图 | 减少内存分配开销 |
| 适时启停 | 根据可见性控制shimmering状态 | 降低CPU使用率 |
| 层级优化 | 减少不必要的视图层级 | 提升渲染性能 |
| 参数调优 | 根据设备性能调整shimmering参数 | 平衡效果与性能 |
// 性能优化示例
- (void)optimizeShimmeringPerformance {
// 根据设备性能调整参数
if ([UIDevice currentDevice].performanceLevel == LowPerformance) {
self.shimmeringSpeed = 180;
self.shimmeringPauseDuration = 0.6;
} else {
self.shimmeringSpeed = 230;
self.shimmeringPauseDuration = 0.4;
}
// 适时停止不可见的shimmering
if (!self.window) {
self.shimmering = NO;
}
}
响应式布局适配
多视图组合需要良好的响应式布局支持,确保在不同屏幕尺寸和设备方向上都能正常显示:
- (void)updateLayoutForSize:(CGSize)size {
// 动态调整各个shimmering视图的frame
self.backgroundShimmer.frame = CGRectMake(0, 0, size.width, size.height);
self.contentShimmer.frame = CGRectMake(20, 100, size.width - 40, size.height - 200);
self.highlightShimmer.frame = CGRectMake(0, 0, 80, size.height);
// 根据屏幕方向调整参数
if (size.width > size.height) {
// 横屏模式
self.highlightShimmer.shimmeringDirection = FBShimmerDirectionDown;
} else {
// 竖屏模式
self.highlightShimmer.shimmeringDirection = FBShimmerDirectionRight;
}
}
通过多视图组合技术,开发者可以构建出既美观又实用的复杂加载动画,显著提升应用的用户体验质量。这种方法的灵活性使得它适用于各种不同的应用场景和设计需求。
与主流框架的集成方案
Shimmer作为一个轻量级的iOS加载动画框架,提供了与多种主流开发框架的无缝集成方案。无论是传统的Objective-C项目还是现代化的Swift项目,亦或是使用React Native等跨平台框架,Shimmer都能轻松融入您的开发工作流。
CocoaPods集成
CocoaPods是iOS开发中最常用的依赖管理工具,Shimmer提供了完整的Pod支持。在您的Podfile中添加以下配置:
pod 'Shimmer', '~> 1.0.2'
执行pod install后,您就可以在项目中直接使用Shimmer的所有功能。这种集成方式支持自动版本管理和依赖解析,确保项目的稳定性和可维护性。
Carthage集成
对于偏好Carthage的开发者,Shimmer同样提供了良好的支持。在Cartfile中添加:
github "facebook/Shimmer" ~> 1.0.2
运行carthage update后,将生成的framework添加到项目中。Carthage集成方式更加轻量,不会修改项目的Xcode配置,适合需要精细控制依赖关系的项目。
Swift Package Manager集成
随着Swift生态的成熟,SPM已成为官方推荐的依赖管理工具。Shimmer支持通过SPM集成:
- 在Xcode中选择File > Add Packages
- 输入仓库URL:https://github.com/facebook/Shimmer
- 选择版本规则并添加到项目
SPM集成提供了最佳的Swift兼容性和工具链支持。
React Native集成
对于React Native项目,可以通过创建原生模块来集成Shimmer效果:
// ShimmerViewManager.h
#import <React/RCTViewManager.h>
#import "FBShimmeringView.h"
@interface ShimmerViewManager : RCTViewManager
@end
// ShimmerViewManager.m
#import "ShimmerViewManager.h"
@implementation ShimmerViewManager
RCT_EXPORT_MODULE(ShimmerView)
RCT_EXPORT_VIEW_PROPERTY(shimmering, BOOL)
RCT_EXPORT_VIEW_PROPERTY(shimmeringSpeed, CGFloat)
RCT_EXPORT_VIEW_PROPERTY(shimmeringHighlightLength, CGFloat)
- (UIView *)view {
FBShimmeringView *shimmeringView = [[FBShimmeringView alloc] init];
return shimmeringView;
}
@end
然后在JavaScript端使用:
import { requireNativeComponent } from 'react-native';
const ShimmerView = requireNativeComponent('ShimmerView');
const LoadingComponent = () => (
<ShimmerView
style={{ width: 200, height: 50 }}
shimmering={true}
shimmeringSpeed={230}
shimmeringHighlightLength={0.7}
>
<Text style={{ color: '#ccc' }}>加载中...</Text>
</ShimmerView>
);
Flutter集成
对于Flutter项目,可以通过Platform Channels实现Shimmer效果的集成:
// flutter_shimmer.dart
class FlutterShimmer {
static const MethodChannel _channel =
MethodChannel('flutter_shimmer');
static Future<void> startShimmering() async {
await _channel.invokeMethod('startShimmering');
}
static Future<void> stopShimmering() async {
await _channel.invokeMethod('stopShimmering');
}
}
对应的iOS端实现:
// FlutterShimmerPlugin.m
#import "FlutterShimmerPlugin.h"
#import "FBShimmeringView.h"
@implementation FlutterShimmerPlugin
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
FlutterMethodChannel* channel = [FlutterMethodChannel
methodChannelWithName:@"flutter_shimmer"
binaryMessenger:[registrar messenger]];
FlutterShimmerPlugin* instance = [[FlutterShimmerPlugin alloc] init];
[registrar addMethodCallDelegate:instance channel:channel];
}
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
if ([call.method isEqualToString:@"startShimmering"]) {
// 实现Shimmer启动逻辑
result(nil);
} else if ([call.method isEqualToString:@"stopShimmering"]) {
// 实现Shimmer停止逻辑
result(nil);
} else {
result(FlutterMethodNotImplemented);
}
}
@end
与UI框架的深度集成
Shimmer可以与各种UI框架深度集成,以下是一些常见的使用模式:
// 与SwiftUI集成
struct ShimmerView: UIViewRepresentable {
@Binding var isShimmering: Bool
let content: UIView
func makeUIView(context: Context) -> FBShimmeringView {
let shimmeringView = FBShimmeringView()
shimmeringView.contentView = content
return shimmeringView
}
func updateUIView(_ uiView: FBShimmeringView, context: Context) {
uiView.shimmering = isShimmering
}
}
// 与RxSwift集成
extension Reactive where Base: FBShimmeringView {
var shimmering: Binder<Bool> {
return Binder(self.base) { view, isShimmering in
view.shimmering = isShimmering
}
}
}
// 使用示例
viewModel.isLoading
.bind(to: shimmeringView.rx.shimmering)
.disposed(by: disposeBag)
自定义配置集成
Shimmer提供了丰富的配置选项,可以通过配置文件或依赖注入的方式进行定制:
# shimmer_config.yaml
default:
speed: 230
highlight_length: 0.7
opacity: 0.5
pause_duration: 0.4
fast:
speed: 350
highlight_length: 0.5
slow:
speed: 150
highlight_length: 0.9
对应的配置加载代码:
class ShimmerConfigurator {
static func configure(view: FBShimmeringView, with config: ShimmerConfig) {
view.shimmeringSpeed = config.speed
view.shimmeringHighlightLength = config.highlightLength
view.shimmeringAnimationOpacity = config.opacity
view.shimmeringPauseDuration = config.pauseDuration
}
}
性能优化集成
在大型项目中,Shimmer的集成需要考虑性能优化:
// 使用对象池管理Shimmer视图
class ShimmerViewPool {
private var pool: [FBShimmeringView] = []
func dequeueReusableView() -> FBShimmeringView {
if let view = pool.popLast() {
return view
}
return FBShimmeringView()
}
func enqueueReusableView(_ view: FBShimmeringView) {
view.shimmering = false
view.contentView = nil
pool.append(view)
}
}
// 在UITableView或UICollectionView中使用
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
if isLoading {
let shimmerView = shimmerPool.dequeueReusableView()
// 配置并显示shimmer效果
}
return cell
}
通过以上多种集成方案,Shimmer可以灵活地适应不同的项目架构和技术栈,为iOS应用提供优雅的加载动画体验。
自定义闪烁效果的高级技巧
Shimmer框架提供了丰富的自定义选项,让开发者能够创建出独特而精美的加载动画效果。通过深入理解核心参数和高级配置技巧,你可以实现从简单的文本闪烁到复杂的图形动画等各种效果。
核心参数深度解析
Shimmer框架的核心配置参数提供了精细的控制能力,下面通过表格展示主要参数及其作用:
| 参数名称 | 类型 | 默认值 | 描述 | 应用场景 |
|---|---|---|---|---|
shimmeringSpeed | CGFloat | 230.0 | 闪烁速度(点/秒) | 控制动画流畅度 |
shimmeringHighlightLength | CGFloat | 1.0 | 高亮区域长度比例 | 调整光带宽度 |
shimmeringAnimationOpacity | CGFloat | 0.5 | 动画时内容透明度 | 创建淡入淡出效果 |
shimmeringOpacity | CGFloat | 1.0 | 非动画时内容透明度 | 基础显示状态 |
shimmeringPauseDuration | CFTimeInterval | 0.4 | 闪烁间隔时间 | 控制节奏感 |
shimmeringDirection | FBShimmerDirection | Right | 动画方向 | 创建不同流向效果 |
高级动画配置技巧
1. 多方向动画组合
通过动态改变动画方向,可以创建出更加生动的视觉效果:
// 创建交替方向动画
- (void)setupAlternatingDirectionShimmer {
__weak typeof(self) weakSelf = self;
[NSTimer scheduledTimerWithTimeInterval:2.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
weakSelf.shimmeringView.shimmeringDirection =
(weakSelf.shimmeringView.shimmeringDirection == FBShimmerDirectionRight) ?
FBShimmerDirectionLeft : FBShimmerDirectionRight;
}];
}
2. 渐变速度效果
实现速度渐变可以增加动画的自然感:
// 速度渐变实现
- (void)applySpeedGradientEffect {
CABasicAnimation *speedAnimation = [CABasicAnimation animationWithKeyPath:@"shimmeringSpeed"];
speedAnimation.fromValue = @(100.0);
speedAnimation.toValue = @(400.0);
speedAnimation.duration = 3.0;
speedAnimation.autoreverses = YES;
speedAnimation.repeatCount = HUGE_VALF;
[self.shimmeringView.layer addAnimation:speedAnimation forKey:@"speedGradient"];
}
3. 多层闪烁效果
通过嵌套多个Shimmer视图创建复杂的层次效果:
// 创建多层闪烁效果
- (void)createMultiLayerShimmer {
// 底层缓慢闪烁
FBShimmeringView *baseLayer = [[FBShimmeringView alloc] initWithFrame:self.view.bounds];
baseLayer.shimmeringSpeed = 150.0;
baseLayer.shimmeringHighlightLength = 0.8;
// 上层快速闪烁
FBShimmeringView *topLayer = [[FBShimmeringView alloc] initWithFrame:CGRectInset(self.view.bounds, 20, 20)];
topLayer.shimmeringSpeed = 300.0;
topLayer.shimmeringHighlightLength = 0.3;
[self.view addSubview:baseLayer];
[baseLayer.contentView addSubview:topLayer];
}
自定义遮罩高级技巧
1. 自定义渐变遮罩
通过继承FBShimmeringMaskLayer实现自定义渐变效果:
@interface CustomShimmerMaskLayer : FBShimmeringMaskLayer
@property (nonatomic, strong) NSArray<UIColor *> *customGradientColors;
@end
@implementation CustomShimmerMaskLayer
- (void)updateGradientColors {
NSMutableArray *cgColors = [NSMutableArray array];
for (UIColor *color in self.customGradientColors) {
[cgColors addObject:(id)color.CGColor];
}
self.colors = cgColors;
self.locations = @[@0.0, @0.5, @1.0];
}
@end
2. 动态遮罩形状
创建非矩形遮罩实现特殊形状的闪烁效果:
// 圆形遮罩实现
- (CAShapeLayer *)createCircularMaskForView:(UIView *)view {
CAShapeLayer *maskLayer = [CAShapeLayer layer];
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:view.bounds];
maskLayer.path = path.CGPath;
return maskLayer;
}
// 应用自定义形状遮罩
FBShimmeringView *shimmerView = [[FBShimmeringView alloc] init];
shimmerView.contentView.layer.mask = [self createCircularMaskForView:shimmerView];
性能优化技巧
1. 动画帧率控制
2. 内存使用优化
// 智能内存管理
- (void)optimizeShimmerMemoryUsage {
// 在视图不可见时暂停动画
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(pauseShimmerWhenBackground)
name:UIApplicationDidEnterBackgroundNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(resumeShimmerWhenForeground)
name:UIApplicationWillEnterForegroundNotification
object:nil];
}
- (void)pauseShimmerWhenBackground {
self.shimmeringView.shimmering = NO;
}
- (void)resumeShimmerWhenForeground {
if (self.shimmeringView.window) {
self.shimmeringView.shimmering = YES;
}
}
高级交互效果
1. 触摸响应闪烁
// 触摸交互闪烁效果
- (void)setupTouchResponsiveShimmer {
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:@selector(handleTap:)];
[self.shimmeringView addGestureRecognizer:tapGesture];
}
- (void)handleTap:(UITapGestureRecognizer *)gesture {
// 点击时增强闪烁效果
[UIView animateWithDuration:0.2 animations:^{
self.shimmeringView.shimmeringSpeed = 500.0;
self.shimmeringView.shimmeringHighlightLength = 0.9;
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.5 animations:^{
self.shimmeringView.shimmeringSpeed = 230.0;
self.shimmeringView.shimmeringHighlightLength = 1.0;
}];
}];
}
2. 滚动同步效果
// 与ScrollView滚动同步的闪烁效果
- (void)syncShimmerWithScrollView:(UIScrollView *)scrollView {
[scrollView addObserver:self
forKeyPath:@"contentOffset"
options:NSKeyValueObservingOptionNew
context:nil];
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary<NSKeyValueChangeKey,id> *)change
context:(void *)context {
if ([keyPath isEqualToString:@"contentOffset"]) {
CGPoint offset = [change[NSKeyValueChangeNewKey] CGPointValue];
CGFloat speedFactor = 1.0 + fabs(offset.y) / 100.0;
self.shimmeringView.shimmeringSpeed = 230.0 * speedFactor;
}
}
通过掌握这些高级技巧,你可以充分发挥Shimmer框架的潜力,创建出既美观又高效的加载动画效果,显著提升用户体验。
总结
Shimmer框架作为一个强大的iOS加载动画解决方案,提供了丰富的自定义选项和灵活的集成方式。通过手势识别、多视图组合、框架集成和高级自定义技巧,开发者可以创建出各种独特的加载动画效果。本文介绍的技术不仅提升了动画的视觉效果,还优化了性能表现,为移动应用提供了更加流畅和吸引人的用户体验。掌握这些高级技巧将帮助开发者在实际项目中实现专业级的加载动画设计。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



