The weather is too hot, I hope this small fan can bring you a little coolness

The temperature has been changing recently, and it has returned to the high temperature weather of more than 30 degrees in the past few days. In such weather, if the office does not have an air conditioner or electric fan, it is difficult to concentrate on work. The air conditioner may be used every day. There are fans in the office, but the fan is probably prepared by yourself. If you haven’t had time to prepare it, you can first consider drawing a fan on the desktop and watching it blow. After all, the ancients hoped that plums would quench their thirst. Let’s draw a fan to cool down today.

source address

github.com/coffeetang/…

Preparation

First consider the structure of the fan. Our fan consists of several parts, namely the base, the column, the fan frame, and the fan blades. Up and down structure, the base is at the bottom, the others are on top, except the base, the rest are drawn in one Canvas, the general structure is as follows

image.png

fan blade

The blades of a fan can actually be seen as drawing a fan shape on the canvas, and we need to use a function to draw a fan shape drawArc. The parameter list of this function is as follows

image.png

We are all familiar with the parameters. The parameters needed to draw the sector here are

  • brush: Used to set the gradient color
  • startAngle: Indicates the starting angle
  • sweepAngle: Indicates the sector angle
  • userCenter: Indicates whether the two ends of the sector are connected to the center of the circle
  • topLeft: Indicates the coordinates of the upper left corner of the fan-shaped range
  • size: Indicates the drawing range of the sector
  • style: The default value is filled by Fill, so we don't have to worry about it

According to the parameters, we need to create several variables, the first is the coordinates of the center of the circle, which is the center coordinates taken Canvas, so no matter how large or small the window is, our center coordinates will be at the center of the entire canvas

image.png

The second is our radius, the size of the radius determines the size of the entire fan-shaped drawing range

image.png

Then our code to draw a fan is as follows

image.png image.png

A fan shape is drawn in this way, and a fan has a total of three blades. We want to draw three fan shapes, and they are equally divided on the circumference. How should we draw it? Using this method here, first create an array, which contains the gradient color to be used for each sector

image.png

Then create an array, which contains each sectorstartAngle

image.png

Then first of all, we can draw all six sectors by traversing the array

image.png image.png

我们看到这个时候界面上展示的就是一个由六个扇形组成的大圆形,然后我们把colorList里面每隔一组颜色就把颜色改成透明的,那么这个圆形就看起来就像是三个被等分的出来的扇形一样了

image.png image.png

扇框与立柱

扇叶已经完成了,接下来就是绘制扇框与立柱的工作,这两个都比较容易,立柱就是从圆心位置向下绘制出一条直线

image.png image.png

然后我们在扇形靠外一点的位置绘制一个圆形作为扇框的边框,这里用到了drawPath函数,drawPath的第一个参数是Path,所以我们先将Path做出来

image.png

然后再调用drawPath函数,将framePath传进去

image.png image.png

然后就是风扇前面的网罩,网罩常见的有从中心向外延伸出去的一条条直线,也有的就是一个个井字格组成起来的样子,这边按照前者做个网罩样式出来,这种样式与扇叶的思想有点接近,都是按照角度在一个圆周上等分的绘制样式,所以我们首先需要确定好这些角度,也有一个list维护起来

image.png

这里就是有45根线,每过8度画一根,而我们知道绘制线条用到的函数drawLine需要知道一个start坐标和一个end坐标,start都知道是圆形坐标,而end的xy坐标就要根据角度与半径算出来了,计算的代码如下所示

image.png

第一个参数就是网罩的半径长度,第二个参数为圆形x坐标或者y坐标,第三个参数是角度,那么我们就可以使用这两个函数,遍历lineAngleList来绘制出网罩

image.png image.png

绘制风扇部分就完成了,下面开始开发底座上的开关

总开关与强度开关

底座上的开关分两个区域,左边是调节强度的区域,右边是总开关区域,总开关设计成一个滑块的样式,滑块默认在左边为关闭状态,点击或者拖动滑块,滑块滑动到右边,状态变成开启,滑块高亮,首先建立一个变量用来记录当前开关状态,再定义两个常量分别代表关闭与打开

image.png

默认为关闭状态,滑块的实现我们需要用到swipeable操作符,参数列表如下

image.png

其中我们需要用到的参数有

  • state:滑块的状态,需要监听滑块的状态来更新开关的状态值
  • anchors:锚点,某个位置对应滑块的一个状态值
  • thresholds:阈值,判读一个鼠标拖动事件滑动到某个位置的时候,这个位置属于哪种状态,那么当鼠标停止拖动时候,滑动可以animate到对应状态位置
  • orientation:拖动方向

根据需要的参数我们来创建对应的变量,滑块的代码如下所示

image.png image.png

这里滑块的背景颜色会根据开关状态来变化,而开关的状态我们就通过监听swipeState来更新

image.png 0606aa1.gif

我们拖动滑块改变开关状态的功能如上图所示完成了,而点击滑块边上区域来改变开关状态就需要在滑块父布局上添加点击事件,点击一次更新滑块状态,而更新操作需要用到SwipeableState里面的animateTo函数,这个函数是个挂起函数,所以还需要给它提供一个协程作用域,恰好我们更新滑块状态是根据点击来触发的,所以这里选择使用LaunchedEffect函数

image.png 0606aa2.gif

滑块部分就做完了,然后是左边区域的调节强度功能,这个区域准备由三个色块组成,每个色块都可以点击,每点击一个色块,强度设置成对应级别,符合该级别的色块颜色高亮,否则就变暗,所以这里也需要一个表示强度的变量值

image.png

然后添加上三个色块以及每个色块的逻辑代码和点击事件

image.png 0606aa3.gif

这里每个色块高亮的条件都不一样,但是有个共同条件就是必须是开关状态开启的情况下才能高亮,如果关闭的话,所有色块都会变暗,另外fanState对应的值有1000,600,200的原因我们接下去会说,这个跟风扇的转速有关

让风扇转起来

From the point of view of the code, let the fan rotate at a different position every time the fan is drawn. From the parameters drawArcin the function we draw the fan, if we want to change the position of the fan, it is the changed startAnglevalue, which is its value. The initial value plus a value that changes at any time, the range of this change is 0f ~ 360f, then for the process of this cyclic change, we must first think of using cyclic animation

image.png

Here we can see that fanStatethe value of is actually the time for looping the animation. fanStateThe smaller the value of the value is, the faster the rotation speed is. In addition, the initial value and target value of the animation are also added with the fanStatevalue of fanState. Let the Composable function animateFloattrigger the reorganization, so that a new InfiniteRepeatableSpec object can be regenerated, and the speed can be changed. Otherwise, animateFloatthe three parameters will not change and there will be no reorganization, and wheelStatethe original value is still the same wheelState. After getting the value of It is added to the drawArc function startAngleinside

image.png

There is also a judgment added here. When the switch is on, the change value drawArcis startAngleadded wheelState. When it is off, this value is not added, that is, the fan is in a static state. Let's take a look at the effect

0606aa5.gif

Summarize

Our fan is also finished, and the knowledge points used are commonly used in Compose development, such as loop animation, Canvas drawing, and gesture operations, so simply draw a fan on the computer screen. I know if you can feel a cool breeze after reading this article~

おすすめ

転載: juejin.im/post/7244337505494401085
おすすめ