用贝塞尔曲线绘制带有文本的波浪球控件

作者:admin 2019-11-24 13:12:32 0 标签:

原始标题:用贝塞尔曲线绘制带有文本的波浪球控件

近日,暴风集团发布了2019年第三季度财务报告:该公司前三季度收入为9360万元,同比下降90.95%。净利润亏损6.5亿元,同比下降184.50%,亏损2.28亿元。

与此同时,深交所向暴风集团发出了一封关注信,称除了被批准逮捕的总经理冯欣之外,公司所有高级管理人员均已辞职,协助信息披露的证券代表也已辞职。请尽快任命相关高级管理人员,确保公司稳定运行,及时履行信息披露义务。

忙碌的一周过去了,明天将是一个快乐的星期六。我希望每个人都能好好休息。

本文来源于叶陈至的贡献,分享了他使用颤振进行的高级用户界面效果定制,希望对大家有所帮助!同时,我也感谢作者精彩的文章。

叶陈至的博客地址:

https://juejin.im/user/57c2ea9befa631005abd00c6

https://juejin.im/user/57c2ea9befa631005abd00c6

/body/

颤振中的定制窗口小部件(custom Widget)被视为颤振系统中的高级知识点之一,相当于原始开发中的定制视图。根据我的个人经验,自定义小部件的难度低于自定义视图。然而,由于flux的开源库目前并不丰富,一些效果仍然需要开发人员自己来实现。本文将介绍如何使用颤振实现一个带文本的波浪球小部件,效果如下:

首先,总结波形加载工具(WaveLoadingWidget)的特点,从而总结达到效果所需的步骤。

小部件的主体是一个不规则的半圆,顶部以波浪式的方式从左到右上下移动。

展开全文

球面波可以定制颜色,在这里被命名为波色(waveColor)。

波浪线将嵌入文本分为上下两种颜色。上部文本颜色以背景颜色命名,而下部文本颜色以前景颜色命名。文本的颜色总是动态变化的。

虽然波浪在不断运动,但只要能画出一帧的图形,动态效果就可以通过不断改变波浪的位置参数来完成,所以这里小部件被认为是静态的,静态效果可以先实现。

将绘图步骤分解为以下步骤:

在背景色中绘制文本,并在画布底部绘制。

根据小部件的宽度和高度信息,构造不超过该范围的最大循环路径(circlePath)。

以圆环路径(circlePath)的水平中线为波浪的波浪线,利用贝塞尔曲线分别在波浪线的上侧和下侧画出连续的波路径,路径的末端和末端以矩形形式连接在一起形成波路径,波路径的底部与圆环路径的底部相交于一点。

取圆形路径和波形路径、目标路径的交点,并用波形颜色填充。这时,你会看到半圆形的球面波。

使用canvas.clipPath(targetPath)方法修剪画布,然后用前底色的颜色绘制文本。此时,绘制的前景颜色文本(foregroundColor text)将只显示targetPath内的部分,从而与在两个不同时间绘制的文本重叠,获得不同颜色范围的文本。

颤振动画(Floot animation)用于连续改变wavePath起始点的x坐标,同时重新绘制用户界面,以获得波浪不断从左向右移动的效果。

现在让我们一步一步地实现上面的绘制步骤。

1。初始化画笔

flux通过抽象类custompaint为开发人员提供了一个进入自绘制用户界面的入口。其内部抽象方法void paint(画布画布,尺寸大小)提供了画布对象画布尺寸对象包含小部件宽度和高度信息。

由此继承自定义画笔类,初始化画笔对象和各种配置参数(要绘制的文本、颜色值等)。)

class waveloading PaintErextendscustomPainter {

//如果外部没有指定颜色值,则使用该默认颜色值

静态最终颜色默认值颜色=颜色。浅蓝色;

//画笔对象

var _ paint = Paint

//圆形路径

路径_循环路径=路径;

//波形路径

路径_波形路径=路径;

//要显示的文本

最终字符串文本;

//字体大小

最终双字体大小;

最终颜色背景颜色;

最终颜色前景颜色;

最终颜色波形颜色;

波形加载绘制器(

{这个. text,

这个. fontSize,

背景颜色,

这是前底色,

这个.波形}) {

油漆(_ t)

..isAntiAlias =真

..style =绘画Style.fill

..strokeWidth = 3

..颜色=波形颜色??默认颜色;

}

@覆盖

空隙漆(帆布,尺寸大小){

}

@覆盖

boolshouldRepaint(海关油漆工老代表){

returntrue

}

}

