#夏日挑战赛# HarmonyOS 实现一个文字云组件 原创 精华

lxj29
发布于 2022-7-8 22:27
浏览
1收藏

本文正在参加星光计划3.0–夏日挑战赛

前言

本篇文章分享一下我实现的一个文字云组件,实现原理很简单,通过文字出现的频率,来动态生成文字大小,最后渲染即可

介绍

文字云,可以根据文字出现的频率,来展示不同的文字大小,并随机生成颜色

效果展示

#夏日挑战赛# 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 实现一个文字云组件-鸿蒙开发者社区

总结📝

不足点:样式排版不是特别好,加上动画效果应该会好看点

最后,通过自定义组件,加深对HarmonyOS的开发,共建鸿蒙生态!

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
wordCloud.zip 1.3K 16次下载
已于2022-7-29 19:34:14修改
10
收藏 1
回复
举报
5条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

很有意思的样例。

1
回复
2022-7-11 10:14:59
lxj29
lxj29 回复了 红叶亦知秋
很有意思的样例。

->_<-

回复
2022-7-15 14:41:29
阿毛0920
阿毛0920

优秀

 

回复
2022-7-20 18:03:19
Whyalone
Whyalone

U•ェ•*U

 

开发需求:文字散布成一朵云的形状

上传一张云朵的图片,并输入字符,字符会根据图片中云朵的形状随机排布。

 

 

回复
2022-7-21 18:44:50
lxj29
lxj29 回复了 Whyalone
U•ェ•*U 开发需求:文字散布成一朵云的形状 上传一张云朵的图片,并输入字符,字符会根据图片中云朵的形状随机排布。

小本本记下来了嗷U•ェ•*U

回复
2022-7-23 00:03:40
回复
    相关推荐