本文正在參加星光計劃3.0–夏日挑戰賽
前言
本篇文章分享一下我實作的一個文字雲元件,實作原理很簡單,通過文字出現的頻率,來動态生成文字大小,最後渲染即可
介紹
文字雲,可以根據文字出現的頻率,來展示不同的文字大小,并随機生成顔色
效果展示

使用
參數名稱 | 參數描述 | 參數類型 | 預設值 |
---|---|---|---|
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
的開發,共建鴻蒙生态!
附件連結:https://ost.51cto.com/resource/2169