二。绘制背景彩色文本

颤振的画布对象不提供直接绘制文本的应用编程接口,绘制文本的步骤比本地自定义视图更麻烦

@覆盖

空隙漆(帆布,尺寸大小){

双面=最小值(尺寸、宽度、尺寸、高度);

双半径=边/2.0;

_drawText(画布:画布,侧面:侧面,颜色:背景颜色);

}

void _ DrawText({画布画布,双面,颜色}) {

paragraph Builder Pb = paragraph Builder(paragraph STYLe(

文本对齐:文本对齐。居中,

fontStyle: FontStyle.normal,

字体大小:字体大小??0,

);

pb.pushStyle(用户界面。文本样式(颜色:颜色??默认颜色));

pb.addText(文本);

段落约束pc =段落约束(宽度:字体大小??0);

段落段落= pb.build..布局(PC);

画布.绘图段落(

段落,

偏移(

(侧段宽度)/ 2.0,(侧段高度)/2.0);

}

三。构建环形路径

小部件的宽度和高度的最小值作为圆的直径,以构造不超出小部件范围的最大圆形路径。

@覆盖

空隙漆(帆布,尺寸大小){

双面=最小值(尺寸、宽度、尺寸、高度);

双半径=边/2.0;

_drawText(画布:画布,侧面:侧面,颜色:背景颜色);

_ circlePath.reset

_circlePath.addArc(矩形,从LTWH(0,0,边,边),0,2 * pi);

}

4。使用贝塞尔曲线绘制波浪线

这里,波浪的宽度和高度根据固定的比例值来评估,以_circlePath的中间分隔线作为水平线,并且根据水平线上方和下方的贝塞尔曲线来绘制连续的波浪线

@覆盖

空隙漆(帆布,尺寸大小){

双面=最小值(尺寸、宽度、尺寸、高度);

双半径=边/2.0;

_drawText(画布:画布,侧面:侧面,颜色:背景颜色);

_ circlePath.reset

_circlePath.addArc(矩形,从LTWH(0,0,边,边),0,2 * pi);

双波长宽度=边* 0.8;

双波长高度=边/6;

_ wavePath.reset

_波形路径.移动到(-波形宽度,半径);

对于(double I =-WaveWidth;i <。侧面;i +=波形宽度)

_ WavePath . relativeequadraticbezierto(

波宽/ 4,-波高,波宽/ 2,0);

_ WavePath . relativeequadraticbezierto(

波形宽度/ 4,波形高度,波形宽度/ 2,0);

}

//为了让读者更容易理解,这里画出了路径,这并不是真正必要的。

画布.绘图路径(_wavePath,_ paint);

}

此时,绘制的曲线仍处于未闭合状态,并且_wavePath的末端和末端需要连接,以便与_circlePath相交。

_wavePath.relativeLineTo(0,半径);

_波径.线至(-波宽,边);

_ wavePath.close

关闭_wavePath后,此时绘制的图表如下

v .走_circlePath和_wavePath 的交叉口

环形路径和波形路径的交点是半圆形波。

varcombine =路径.组合(病理操作.相交,_循环路径,_波形路径);

画布.绘图路径(组合,_绘制);

//为了让读者更容易理解,这里画出了路径,这并不是真正必要的。

画布.绘图路径(组合,_绘制);

六。修剪画布和绘制顶部文本

文本的颜色分为上部和下部。前景颜色的文本不需要显示上部。因此,在绘制前底色(foregroundColor)的文本时,需要将文本的上半部分剪掉,这样就可以将两次不同时间绘制的文本重叠起来,得到不同颜色范围的文本。

画布.剪辑路径(组合);

_drawText(画布:画布,侧面:侧面,颜色:前底色);

八。添加动画

现在您已经绘制了单个帧的效果图,您可以考虑移动小部件。

只要贝塞尔曲线起点的坐标不断改变,从左向右连续移动,就可以产生从左向右移动的波浪效果。

波形加载绘制器(WaveLoadingPainter)只负责根据从外部导入的动画值绘制用户界面。构造动画值的逻辑由external _ WaveLoadingWidgetState处理。这里规定,动画值的值从0增加到1,并且在开始构造_波形路径之前只需要移动起始坐标点。

@覆盖

空隙漆(帆布,尺寸大小){

双面=最小值(尺寸、宽度、尺寸、高度);

双半径=边/2.0;

_drawText(画布:画布,侧面:侧面,颜色:背景颜色);

_ circlePath.reset

_circlePath.addArc(矩形,从LTWH(0,0,边,边),0,2 * pi);

双波长宽度=边* 0.8;

双波长高度=边/6;

_ wavePath.reset

_波形路径.移动到((动画值- 1) *波形宽度,半径);

对于(double I =-WaveWidth;i <。侧面;i +=波形宽度)

_ WavePath . relativeequadraticbezierto(

波宽/ 4,-波高,波宽/ 2,0);

_ WavePath . relativeequadraticbezierto(

波形宽度/ 4,波形高度,波形宽度/ 2,0);

}

_wavePath.relativeLineTo(0,半径);

_波径.线至(-波宽,边);

_ wavePath.close

varcombine =路径.组合(病理操作.相交,_循环路径,_波形路径);

画布.绘图路径(组合,_绘制);

画布.剪辑路径(组合);

_drawText(画布:画布,侧面:侧面,颜色:前底色);

}

