#夏日挑战赛# HarmonyOS 实现一个文字云组件 原创 精华
前言
本篇文章分享一下我实现的一个文字云组件,实现原理很简单,通过文字出现的频率,来动态生成文字大小,最后渲染即可
介绍
文字云,可以根据文字出现的频率,来展示不同的文字大小,并随机生成颜色
效果展示
使用
参数名称 | 参数描述 | 参数类型 | 默认值 |
---|---|---|---|
list | 需要展示的数据 | Array | 无 |
width | 组件宽度 | Number | 400 |
height | 组件高度 | Number | 500 |
temp | 步频 | Number | 5 |
font-max | 最大文字大小 | Number | 80 |
font-min | 最小文字大小 | Number | 25 |
解释一下:
步频
,就是文字扩大的比例。
原理分析
1.随机颜色
在效果图中我们可以看到,每个词的颜色是不一样的,这是通过随机颜色实现的
我们知道,颜色可以通过rgb获取,rgb中有三个参数rgb(xxx,xxx,xxx),通过三个参数决定颜色,所以我们可以通过随机数来生成这三个参数
参数取值范围: 0~255
getColor()
let r = Math.floor(Math.random() * 255);
let g = Math.floor(Math.random() * 255);
let b = Math.floor(Math.random() * 255);
return "rgb(" + r + "," + g + "," + b + ")";
该方法用于获取颜色,并且是通过随机数获取,最后通过字符拼接得到一个完整的
rgb(xxx,xxx,xxx)
并返回
2.文字大小
文字大小是用过temp(步频)和num(词频)两个参数控制的,num是固定的,步频的可以用户自定义。此外,为了防止词频过大,造成文字过大或者过小,影响用户体验,所以,增加最大文字和最小文字
getSize(num)
getSize (num) {
let fontSize = num * this.temp;
if(fontSize>this.fontMax) fontSize = this.fontMax
if (fontSize<this.fontMin) fontSize = this.fontMin
console.log(this.fontMin)
return fontSize +'px' ;
}
3.数据整合
通过循环,将上面获取到的文字大小、文字颜色,push到list中的每一项中,此时我们的数据就有文字对应的样式了
展示数据的时候我希望能将位置打乱,所以需要对数组随机排序,方法有很多,我是通过sort()方法来实现的
sort(a,b)为一个方法时,如果返回值<0,则a会排到b前面,返回值>0,则a会排到b后面
根据这个性质,我们只需要随机生成返回值,使它在正负数区间内即可
getList()
getList () {
this.list.forEach(item => {
let temp = item;
temp.size = this.getSize(item.num)
temp.color = this.getColor()
this.textList.push(temp)
})
// 将数组顺序打乱
this.textList.sort(() => {
return (Math.random()-0.5);
});
}
4.组件调用
组件调用这里我就不介绍了,详细使用可以看官方文档。
这里传入的参数中list的格式,必须有text(文字)和num(频率),类似这样[{text:'文本1',num:10}]
<element name='comp' src='../../common/component/wordCloud/index.hml'></element>
<div class="container">
<comp list="{{userlist}}" width="400" height="500" temp="6" font-max="100" font-min="20"></comp>
</div>
小提示:我遇到的一些小问题,
fontMax
要用-
分开,写成font-max
,不然传不过去…
完整代码
index.js
// @ts-nocheck
// comp.js
export default {
props: {
// 需要展示的数据 格式 :[{text:'文本1',num:10}]
list: {
type: Array,
default: []
},
width: {
type: Number,
default: 400
},
height: {
type: Number,
default: 500
},
// 接收步频
temp: {
type: Number,
default: 5
},
fontMax:{
type:Number,
default:80,
},
fontMin:{
type:Number,
default:25
}
},
onInit(){
this.getList()
},
data() {
return {
textList: []
};
},
//随机获取颜色
getColor () {
let r = Math.floor(Math.random() * 255);
let g = Math.floor(Math.random() * 255);
let b = Math.floor(Math.random() * 255);
return "rgb(" + r + "," + g + "," + b + ")";
},
//计算文字大小。通过(词频*步频)计算字体大小
getSize (num) {
let fontSize = num * this.temp;
if(fontSize>this.fontMax) fontSize = this.fontMax
if (fontSize<this.fontMin) fontSize = this.fontMin
console.log(this.fontMin)
return fontSize+'px' ;
},
//将用户的数据存储到容器中
getList () {
this.list.forEach(item => {
let temp = item;
temp.size = this.getSize(item.num)
temp.color = this.getColor()
this.textList.push(temp)
})
// 将数组顺序打乱
this.textList.sort(() => {
return (Math.random()-0.5);
});
}
}
index.hml
<div class="container"
style="height:{{height}}px;width:{{width}}px;">
<text class="box">
<span for="{{textList}}"
style="font-size:{{$item.size}}px;;color: {{$item.color}};">
{{ $item.name }}
</span>
</text>
</div>
index.css
.container {
border: 1px solid #ffcc00;
flex-direction: column;
justify-content: center;
align-items: center;
}
.box{
margin: 10px;
}
补充
上篇文章实现了一个进度条组件progress,但是由于考试周,没什么时间实现,如何就留下了一些拓展思路。
最后实现完给大家看看最终效果
总结📝
不足点:样式排版不是特别好,加上动画效果应该会好看点
最后,通过自定义组件,加深对HarmonyOS
的开发,共建鸿蒙生态!
很有意思的样例。
->_<-
优秀
U•ェ•*U
开发需求:文字散布成一朵云的形状
上传一张云朵的图片,并输入字符,字符会根据图片中云朵的形状随机排布。
小本本记下来了嗷U•ェ•*U