人人做人人干-人人做人人看-人人做人人爽国产视-人人做人人爽人人爱-色屋视频-色屋网

歡迎您光臨深圳塔燈網絡科技有限公司!
電話圖標 余先生:13699882642

網站百科

為您解碼網站建設的點點滴滴

Flutter動畫設計原理

發表日期:2018-12 文章編輯:小燈 瀏覽次數:2783

動畫實現的方式

Flutter中,我們可以簡單的把調用this.setState()理解為渲染一幀。那么只要我們不停的在調用這個方法的同時更新位置信息,就能實現平移動畫了,其他動畫也是如此。

而Flutter也是這么做的。

這個方式說起來很簡單,但是想要將它封裝成一個使用簡單的框架,卻很不容易。

Flutter的實現

在Flutter中有兩大基類 Animatable 和 Animation

  • Animatable
    這個控制的是動畫的類型的類。例如平移動畫我們關心的是x,y。那么Animatable就需要控制x,y的變化。顏色動畫我們關心的是色值得變化,那么Animatable就需要控制色值。
    貝塞爾曲線運動,我們關心的是路徑是按照貝塞爾方程式來生成x y,所以Animatable要有按照貝塞爾方程式的方式改變x,y。

  • Animation
    這個是控制動畫運動過程的類,不關心動畫的類型。例如動畫開始,停止,反轉,還有各種ease得效果。
    并不關心你是平移,縮放還是貝塞爾曲線動畫。因為所有的動畫這些狀態都是一樣的。

假如我們想實現一個從0平移到200位置的動畫該怎么做呢?

按照Flutter的實現方式我們要先要實現一個對應的Animatable。當然flutter已經為我門預制了很多類,Tween這個類就可已實現。
很多說Tween是補間動畫,自認為很是不準確。這里的Tween其實是一個一元一次函數的實現。簡單的說就是單個維度的漸變動畫。
如果要實現多維度的動畫,就需要自己實現Animatable。

T lerp(double t) { assert(begin != null); assert(end != null); return begin + (end - begin) * t; }T transform(double t) { if (t == 0.0) return begin; if (t == 1.0) return end; return lerp(t); } 

有了Animatable,我們還需要一個Animation,要不然怎么開始動畫?

當然Animation Flutter也為我們預制了。AnimationController就是一個。

各種類都有了就開始寫代碼

class _SimpleRouteState extends State<SimpleRoute> with SingleTickerProviderStateMixin{ ...AnimationController _controller;@override void initState() { _controller = AnimationController( duration : Duration(seconds: 1) , vsync: this ); ... }//點擊按鈕 開始動畫 _offsetAnim(bool isForward){ Animation<double> animation = Tween( begin:0.0 , end: 200.0).animate(_controller); animation.addListener((){ this.setState((){ this.left = animation.value; }); }); if(isForward){ _controller.forward(); }else{ _controller.reverse(); } } } 

上面的代碼先創建一個Animatable,然后調用animate(),傳入Animation
Animation 開始動畫。
每刷一幀都會執行一次

this.setState((){ this.left = animation.value; }); 

動畫就實現了

動畫實現原理

帶著幾個問題分析:
1.AnimationController在動畫中扮演一個什么角色?
2.調用forward之后,為什么動畫就會開始?
3.是誰驅動動畫一直執行,難道有for循環嗎?

AnimationController的角色

  • Overview

我的理解:AnimationController 將動畫描述成一個可以量化的過程,這個量化的值就是從0.0到1.0的過程(采用默認的下限值和上限值)。
從0.0到1.0就是forward , 從1.0到0.0就是reverse。而這個值就是_value這個變量。

  • 如何實現從0.0到1.0的過程?

通過Ticker來接受GPU的垂直同步信號,在每次接受到信號后更新這個值。

//收到垂直信號后的回調處理方法 void _tick(Duration elapsed) { _lastElapsedDuration = elapsed; final double elapsedInSeconds = elapsed.inMicroseconds.toDouble() / Duration.microsecondsPerSecond; assert(elapsedInSeconds >= 0.0); _value = _simulation.x(elapsedInSeconds).clamp(lowerBound, upperBound); if (_simulation.isDone(elapsedInSeconds)) { _status = (_direction == _AnimationDirection.forward) ? AnimationStatus.completed : AnimationStatus.dismissed; stop(canceled: false); } notifyListeners(); _checkStatusChanged(); } 

這也就是為什么構建必須要傳入vsync的原因,AnimationController用他來創建一個Ticker的。