class _ WaveLoadingWidgetStateExtenstestate & lt;波形加载获得。

使用withSingleTickerProviderStateMixin {

最终字符串文本;

最终双字体大小;

最终颜色背景颜色;

最终颜色前景颜色;

最终颜色波形颜色;

动画控制器控制器;

动画<。双倍。动画;

_WaveLoadingWidgetState(

{ @需要此. text,

@需要这个. fontSize,

@要求背景颜色,

@要求。对于底色,

@要求这是. WaveColor });

@覆盖

无效状态

super.initState

控制器=

动画控制器(持续时间:常数持续时间(秒:1),vsync:这个);

控制器。添加状态指示器((状态){

开关(状态)

案例动画状态。解散:

打印(“驳回”);

休息;

案例动画状态。前进:

打印(“转发”);

休息;

案例动画状态。反转:

打印(“反转”);

休息;

案例动画状态。已完成:

打印(“完成”);

休息;

}

});

动画=吐温(

开始:0.0,

结束:1.0,

)。动画(控制器)

..addListener( {

set StATe(= >;{ });

});

控制器。重复;

}

@覆盖

空隙处理

控制器.处置;

super.dispose

}

@覆盖

小部件构建(构建上下文上下文){

返回自定义绘制(

油漆工:波形加载油漆工(

文本:文本,

字体大小:字体大小,

动画价值:动画。价值,

背景颜色:背景颜色,

前底色:前底色,

波色:波色,

),

);

}

}

九。软件包是StatefulWidget,并使用

之后,只需将WaveLoadingPainter包装到StateFullWidget中,并打开可以在StateFullWidget中自定义的参数。

类waveLoadingWidgetextendssTatefulWidget {

最终字符串文本;

最终双字体大小;

最终颜色背景颜色;

最终颜色前景颜色;

最终颜色波形颜色;

WaveLoadingWidget(

{ @需要此. text,

@需要这个. fontSize,

@要求背景颜色,

@要求。对于底色,

@要求此. waveColor}) {

断言(文本!=空值。& amptext . length = = 1);

断言(fontSize!=空值。& ampfontSize >。0);

}

@覆盖

_WaveLoadingWidgetState创建状态= >;_WaveLoadingWidgetState(

文本:文本,

字体大小:字体大小,

背景颜色:背景颜色,

前底色:前底色,

波色:波色,

);

}

用法类似于一般的系统小部件。

容器(

宽度:300,

身高:300,

子级:WaveLoadingWidget(

正文:“坚持不懈”,

fontSize: 215,

背景颜色:颜色。浅蓝色,

前景底色:颜色。白色,

波色:颜色。浅蓝色,

),

),

容器(

宽度:250,

身高:250,

子级:WaveLoadingWidget(

文本:“同时”,

fontSize: 175,

背景颜色:颜色。输入内容,

前景底色:颜色。白色,

波形颜色:颜色。输入内容,

),

),

源代码地址:

https://github.com/leavesC/flutter_do

https://github.com/leavesC/flutter_do

此外,该项目还提供了n个以上常用小部件和自定义小部件的使用和实现方法,涵盖系统小部件、布局容器、动画、高级功能、自定义小部件等。返回搜狐查看更多信息

负责任的编辑: