• 关于使用svg构建六边形蜂巢列表的方式


    由于项目需求,需要在页面中画出一套蜂巢排版格式的列表。在经过网上的一番查阅资料,发现大多六边形的画法都是通过div覆盖由旋转的菱形遮掩为六边形。这种六边形虽然可以满足一些基本的需求,但我暂时没有想到如何满足我想要的边框动态效果。最后寻觅下发现了一款适合的样式,在此基础上做出样式方面的改动,变为符合我需求的蜂巢列表。作为一个前端新手,内容如有错误请多指正,谢谢大家。

    参考地址:https://wow.techbrood.com/fiddle/13533

    这里主要是通过 svg 的 <path> 标签去绘制边框路径,然后使用 <text> 插入单行文本,使用 <foreignObject> 插入可换行文本。

    1.通过svg的x y width height四个参数构建svg实际占据的面积和位置。比如

    <svg x="0" y="0" height="100%" width="100%">

    就是占据了外层 <li> 的全部面积,这样做的好处是可以后续通过控制 <li> 的大小来直接控制svg的整体大小,也可以写具体的px来定位位置。

    2.通过svg的viewBox属性来设置内部的具体尺寸比例。比如

      <li class="hex">
        <svg x="0" y="0" viewBox="0 0 208 240" height="100%" width="100%">
          <path class="path" d="M 104,1 205,60 205,180 104,237 3,180 3,60 Z" />
          <text class="time" x='104' y='60' style='dominant-baseline:middle;text-anchor:middle;'>
            10h
          </text>
          <foreignObject x='4' y='80' width="200" height="85">
              <p class="title">abc-activiti-server</p>
          </foreignObject>
          <text class="num" x='104' y='180' style='dominant-baseline:middle;text-anchor:middle;'>
            1个实例
          </text>
        </svg>
      </li>

    这里的viewBox=“0 0 208 240”说白了其实就是从svg的最左上(0,0)坐标的位置到最右下(208,240)坐标的,内部横向划分207次纵向划分239次的一个网格状区域。这样当我们想要将svg的任意子组件设置位置时,只需要给与指定的x y 即可。同时 <path> 的d属性也是通过这个网格区域来定位描点位置的。

    3.通过 <path> 的d属性来进行边框描绘。d属性的写法有多种,不必纠结于某种写法,能实现即可。比如本次实现我使用的是 d="M 104,1 205,60 205,180 104,237 3,180 3,60 Z" 即M代表开始,每一个x,y代表一个点,默认是直线连接,最后Z结尾,会自动形成闭环路径。

    4.通过 <text> 写一些简短的问题,其中行内样式 dominant-baseline 设置文本垂直居中, text-anchor 设置文本水平居中。过长的文本不会换行,所以要使用下面这个标签。

    5.通过 <foreignObject> 嵌入XHTML元素,用以防止较长的文本内容,对标签设置了宽高后,内部元素可进行换行。

    html代码部分

    <ul>
      <li class="hex">
        <svg x="0" y="0" viewBox="0 0 208 240" height="100%" width="100%">
          <path class="path" d="M 104,1 205,60 205,180 104,237 3,180 3,60 Z" />
          <text class="time" x='104' y='60' style='dominant-baseline:middle;text-anchor:middle;'>
            10h
          </text>
          <foreignObject x='4' y='80' width="200" height="85">
              <p class="title">abc-activiti-server</p>
          </foreignObject>
          <text class="num" x='104' y='180' style='dominant-baseline:middle;text-anchor:middle;'>
            1个实例
          </text>
        </svg>
      </li>
      <li class="hex">
        <svg x="0" y="0" viewBox="0 0 208 240" height="100%" width="100%">
            <path class="path" d="M 104,1 205,60 205,180 104,237 3,180 3,60 Z" />
        </svg>
      </li>
      <li class="hex">
        <svg class="red" x="0" y="0" viewBox="0 0 208 240" height="100%" width="100%">
            <path class="path" d="M 104,1 205,60 205,180 104,237 3,180 3,60 Z" />
        </svg>
      </li>
      <li class="hex">
        <svg x="0" y="0" viewBox="0 0 208 240" height="100%" width="100%">
            <path class="path" d="M 104,1 205,60 205,180 104,237 3,180 3,60 Z" />
        </svg>
      </li>
      <li class="hex">
        <svg x="0" y="0" viewBox="0 0 208 240" height="100%" width="100%">
            <path class="path" d="M 104,1 205,60 205,180 104,237 3,180 3,60 Z" />
        </svg>
      </li>
      <li class="hex">
        <svg x="0" y="0" viewBox="0 0 208 240" height="100%" width="100%">
            <path class="path" d="M 104,1 205,60 205,180 104,237 3,180 3,60 Z" />
        </svg>
      </li>
      <li class="hex">
        <svg x="0" y="0" viewBox="0 0 208 240" height="100%" width="100%">
            <path class="path" d="M 104,1 205,60 205,180 104,237 3,180 3,60 Z" />
        </svg>
      </li>
      <li class="hex">
        <svg x="0" y="0" viewBox="0 0 208 240" height="100%" width="100%">
            <path class="path" d="M 104,1 205,60 205,180 104,237 3,180 3,60 Z" />
        </svg>
      </li>
      <li class="hex">
        <svg class="yellow" x="0" y="0" viewBox="0 0 208 240" height="100%" width="100%">
            <path class="path" d="M 104,1 205,60 205,180 104,237 3,180 3,60 Z" />
        </svg>
      </li>
      <li class="hex">
        <svg x="0" y="0" viewBox="0 0 208 240" height="100%" width="100%">
            <path class="path" d="M 104,1 205,60 205,180 104,237 3,180 3,60 Z" />
        </svg>
      </li>
    <ul>
    View Code

    然后就是css部分,里面用到的不常见样式的具体用法做了简单的文字描述,不太明白的可以尝试百度一下,大多都有专门的图文描述,这里就不再做赘述了

        ul,p {
          margin: 0;
          padding: 0;
        }
        ul {
          list-style: none;
          border: 1px solid #333333;
          overflow: hidden;
        }
        li.hex {
          float: left;
          font-size: 20px;
        }
        svg {
          width: 100%;
    
          color: #3bc292;
        }
        svg path {
          fill: transparent; /* 内部透明填充色 */
          stroke: #3bc292; /* 边框色 */
          stroke-width: 6; /* 边框宽度 */
          stroke-linecap: round; /* 描边端点表现形式 */
          stroke-linejoin: round; /* 描边转角的表现方式 */
          stroke-miterlimit: 4;
          stroke-dasharray: 20; /* 创建虚线,20px实线,20px虚线重复 */
          animation: dash 5s linear infinite; /* 动画名 每次速度 匀速 无限次 */
    
          transition: 0.3s;
          -moz-transition: 0.3s;    /* Firefox 4 */
          -webkit-transition: 0.3s;    /* Safari 和 Chrome */
          -o-transition: 0.3s;    /* Opera */
        }
        svg text {
          fill: #3bc292; /* 文本填充色 */
    
          transition: 0.3s;
          -moz-transition: 0.3s;    /* Firefox 4 */
          -webkit-transition: 0.3s;    /* Safari 和 Chrome */
          -o-transition: 0.3s;    /* Opera */
        }
        svg text.time {
          font-size: 0.8em;
        }
        svg p.title {
          text-align: center;
          font-size: 1.5em;
    
          transition: 0.3s;
          -moz-transition: 0.3s;    /* Firefox 4 */
          -webkit-transition: 0.3s;    /* Safari 和 Chrome */
          -o-transition: 0.3s;    /* Opera */
        }
        svg text.num {
          font-size: 0.8em;
        }
        svg:hover path {
          stroke: #3bc292;
          fill: #69c2a3;
        }
        svg:hover text, svg:hover p.title {
          fill: #ffffff;
          color: #ffffff;
        }
        svg.red path {
          stroke: #f56f6f;
          animation-play-state: paused;
        }
        svg.red:hover path {
          fill: #f56f6f;
        }
        svg.yellow path {
          stroke: #f5b140;
          animation-play-state: paused;
        }
        svg.yellow:hover path {
          fill: #f5b140;
        }
        @keyframes dash {
          to {
            stroke-dashoffset: 120; /* 虚线在原路径下的偏移量 */
          }
        }
    
        /*** SPACING AND SIZING *****************************************************************/
        @media (min- 1401px) {
          .hex {
            width: 12.5%;
            margin: 0 0.5%;
          }
          .hex:nth-child(13n+1) {
            margin-left: 2.5%;
          }
          .hex:nth-child(13n+8),.hex:nth-child(13n+9),.hex:nth-child(13n+10),.hex:nth-child(13n+11),.hex:nth-child(13n+12),.hex:nth-child(13n+13) {
            margin-top: -3%;
            margin-bottom: -3%;
          }
          .hex:nth-child(13n+8) {
            margin-left: 9.25%;
          }
        }
    
        @media (max- 1400px) and (min- 1201px){
          .hex {
            width: 15%;
            margin: 0 0.5%;
          }
          .hex:nth-child(11n+1) {
            margin-left: 2.5%;
          }
          .hex:nth-child(11n+7),.hex:nth-child(11n+8),.hex:nth-child(11n+9),.hex:nth-child(11n+10),.hex:nth-child(11n+11) {
            margin-top: -3.6%;
            margin-bottom: -3.6%;
          }
          .hex:nth-child(11n+7) {
            margin-left: 10.5%;
          }
        }
    
        @media (max- 1200px) and (min- 901px){
          .hex {
            width: 19%;
            margin: 0 0.3%;
          }
          .hex:nth-child(9n+1) {
            margin-left: 1%;
          }
          .hex:nth-child(9n+6),.hex:nth-child(9n+7),.hex:nth-child(9n+8),.hex:nth-child(9n+9) {
            margin-top: -4.6%;
            margin-bottom: -4.6%;
          }
          .hex:nth-child(9n+6) {
            margin-left: 10.5%;
          }
        }
    
        @media (max- 900px) and (min- 601px) {
          .hex {
            width: 24%;
            margin: 0 0.3%;
          }
          .hex:nth-child(7n+1) {
            margin-left: 0.8%;
          }
          .hex:nth-child(7n+5),.hex:nth-child(7n+6),.hex:nth-child(7n+7) {
            margin-top: -6%;
            margin-bottom: -6%;
          }
          .hex:nth-child(7n+5) {
            margin-left: 13.1%;
          }
        }
    
        @media (max- 600px) {
          .hex {
            width: 30%;
            margin: 0 1%;
          }
          .hex:nth-child(5n+1) {
            margin-left: 3%;
          }
          .hex:nth-child(5n+4),.hex:nth-child(5n+5) {
            margin-top: -6.5%;
            margin-bottom: -6.5%;
          }
          .hex:nth-child(5n+4) {
            margin-left: 19%;
          }
        }
    View Code
  • 相关阅读:
    合并报表优化记录
    如何在后台代码中执行原生sql?
    eclipse从数据库逆向生成Hibernate实体类
    用Eclipse进行远程Debug代码
    hibernate自动生成数据库表
    hibernate自动生成数据库表
    php通过UNIX源码编译安装
    php设置方法
    php其他配制选项
    终于做出了目录认证!
  • 原文地址:https://www.cnblogs.com/chenshuipeng/p/svg-path.html
Copyright © 2020-2023  润新知