您好!欢迎来到爱源码

爱源码

热门搜索: 抖音快手短视频下载   

颤振复杂加载动画的剥茧 [网站源码]

  • 时间:2022-10-12 18:20 编辑: 来源: 阅读:292
  • 扫一扫,手机访问
摘要:颤振复杂加载动画的剥茧 [网站源码]
首先,在前言之前,我分析了我的一篇文章《iOS复杂动画的剥离》中一个复杂加载动画的实现过程。现在有意看了Flutter的动画,于是有了用Flutter实现这个动画作为练习的想法。最后使用Flutter的效果如下:welcome.gif接下来我们重新分析一下这个动画的实现过程。第二,分析动画的步骤。上图的动画乍一看有点复杂,但是当我们一步步分析的时候,会发现其实并没有那么难。 如果你仔细看,会发现大致步骤如下:1。首先,一个圆圈出来了。2.圆在水平和垂直方向受到挤压,呈椭圆形。3.左下角、右下角、圆的顶部依次各凸出一小部分(内三角形拉伸)。4.圆和突出部分形成的图形转一圈变成三角形(三角形不变,缩小圆)5。两个带有矩形边框的动画出现在三角形的左侧。将三角形包围在矩形中。6.矩形从底部被波浪填充。7.将填充的矩形放大到全屏。欢迎弹出窗口的一般步骤如上。让我们一步步实现每一步。 3.剥茧1。分析因为在Flutter中一切都是widget,首先根据我们的分析,我们大概需要下面的widget圆三角形和两个矩形边框水波文本Text。首先,我们需要创建一个动画控制器,其次是动画三要素:animation controller曲线动画第2周。实现圆变圆的变化过程大致如下(w->;宽度,h-& gt;高度):(h = 0,w = 0)此时没有圆(h = 120,w = 120)。圆由小变大(h = 120,w = 130)->: (h = 120,w = 120)->;(h = 130,w = 120)-& gt;(h = 120,w = 120)圆变成椭圆的过程(h = 0,w = 0)以上过程是一个圆在整个动画循环中的变化过程。于是我们用TweenSequence来实现每个时间段的时间比例//起始圆的宽度变化静态Tween sequence circlewidthtweensequence = Tween sequence([Tween sequence item(Tween:Tween(begin:0.0,end: 120.0),weight: 5),Tween sequence item(Tween:Tween(begin:120.0,end: 130.0),weight: 10),Tween sequence item(Tween:Tween(begin:130.0,enddouble & gt(120.0),权重:20),TweenSequenceItem(Tween:Tween(begin:120.0,end: 0.0),权重:10),TweenSequenceItem(Tween:constant Tween & lt;double & gt(0.0),权重:45),]);//初始圆形静态tween序列的高度变化circleheihtweensequence = tween序列([tween: tween (begin: 0.0,end: 120.0),weight: 5),tween:constant tween < double & gt;(120.0),权重:20),TweenSequenceItem(Tween:Tween(begin:120.0,end: 130.0),权重:10),TweenSequenceItem(Tween:Tween(begin:130.0,end: 120.0),权重:10),TweenSequenceItem(Tween:constant Tween & lt;double & gt(0.0),权重:45),]);基于上述内容,您可以制作圆的整个生命周期的动画...@ override Widget build(build context context){ return animation builder(animation:_ controller,builder: (BuildContext context,Widget child){ return Center(child:clip rect(borderRadius:borderRadius . circular(60),child:Container(color:colors . purple,height:_ circleheightween . value,WidthTween.value,),);}, );}效果如下:circle.gif3实现三角形变化三角形变化的过程其实很简单,主要是以下几个步骤:将三角形从0拉伸旋转到大三角形,分别知道三角形的左、右、顶角。首先,我们需要画一个三角形,因为我们没有三角形这样的小部件,所以我们需要手动完成。 其实在Flutter中实现各种复杂图形非常简单。Flutter为我们提供了一个通用的自定义画师类。我们只需要继承然后实现Paint和shouldRepaint这两个通用方法,设置三角形就可以实现下面这个类triangle painter扩展自定义painter { color colorPaint _paint = Paint()..冲程宽度= 5.0..color = Colors .紫色..isAntiAlias = true..stroke join = stroke join . round;Path _ Path = Path();双左、右、上;TrianglePainter({this.left,this.right,this . top });@ override void paint(Canvas Canvas,Size Size){ final _ width = Size . width;final _ height = size.height_path.moveTo(left * _width,0.85 * _ height);_path.lineTo(right * _width,0.85 * _ height);_path.lineTo(0.5 * _width,top * _ height);_ path . close();canvas.drawPath(_path,_ paint);} @ override bool should repaint(custom painter old delegate)= & gt;真实;}三角形改变后的补间如下//三角形大小改变静态补间序列TrianglesizeTween sequence =补间序列([补间序列项(tween: tween (begin: 0.0,end: 120.0),权重:15),TweenSequenceItem(Tween:constant Tween & lt;double & gt(120.0),重量:85),]);//三角形静态补间序列三角形left tween sequence = tween sequence([补间序列项(tween:constant tween < double & gt;(0.2),权重:15),TweenSequenceItem(tween: Tween(开始:0.2,结束:0.02),权重:10),TweenSequenceItem(Tween:constant Tween & lt;double & gt(0.02),权重:75),]);静态TweenSequence triangleRightTweenSequence = TweenSequence([TweenSequence item(tween:constant tween & lt;double & gt(0.8),权重:25),TweenSequenceItem(tween: Tween(开始:0.8,结束:0.98),权重:10),TweenSequenceItem(Tween:constant Tween & lt;double & gt(0.98),权重:65),]);静态tween sequence triangleTopTweenSequence = tween sequence([tween sequence item(tween:constant tween & lt;double & gt(0.05),权重:35),TweenSequenceItem(Tween:Tween(begin:0.05,end: -0.1),权重:10),TweenSequenceItem(Tween:constant Tween & lt;double & gt(-0.1),权重:55),]);//整体旋转静态tween sequence rotationween sequence = tween sequence([tween sequence(tween:constant tween < double & gt;(0.0),权重:45),TweenSequenceItem(Tween:Tween(begin:0.0,end: 2.0),权重:10),TweenSequenceItem(Tween:constant Tween & lt;double & gt(2.0),权重:45),]);最后,获取补间值来渲染动画...@ override Widget build(build context context){ return animation:_ controller,builder: (BuildContext context,Widget child){ return Center(child:Transform(alignment:alignment . Center,Transform:matrix 4 . rotation z(math . pi * _ rotationween . value),child:Container(height:_ trianglesizetween . value,width: _triangleSizeTween.value),child:custom paint:triangle painter(left painter(左:_ triangleLeftTween.value,右:_ trianglet}, );}最后三角形动画变化效果如下:triangle.gif4实现矩形框的变化。类似地,我们必须使用自定义画师类方形画师扩展自定义画师{双倍进度;颜色颜色;最终绘制_绘制=绘制()..strokeCap = StrokeCap.round..style = PaintingStyle.stroke..stroke width = 5;SquarePainter({this.progress,this . color = colors . purple });@ override void paint(Canvas Canvas,Size Size){ _ paint . color = color;如果(进度& gt0) { var path = createPath(4,size . width);path metric path metric = path . compute metrics()。第一;path extract path = path metric . extract path(0.0,path metric . length * progress);canvas.drawPath(extractPath,_ paint);} } @ override bool should repaint(custom painter old delegate)= & gt;真实;Path createPath(int sides,double radius){ Path Path = Path();//根据三角形的系数画一个矩形。double wFartor = 0.02//左下方双H因子= 0.85;//右下方双T因子= 0.10;//顶部三角形path.moveto (wfartor * radius,HF factor * radius);for(int I = 1;我& lt=侧面;i++) { double x,y;if(I = = 1){ x = wFartor * radius;y = -tFactor *半径;} else if(I = = 2){ x = radius;y = -tFactor *半径;} else if(I = = 3){ x = radius;y =半径* hFactor} else { x = wFartor * radiusy =半径* hFactor} path.lineTo(x,y);} path . close();返回路径;}}需要注意的是,我们需要使用PathMetric来获取路径,类似于Android中的PathMeasure.getSegment(),两个线性矩形的补间变化如下//线性矩形变化静态Tween sequence rectween sequence 1 = Tween sequence([Tween sequence(Tween:constant Tween < double & gt;(0.0),权重:55),TweenSequenceItem(Tween:Tween(begin:0.0,end: 1.0),权重:10),TweenSequenceItem(Tween:Tween(begin:1.0,end: 1.0),权重:35),);静态tween sequence rectweensequence 2 = tween sequence([tween sequence item(tween:constant tween & lt;double & gt(0.0),权重:65),TweenSequenceItem(Tween:Tween(begin:0.0,end: 1.0),权重:10),TweenSequenceItem(Tween:constant Tween & lt;double & gt(1.0),权重:25),]);因为它是两个矩形的变体,所以我们使用堆栈来包装...@ override Widget build(build context context){ return animation:_ controller,builder: (BuildContext context,Widget child){ return Center(child:Transform(alignment:alignment . Center,Transform:matrix 4 . rotation z(math . pi * _ rotationween . value),child:Stack(alignment:alignment . Center,children:[Container(height:_ trianglesizetween . value,width: _triangleSizeTween.value),child:custom paint(paint:square paint(progress:_ 1}, );}最终效果如下:square.gif5 .实现水波变化和放大效果稍微复杂一点。由于我们整个过程中的所有动画都是由AnimationController控制的,所以我们也需要一个动画来控制水波振荡的效果。但我们的_HWAnimatePageState是从SingleTickerProviderStateMixin继承的,它只能有一个AnimationController。 基于这种情况,水波动画被绘制到一个单独的widget中,你可以在自己设置的wave_progress中看到源代码。绘制水波的代码如下。//绘制水波动画paint wave paint = newpaint()..color = wavecolor//水波振幅双amp = 2.0双p =进度/100.0;double base height =(1-p)* size . height;Path Path = Path();path.moveTo(0.0,base height);for(双i = 0.0我& lt尺寸.宽度;i++) { path.lineTo( i,base height+math . sin((I/size . width * 2 * math . pi)+(animation . value * 2 * math . pi))* amp-15);} path.lineTo(size.width,size . height-15);path.lineTo(0.0,size . height-15);path . close();canvas.drawPath(path,wave paint);水波上升变大后显示的文字的补间过程如下。//水波的动画上升变化静态补间序列=补间序列([补间序列项(tween:常数补间< double & gt(0.0),权重:75),TweenSequenceItem(Tween:Tween(begin:0.0,end: 1.0),权重:10),TweenSequenceItem(Tween:constant Tween & lt;double & gt(1.0),权重:15),]);//水波宽度和高度的变化静态tween序列waveidthtween序列= tween序列([tween序列(tween:常数tween < double & gt(120.0),权重:80),TweenSequenceItem(Tween:Tween(begin:120.0,end: screenWidth),权重:10),TweenSequenceItem(Tween:constant Tween & lt;double & gt(屏幕宽度),重量:10),]);静态tween sequence wave height tween sequence = tween sequence([tween sequence item(tween:constant tween & lt;double & gt(120.0),权重:80),TweenSequenceItem(Tween:Tween(begin:120.0,end: screenHeight),权重:10),TweenSequenceItem(Tween:constant Tween & lt;double & gt(屏幕高度),重量:10),]);//最后显示的文本更改过程静态补间序列textsizetweensequence =补间序列([tween:constant tween < double & gt;(0),权重:85),TweenSequenceItem(Tween:Tween(begin:0.0,end: 30.0),权重:10),TweenSequenceItem(Tween:constant Tween & lt;double & gt(50),权重:5),]);根据Tween,效果如下:wave.gif6实现组合动画,将以上步骤的动画效果全部放入一个Stack @ override Widget build(build context context){ return animated builder(animation:_ controller,builder: (BuildContext context,Widget child){ return Center(child:Transform(alignment:alignment . Center,Transform:matrix 4 . rotation z(math . pi * _ rotationween . value),child:Stack(alignment:alignment . Center,children:[clip rect(borderRadius:borderRadius . circular child:custom paint(painter:trianglefttween . value,right:_ trianglefttween . value,top: _triangleTopTween.value,),),Container(height:_ trianglesizetween . value,width: _triangleSizeTween.value:_ trianglesizetween . value,child:custom paint(painter:square painter(progress:_ rect 1 tween . value),),Container(height:_ trianglesizetween . value,width:_ trianglesizetween . value),child:custom }, );}这样每个widget都会根据它所依赖的补间值来制作动画,最终实现加载动画的效果。 最后,相比原来的iOS原生开发,Flutter更方便的实现少量的效果,比如布局,比如英雄动画,所以我更看好Flutter。 后面也会多参考一点颤振知识。 比如,其实分析这部动画的每一步都不是太难,但是你要有足够的耐心去分析,去面对困难。 你可以从这里看到所有的最终源代码。欢迎明星!


  • 全部评论(0)
