Android利用貝塞爾曲線繪制動(dòng)畫的示例代碼
前面我們花了幾篇介紹了貝塞爾曲線的原理和繪制貝塞爾曲線,著實(shí)讓我們見(jiàn)識(shí)到了貝塞爾曲線的美。好奇心驅(qū)使我想看看貝塞爾曲線動(dòng)起來(lái)會(huì)是什么樣?本篇就借由動(dòng)畫驅(qū)動(dòng)貝塞爾曲線繪制看看動(dòng)起來(lái)的貝塞爾曲線什么效果。
彩虹系列
通過(guò)動(dòng)畫控制繪制的結(jié)束點(diǎn),就可以讓貝塞爾曲線動(dòng)起來(lái)。例如下面的動(dòng)圖展示的效果,看起來(lái)像搭了一個(gè)滑滑梯一樣。實(shí)際上就是用7條貝塞爾曲線實(shí)現(xiàn)的,我們使用了 Animation
對(duì)象的值來(lái)控制繪制的結(jié)束點(diǎn),從而實(shí)現(xiàn)了對(duì)應(yīng)的動(dòng)畫效果。
具體源碼如下,其中控制繪制結(jié)束點(diǎn)就是在動(dòng)畫過(guò)程中修改循環(huán)的次數(shù),即t <= (100 * animationValue).toInt();
這句代碼,其中 animationValue 是動(dòng)畫控制器當(dāng)前值,范圍時(shí)從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); } }
我們修改曲線的控制點(diǎn)還可以實(shí)現(xiàn)下面的效果,大家有興趣可以自己嘗試一下。
彈簧動(dòng)畫
用多個(gè)貝塞爾曲線首尾相接,在垂直方向疊起來(lái)就能畫出一條彈簧了,然后我們更改彈簧的間距和高度(曲線的數(shù)量)就能做出彈簧壓下去和彈起來(lái)的動(dòng)畫效果了。
這部分的代碼如下所示:
@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); }
復(fù)雜立體感動(dòng)畫
通過(guò)多條貝塞爾圖形組成的曲線往往會(huì)有立體的效果,而立體的效果動(dòng)起來(lái)的時(shí)候就會(huì)感覺(jué)是3D 動(dòng)畫一樣,實(shí)際上通過(guò)貝塞爾曲線是能夠繪制出一些3D 效果的動(dòng)畫的,比如下面這個(gè)效果,就感覺(jué)像在三維空間飛行一樣(如果配上背景圖移動(dòng)會(huì)更逼真)。這里實(shí)際使用了4組貝塞爾曲線來(lái)實(shí)現(xiàn),當(dāng)然實(shí)際還可以畫一些有趣的圖形,比如說(shuō)畫一條魚(yú)。這個(gè)源碼比較長(zhǎng),就不貼了,有興趣的可以自行去下載源碼(注:本篇之后的 Flutter版本升級(jí)到了2.10.3):繪圖相關(guān)源碼。
總結(jié)
可以看到,通過(guò)動(dòng)畫控制貝賽爾曲線動(dòng)起來(lái)的效果還是挺有趣的。而且,我們還可以根據(jù)之前動(dòng)畫相關(guān)的篇章做一些更有趣的效果出來(lái)。這種玩法可以用在一些特殊的加載動(dòng)畫或是做一些比較酷炫的特效上面,增添 App 的趣味性。
到此這篇關(guān)于Android利用貝塞爾曲線繪制動(dòng)畫的示例代碼的文章就介紹到這了,更多相關(guān)Android貝塞爾曲線內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android實(shí)現(xiàn)從底部彈出的Dialog示例(一)
這篇文章主要介紹了Android實(shí)現(xiàn)從底部彈出的Dialog示例(一),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-01-01android實(shí)現(xiàn)計(jì)步功能初探
這篇文章主要介紹了android實(shí)現(xiàn)計(jì)步功能初探,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-12-12Android利用ShaderMask實(shí)現(xiàn)花里胡哨的文字特效
我們的?App?大部分時(shí)候的文字都是一種顏色,實(shí)際上,文字的顏色也可以多姿多彩。我們今天就來(lái)介紹一個(gè)能夠輕松實(shí)現(xiàn)文字漸變色的組件?——?ShaderMask,感興趣的可以了解一下2022-12-12Android Insets相關(guān)知識(shí)總結(jié)
這篇文章主要介紹了Android Insets相關(guān)知識(shí)總結(jié),幫助大家更好的理解和學(xué)習(xí)使用Android,感興趣的朋友可以了解下2021-03-03安卓開(kāi)發(fā)之FragmentPagerAdapter和FragmentStatePagerAdapter詳解
這篇文章主要介紹了安卓開(kāi)發(fā)之FragmentPagerAdapter和FragmentStatePagerAdapter詳解的相關(guān)資料,需要的朋友可以參考下2022-08-08Android測(cè)量每秒幀數(shù)Frames Per Second (FPS)的方法
這篇文章主要介紹了Android測(cè)量每秒幀數(shù)Frames Per Second (FPS)的方法,涉及Android針對(duì)多媒體文件屬性操作的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-10-10