網站首頁 編程語言 正文
前面我們花了幾篇介紹了貝塞爾曲線的原理和繪制貝塞爾曲線,著實讓我們見識到了貝塞爾曲線的美。好奇心驅使我想看看貝塞爾曲線動起來會是什么樣?本篇就借由動畫驅動貝塞爾曲線繪制看看動起來的貝塞爾曲線什么效果。
彩虹系列
通過動畫控制繪制的結束點,就可以讓貝塞爾曲線動起來。例如下面的動圖展示的效果,看起來像搭了一個滑滑梯一樣。實際上就是用7條貝塞爾曲線實現的,我們使用了 Animation
對象的值來控制繪制的結束點,從而實現了對應的動畫效果。
具體源碼如下,其中控制繪制結束點就是在動畫過程中修改循環的次數,即t <= (100 * animationValue).toInt();
這句代碼,其中 animationValue 是動畫控制器當前值,范圍時從0-1。
class AnimationBezierPainter extends CustomPainter { AnimationBezierPainter({required this.animationValue}); final double animationValue; @override void paint(Canvas canvas, Size size) { final lineWidth = 6.0; paint.strokeWidth = lineWidth; paint.style = PaintingStyle.stroke; final colors = [ Color(0xFFE05100), Color(0xFFF0A060), Color(0xFFE0E000), Color(0xFF10F020), Color(0xFF2080F5), Color(0xFF104FF0), Color(0xFFA040E5), ]; final lineNumber = 7; for (var i = 0; i < lineNumber; ++i) { paint.color = colors[i % colors.length]; _drawAnimatedLines(canvas, paint, size, size.height / 4 + i * lineWidth); } } @override bool shouldRepaint(covariant CustomPainter oldDelegate) { return true; } _drawRainbowLines(Canvas canvas, Paint paint, Size size, yPos) { var yGap = 60.0; var p0 = Offset(0, yPos - yGap / 2); var p1 = Offset(size.width * 2 / 3, yPos - yGap); var p2 = Offset(size.width / 3, yPos + yGap); var p3 = Offset(size.width, yPos + yGap * 1.5); var path = Path(); path.moveTo(p0.dx, p0.dy); for (var t = 1; t <= (100 * animationValue).toInt(); t += 1) { var curvePoint = BezierUtil.get3OrderBezierPoint(p0, p1, p2, p3, t / 100.0); path.lineTo(curvePoint.dx, curvePoint.dy); } canvas.drawPath(path, paint); } }
我們修改曲線的控制點還可以實現下面的效果,大家有興趣可以自己嘗試一下。
彈簧動畫
用多個貝塞爾曲線首尾相接,在垂直方向疊起來就能畫出一條彈簧了,然后我們更改彈簧的間距和高度(曲線的數量)就能做出彈簧壓下去和彈起來的動畫效果了。
這部分的代碼如下所示:
@override void paint(Canvas canvas, Size size) { var paint = Paint()..color = Colors.black54; final lineWidth = 2.0; paint.strokeWidth = lineWidth; paint.style = PaintingStyle.stroke; final lineNumber = 20; // 彈簧效果 final yGap = 2.0 + 16.0 * animationValue; for (var i = 0; i < (lineNumber * animationValue).toInt(); ++i) { _drawSpiralLines( canvas, paint, size, size.width / 2, size.height - i * yGap, yGap); } } _drawSpiralLines(Canvas canvas, Paint paint, Size size, double xPos, double yPos, double yGap) { final xWidth = 160.0; var p0 = Offset(xPos, yPos); var p1 = Offset(xPos + xWidth / 2 + xWidth / 4, yPos - yGap); var p2 = Offset(xPos + xWidth / 2 - xWidth / 4, yPos - 3 * yGap); var p3 = Offset(xPos, yPos - yGap); var path = Path(); path.moveTo(p0.dx, p0.dy); for (var t = 1; t <= 100; t += 1) { var curvePoint = BezierUtil.get3OrderBezierPoint(p0, p1, p2, p3, t / 100.0); path.lineTo(curvePoint.dx, curvePoint.dy); } canvas.drawPath(path, paint); }
復雜立體感動畫
通過多條貝塞爾圖形組成的曲線往往會有立體的效果,而立體的效果動起來的時候就會感覺是3D 動畫一樣,實際上通過貝塞爾曲線是能夠繪制出一些3D 效果的動畫的,比如下面這個效果,就感覺像在三維空間飛行一樣(如果配上背景圖移動會更逼真)。這里實際使用了4組貝塞爾曲線來實現,當然實際還可以畫一些有趣的圖形,比如說畫一條魚。這個源碼比較長,就不貼了,有興趣的可以自行去下載源碼(注:本篇之后的 Flutter版本升級到了2.10.3):繪圖相關源碼。
總結
可以看到,通過動畫控制貝賽爾曲線動起來的效果還是挺有趣的。而且,我們還可以根據之前動畫相關的篇章做一些更有趣的效果出來。這種玩法可以用在一些特殊的加載動畫或是做一些比較酷炫的特效上面,增添 App 的趣味性。
原文鏈接:https://juejin.cn/post/7095735501793001479
相關推薦
- 2022-08-28 SpringCloudAlibaba-3.分布式事務(Seata)
- 2022-04-09 Redis分布式鎖防止緩存擊穿的實現_Redis
- 2022-12-08 c++只保留float型的小數點后兩位問題_C 語言
- 2022-09-30 ASP.NET?MVC為用戶創建專屬文件夾_實用技巧
- 2022-08-13 Redis - 時間序列數據類型的保存方案和消息隊列實現
- 2022-06-23 詳解windows?server?2012的DHCP保留地址導出導入、DHCP故障轉移配置、DNS條
- 2022-06-22 C++詳細分析引用的使用及其底層原理_C 語言
- 2022-11-23 GoLang?channel底層代碼實現詳解_Golang
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支