资讯详情页最新发布上方横幅
最新发布的资讯信息
【技术支持|常见问题】1556原创ng8文章搜索页面不齐(2024-05-01 14:43)
【技术支持|常见问题】1502企业站群-多域名跳转-多模板切换(2024-04-09 12:19)
【技术支持|常见问题】1126完美滑屏版视频只能显示10个(2024-03-29 13:37)
【技术支持|常见问题】响应式自适应代码(2024-03-24 14:23)
【技术支持|常见问题】1126完美滑屏版百度未授权使用地图api怎么办(2024-03-15 07:21)
【技术支持|常见问题】如何集成阿里通信短信接口(2024-02-19 21:48)
【技术支持|常见问题】算命网微信支付宝产品名称年份在哪修改?风水姻缘合婚配对_公司起名占卜八字算命算财运查吉凶源码(2024-01-07 12:27)
【域名/主机/服务器|】帝国CMS安装(2023-08-20 11:31)
【技术支持|常见问题】通过HTTPs测试Mozilla DNS {免费源码}(2022-11-04 10:37)
【技术支持|常见问题】别告诉我你没看过邰方这两则有思想的创意广告! (2022-11-04 10:37)

联系我们
Q Q:375457086
Q Q:526665408
电话:0755-84666665
微信:15999668636
联系客服
企业客服1 企业客服2 联系客服
86-755-84666665
手机版
手机版
扫一扫进手机版
返回顶部