  • forward之后做了啥?

先停止當前正在進行的動畫,然后調用Ticker的start(),開始接受垂直同步的回調,然后再回調中根據流失的時間,來計算當前的value值。
從而達到控制動畫進程的目的。

TickerFuture forward({ double from }) { ... //如果from沒有值,就默認是動畫到1.0(upperBound的默認值是1.0) _direction = _AnimationDirection.forward; if (from != null) value = from; return _animateToInternal(upperBound); }//構建一個Simulation TickerFuture _animateToInternal(double target, { Duration duration, Curve curve = Curves.linear, AnimationBehavior animationBehavior }) { ...if (simulationDuration == null) { ... // final double range = upperBound - lowerBound; final double remainingFraction = range.isFinite ? (target - _value).abs() / range : 1.0; simulationDuration = this.duration * remainingFraction; } else if (target == value) { // Already at target, don't animate. simulationDuration = Duration.zero; } stop(); ...return _startSimulation(_InterpolationSimulation(_value, target, simulationDuration, curve, scale)); }//開啟_ticker value開始從0.0到1.0變化。 TickerFuture _startSimulation(Simulation simulation) {... _value = simulation.x(0.0).clamp(lowerBound, upperBound); final TickerFuture result = _ticker.start(); ...return result; } 

由此可見 AnimationController 在動畫中扮演著控制動畫過程的角色,通過維護著一個從0.0到1.0的變量來控制動畫的進行。

Tween的角色

  • Overview

    配合AnimationController,將一個變量從begin變化到end的過程。這個變化的過程是一個簡單的一元一次函數。
    t的取值范圍是[0,1]。若t是均勻變化的,就是線性的從begin到end。

    T lerp(double t) { return begin + (end - begin) * t; } 

    若這個變量是多個維度,例如是一個Rect,有四個變量,那就要從寫這個方法了。可以參見RectTween。

  • Animation<T> animate(Animation parent) 這個方法做了啥?

這個就需要了解一個Flutter的私有類 _AnimatedEvaluation 它的父類是Animation。
它起到了連接Tween和AnimationController的作用,具體體現在它的get value的實現

@override T get value => _evaluatable.evaluate(parent); 

這個_evaluatable就是構建_AnimatedEvaluation傳入的Tween,這句話會調用Tween的evaluate(),最終會調用上面的lerp();lerp參數t就是AnimationController維護的那個從0.0到1.0的變量。

當你每次在setState()后調用animation.value,就會走上面這個個方法,得到的就是當前時間點的動畫的值。這樣,整個動畫就被驅動起來了。所以Flutter動畫里面不存在for循環。

總結

* 如何用flutter實現一個貝塞爾曲線運動?

原理:繼承Animatable實現一個_BezierTween,并重寫他的transform();這里直接將貝塞爾曲線方程式帶進去即可。
當然重寫Tween的lerp方法也是可行的。

bei.jpeg i2lhs-vedko.gif

實現源碼:

class _Point{ const _Point({this.x , this.y});final double x; final double y; }class _BezierTween extends Animatable<_Point>{ _BezierTween({ this.p0, this.p1, this.p2 }):assert(p0 != null), assert(p1 != null), assert(p2 != null);final _Point p0; //起始點 final _Point p1; //途徑點 final _Point p2; //終點@override transform(double t) { double x = (1-t) * (1-t) * p0.x + 2 * t * (1-t) * p1.x + t * t * p2.x; double y = (1-t) * (1-t) * p0.y + 2 * t * (1-t) * p1.y + t * t * p2.y; return _Point( x:x , y:y ); } } 

使用

@override void initState() { super.initState();_controller = AnimationController(duration:Duration(seconds: 2) , vsync: this);_p0= _Point( x:30,y:30); _p1= _Point( x:30,y:200); _p2= _Point( x:200,y:200); _animation = _BezierTween(p0: _p0 , p1: _p1 , p2: _p2).animate(_controller); _animation.addListener((){ this.setState((){}); }); }

本頁內容由塔燈網絡科技有限公司通過網絡收集編輯所得,所有資料僅供用戶學習參考,本站不擁有所有權,如您認為本網頁中由涉嫌抄襲的內容,請及時與我們聯系,并提供相關證據,工作人員會在5工作日內聯系您,一經查實,本站立刻刪除侵權內容。本文鏈接:http://www.kwpm.com.cn/17759.html
上一篇:Flutter 初嘗 下一篇:Flutter VS Weex
相關APP開發
 八年  行業經驗

多一份參考,總有益處

聯系深圳網站公司塔燈網絡,免費獲得網站建設方案及報價

咨詢相關問題或預約面談,可以通過以下方式與我們聯系

業務熱線:余經理:13699882642

Copyright ? 2013-2018 Tadeng NetWork Technology Co., LTD. All Rights Reserved.    

主站蜘蛛池模板: 久久高清精品 | 成人污视频网站 | 男女第一次弄进去的视频 | sss亚洲国产欧美一区二区 | 三级在线免费观看 | 制服丝袜在线不卡 | 日韩色视频一区二区三区亚洲 | 精品一区二区三区在线观看 | 亚洲精品高清视频 | 精品国产自在现线看久久 | 男女男在线观看视频网站 | 亚洲欧美另类在线观看 | 日韩精品国产自在久久现线拍 | 天天谢天天干 | 亚洲日韩中文字幕 | 亚洲妇熟xxxxx妇色黄 | 免播放器在线视频 | 欧美日韩一本二本 | 欧美成人综合在线 | 亚洲国产情侣一区二区三区 | 成人免费xxx色视频 成人免费xxxxx在线视频 | 日韩a在线 | 色综合五月天 | 欧美国产日本精品一区二区三区 | 97人洗澡人人澡人人爽 | 国产高清天干天天美女 | 在线播放成人毛片免费视 | 免费观看黄a一级视频日本 免费观看黄a一级视频 | 成人在线播放视频 | 免费羞羞视频 | 国产成人欧美一区二区三区vr | 最近2019最新中文字幕3 | 欧美精品一区二区久久 | 中文字幕亚洲第一 | 欧美三级欧美成人高清www | 黄色一级毛片免费 | 夜夜爽夜夜叫夜夜高潮漏水 | 亚洲第成色999久久网站 | 亚洲欧美另类日本久久影院 | 99色网站| 午夜寂寞影院视频在线观看 |