網站首頁 編程語言 正文
前言
繼續動畫探索,今天用Flutter制作一個心碎的感覺,靈感來源于今天的股市,哎,心哇涼哇涼的。廢話不多說,開始。
效果圖先上:
實現步驟
1、繪制一個心
首先我們使用兩段三階貝塞爾曲線制作一個心型,這里因為需要實現心碎的效果,所以我們需要將心的兩段用兩段路徑path
進行繪制出來,效果:
繪制代碼:
canvas.translate(size.width / 2, size.height / 2); Paint paint = Paint(); paint ..style = PaintingStyle.stroke ..strokeWidth = 2 ..color = Colors.black87; Path path = Path(); path.moveTo(0, 0); path.cubicTo(-200, -80, -60, -240, 0, -140); path.close(); Path path2 = Path(); canvas.save(); canvas.drawPath( path, paint ..color = Colors.red ..style = PaintingStyle.stroke); canvas.restore(); path2.cubicTo(200, -80, 60, -240, 0, -140); path2.close(); canvas.drawPath( path2, paint..color = Colors.black87);
2、繪制心的裂痕
我們看到心確實分成兩半了,但是中間還缺少裂痕,接下來我們就繪制心碎的裂痕,也很簡單,在兩段路徑path
閉合前進行繪制線,效果:
繪制代碼:
path.relativeLineTo(-10, 30); path.relativeLineTo(20, 5); path.relativeLineTo(-20, 30); path.relativeLineTo(20, 20); path.relativeLineTo(-10, 20); path.relativeLineTo(10, 10); path2.relativeLineTo(-10, 30); path2.relativeLineTo(20, 5); path2.relativeLineTo(-20, 30); path2.relativeLineTo(20, 20); path2.relativeLineTo(-10, 20); path2.relativeLineTo(10, 10);
OK,我們已經看到心已經有了裂痕,如何心碎,只需將畫布進行翻轉一定角度即可,這里我們將畫布翻轉45°,看下效果:
左邊:
右邊:
3、加入動畫
已經有心碎的感覺了,接下來加入動畫元素讓心碎的過程動起來。
思路: 我們可以想一下,心碎的過程是什么樣子,心的顏色慢慢變灰,心然后慢慢裂開,下方的動畫運動曲線看起來更符合心碎的過程,里面有不舍,不甘,但最后心還是慢慢的碎了。
我們把畫筆進行填充將這個動畫加入進來看下最終效果。
是不是心碎了一地。
知識點: 這里我們需要找到紅色和灰色的RGB色值,通過Color.fromRGBO(r, g, b, opacity)
方法賦值顏色的色值。然后通過動畫值改變RGB的值即可。 這里我使用的色值是:
紅色:Color.fromRGBO(255, 0, 0, 1)
灰色:Color.fromRGBO(169, 169, 169, 1)
完整代碼
class XinSui extends StatefulWidget { const XinSui({Key? key}) : super(key: key); @override _XinSuiState createState() => _XinSuiState(); } class _XinSuiState extends State<XinSui> with SingleTickerProviderStateMixin { late AnimationController _controller = AnimationController(vsync: this, duration: Duration(milliseconds: 4000)) ..repeat(); late CurvedAnimation cure = CurvedAnimation(parent: _controller, curve: Curves.bounceInOut); late Animation<double> animation = Tween<double>(begin: 0.0, end: 1.0).animate(cure); @override Widget build(BuildContext context) { return Container( child: CustomPaint( size: Size(double.infinity, double.infinity), painter: _XinSuiPainter(animation), ), ); } @override void dispose() { _controller.dispose(); super.dispose(); } } class _XinSuiPainter extends CustomPainter { Animation<double> animation; _XinSuiPainter(this.animation) : super(repaint: animation); @override void paint(Canvas canvas, Size size) { canvas.translate(size.width / 2, size.height / 2); Paint paint = Paint(); paint ..style = PaintingStyle.stroke ..strokeWidth = 2 ..color = Colors.black87; Path path = Path(); path.moveTo(0, 0); path.cubicTo(-200, -80, -60, -240, 0, -140); path.relativeLineTo(-10, 30); path.relativeLineTo(20, 5); path.relativeLineTo(-20, 30); path.relativeLineTo(20, 20); path.relativeLineTo(-10, 20); path.relativeLineTo(10, 10); path.close(); Path path2 = Path(); canvas.save(); canvas.rotate(-pi / 4 * animation.value); canvas.drawPath( path, paint ..color = Colors.red ..color = Color.fromRGBO( 255 - (86 * animation.value).toInt(), (animation.value * 169).toInt(), (animation.value * 169).toInt(), 1) ..style = PaintingStyle.fill); canvas.restore(); path2.cubicTo(200, -80, 60, -240, 0, -140); path2.relativeLineTo(-10, 30); path2.relativeLineTo(20, 5); path2.relativeLineTo(-20, 30); path2.relativeLineTo(20, 20); path2.relativeLineTo(-10, 20); path2.relativeLineTo(10, 10); path2.close(); canvas.rotate(pi / 4 * animation.value); canvas.drawPath( path2,paint); } @override bool shouldRepaint(covariant _XinSuiPainter oldDelegate) { return oldDelegate.animation != animation; } }
小結
動畫曲線Curves配合繪制可以實現很多好玩的東西,這個需要勤加練習方能掌握,僅將此心碎獻給今天受傷的股民朋友們
原文鏈接:https://juejin.cn/post/7090457954415017991
相關推薦
- 2023-11-16 python list列表拼接
- 2022-08-01 詳解Selenium中元素定位方式_python
- 2023-04-17 淺談Golang數據競態_Golang
- 2024-07-18 【探索SpringCloud】服務發現-Nacos服務端數據結構和模型
- 2022-07-09 嵌入式linux使用trace調試步驟記錄
- 2022-10-10 C++超詳細分析type_traits_C 語言
- 2022-07-15 Android?Flutter繪制扇形圖詳解_Android
- 2022-07-14 Nginx限流和黑名單配置的策略_nginx
- 最近更新
-
- 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同步修改后的遠程分支