阅读 1807

用CSS造出詞云效果

前段时间,接到一个需求要做一个充满随机词云的区域,而且词云要互相不重叠,效果如下图:

word-cloud

我刚开始打算先把词云做出来,然后用js算每一个的位置,但实在太难和太麻烦,一方面要用js去随机生成每一个云的位置,另一方面还要考虑生成的位置不发生重叠。后来转个思路去想,不用js,只用css可以吗?最后想到用flex做布局,然后利用js随机生成位置偏移,为了不发生重叠,给每个词云相应的间距就可以了。

现在开始把效果实现吧。

单个词云的实现

在去实现一堆随机词云前,先看下怎样实现单个词云。

首先先把元素写好:

<div class="word-cloud">
  Hello World
</div>
复制代码

然后是css:

.word-cloud {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius: 96px;
  width: 200px;
  height: 100px;
  color: #01FFFC;
  box-shadow: 0 0 20px 7px #01FFFC inset;
}
复制代码

效果如下:

one-cloud

codepen在綫演示

词云实现是没有什么难度的,重点是 box-shadow,利用inset,使阴影向内,把前两个参数设成0, 就可以使阴影向四周扩散。关于box-shadow的更多实现,可以看:

你所不知道的 CSS 阴影技巧与细节

词云布局

(为了方便,这里我用vue来实现,其实用原生js也可以实现)

接下来去做一堆词云吧。先把布局做好:

body {
    padding: 0 0;
    margin: 0 0;
    background-color: rgba(0, 0, 0, 1);
}

#app {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  padding: 30px;
  width: 100%;
  height: 800px;
}
复制代码

先把背景色设为黑色,然后做一个flex布局。

定义一些随机词云数据:

  data() {
    return {
      cloudTexts: [
        'hello',
        'world',
        'monday',
        'tuesday',
        'sanday',
        'foo',
        'bar',
        'cheers',
        'cloud',
        'text',
        'taste',
        'dog',
        'rose',
        'boy',
        'girl',
        'egg'
      ]
    }
  }
复制代码

实现一个方法来生成词云的样式:

    genStyles() {
     // 设定颜色
     const colors = [['#01FFFC', '#01FFFC'], ['#01FF84', '#01FF84'], ['#5843D7', '#E2DDFF'], ['#FD374E', '#FD374E']]
    const colorIndex = Math.floor(Math.random() * 4)
    // 设定随机位置
    const top = Math.floor((Math.random() * 140) - 70)
    const left = Math.floor((Math.random() * 160) - 80)
    
    // 给予间隔,防止折迭
    const margin = `${Math.abs(top) + 4}px ${Math.abs(left) + 4}px`
      
      return {
        position: 'relative',
        top,
        left,
        display: 'flex',
        'justify-content': 'center',
        'align-items': 'center',
        'border-radius': '96px',
        width: '150px',
        height: '70px',
        margin,
        color: colors[colorIndex][1],
        'box-shadow': `0 0 20px 7px ${colors[colorIndex][0]} inset`
      }
    }
复制代码

生成随机数后再相减,使偏移值可以是正或负,然后为了不让词云互相重叠,给每个词云与偏移值相等的间距,保証它们互相不重叠。

最后效果可以看演示:

codepen在綫演示

文章分类
前端
文章标签