乐趣区

关于前端:Shapes布局文字环绕动画

阐明

Shapes也有形态、图形的意思,咱们能够在页面中创立图形,并让内容盘绕在定义的图形边上。
Shapes 的官网文档:https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Shapes/From_box_values

咱们常常在一些宣传手册上看到文字盘绕图形的海报成果,这种海报成果通过 css 也能够实现,shapes布局能够实现不规则的图文盘绕成果。

留神:它须要和 float 属性配合应用。


实现以及语法

咱们先来实现一个文字盘绕图形的成果:

    <div class="container">
        <div class="shape"></div>
        <p>
        这是一行文字这是一行文字这是一行文字这是一行文字这是一行文字这是一行文字这是一行文字
        这是一行文字这是一行文字这是一行文字这是一行文字这是一行文字这是一行文字这是一行文字
        这是一行文字这是一行文字这是一行文字这是一行文字这是一行文字这是一行文字这是一行文字
        这是一行文字
        </p>
    </div>
.container{
   width: 400px;
   height: 200px;
   border: 1px solid red;
   .shape{
    width: 100px;
    height: 100px;
    border: 1px solid gold;
    background: #ccc;
    float: left;  /* shape 必须配合 float */
    shape-outside: border-box; /* 围绕 box 边框盘绕 */
   }
}

上图就是一个根本的文字盘绕成果,float 是必须的 ,它定义了元素浮动的地位,shape-outside: border-box; 示意内容以盒子的边框为基准盘绕。

这里是左浮动,所以盒子定位在右边,文字围绕右边的盒子排列。如果 float:right; 那么文字会围绕左边的盒子盘绕。

下面的 shape-outside: border-box; 是其中一个盘绕模式,shape-outside有多种盘绕模式,如下:

属性 阐明
shape-box 依据浮动元素的边缘(通过 CSS box model 来定义)形态计算出浮动的区域。
margin-box 以浮动元素的外边距边界进行围绕
border-box 以浮动元素的边框为基准盘绕
padding-box 从浮动元素的 padding 地位开始盘绕
content-box 从浮动元素的 content 地位开始盘绕

margin-box

margin: 10px;
shape-outside: margin-box; /* 以 margin 的范畴开始 */

content-box

    border: 10px solid red;
    padding: 10px;
    shape-outside: content-box; /* 以元素的理论大小为终点,去掉 border、margin */

此外还能够定义不规则的图形,让文字盘绕这些不规则的图形。这里咱们用 ellipse() 定义一个椭圆,让文字盘绕椭圆

.shape{
    width: 100px;
    height: 100px;
    background: #ccc;
    float: right;
    clip-path: ellipse(50px 20px at 50% 50%); /* 裁切图形 */
    shape-outside: ellipse(50px 20px at 50% 50%); /* 盘绕的理论图形 */
}

这里须要明确一点,clip-path裁切不是必须的(这里只是为了显示形态而已),真正的 shapes 布局是依据 shape-outside 而来,shape-outsid才是理论盘绕的图形,如下:

.shape{
    width: 100px;
    height: 100px;
    background: #ccc;
    float: right;
    /* clip-path: ellipse(50px 20px at 50% 50%);  */
    shape-outside: ellipse(50px 20px at 50% 50%); /* 盘绕的理论图形 */
}

对于形态裁切的几个属性:

属性 阐明
circle() 定义一个圆形,语法:circle(x 轴(大小)at x 轴坐标 y 轴坐标); at 后为剪切的地位,第一个参数左右,第二个参数高低
ellipse() 定义一个椭圆(应用两个半径和一个圆心地位)。语法:ellipse(x 轴偏移 y 轴偏移 at x 轴坐标 y 轴坐标)
inset() 四个参数,上右下左,定义一个 inset 矩形。
polygon() 定义一个多边形(应用一个 SVG 填充规定和一组顶点)。四个参数,上右下左,每个地位的第一个参数代表左右偏移,第二个参数代表高低偏移
path() 定义一个任意形态(应用一个可选的 SVG 填充规定和一个 SVG 门路定义)。

裁切的具体用法能够去 mdn 上查问


动画

Shapes布局能够配合动画应用,动静的更改裁切的形态实现文字的动静变换:

<div class="container2">
     <div class="variant"></div>   <!-- 左侧的形态 -->
      <div class="variant2"></div>  <!-- 右侧的形态 -->
      <p>
        这是一行文字这是一行文字这是一行文字这是一行文字
        这是一行文字这是一行文字这是一行文字这是一行文字
        这是一行文字这是一行文字这是一行文字这是一行文字
        这是一行文字这是一行文字这是一行文字这是一行文字
        这是一行文字这是一行文字这是一行文字这是一行文字
        这是一行文字这是一行文字
      </p>
</div>
.container2{
    width: 400px;
    height: 200px;
    border: 1px solid green;
    .variant{
        width: 200px;
        height: 200px;
        background: #ccc;
        clip-path: polygon(0 0, 0% 100%, 40% 50%); /* 形态裁切 */
        float: left;  /* 左浮动 */
        shape-outside: polygon(0 0, 0% 100%, 40% 50%);  /* 理论盘绕的形态 */
        animation: square 5s infinite linear;
    }
    
    .variant2{
        width: 200px;
        height: 200px;
        background: #ccc;
        clip-path: polygon(100% 0, 100% 100%, 60% 50%); /* 形态裁切 */
        float: right; /* 右浮动 */
        shape-outside: polygon(100% 0, 100% 100%, 60% 50%); /* 理论盘绕的形态 */
        animation: square2 5s infinite linear;
    }
    >p{text-align: center;}

     /* 利用动画,动静更改裁切的形态 */
    @keyframes square {
        0%,100%{clip-path: polygon(0 0, 0% 100%, 40% 50%);
            shape-outside: polygon(0 0, 0% 100%, 40% 50%);
        }
       25%{clip-path: polygon(0 0, 0% 100%, 40% 25%);
            shape-outside: polygon(0 0, 0% 100%, 40% 25%);
       }
       75%{clip-path: polygon(0 0, 0% 100%, 40% 75%);
            shape-outside: polygon(0 0, 0% 100%, 40% 75%);
       }

    }
    @keyframes square2 {
        0%,100%{clip-path: polygon(100% 0, 100% 100%, 60% 50%);
            shape-outside: polygon(100% 0, 100% 100%, 60% 50%);
        }
       25%{clip-path: polygon(100% 0, 100% 100%, 60% 25%);
            shape-outside: polygon(100% 0, 100% 100%, 60% 25%);
       }
       75%{clip-path: polygon(100% 0, 100% 100%, 60% 75%);
            shape-outside: polygon(100% 0, 100% 100%, 60% 75%);
       }
    }
}

突变裁切

Shapes布局是能够应用突变的,如果突变的色彩齐全通明就相当于不占位,那么 shape 就会占据并围绕通明的地位:

<div class="container3">
     <div class="pngs"></div>
     <p>
     这是一行文字这是一行文字这是一行文字这是一行文字
     这是一行文字这是一行文字这是一行文字这是一行文字
     这是一行文字这是一行文字这是一行文字这是一行文字
     这是一行文字这是一行文字这是一行文字这是一行文字
     这是一行文字这是一行文字
     </p>
</div>
.container3{
    width: 400px;
    height: 200px;
    border: 1px solid gold;
    margin: 30px;
    .pngs{
        width: 200px;
        height: 200px;
        float: left;
        /* 如果突变的透明度为齐全通明,那么 shape 就会占据并围绕通明的地位 */
        /* 建设一个变量 */
        --gradient : linear-gradient(to right bottom , #80c342 40% , transparent 50% , transparent 70%  , #4d90fe 80%);
        shape-outside: var(--gradient);
        background: var(--gradient);
        animation: gradients 5s infinite linear;
    }
    /* 动静更改突变的色彩占比 */
    @keyframes gradients {
        0%,100%{--gradient : linear-gradient(to right bottom , #80c342 40% , transparent 50% , transparent 70%  , #4d90fe 80%);
        }
        25%{--gradient : linear-gradient(to right bottom , #80c342 20% , transparent 30% , transparent 60%  , #4d90fe 70%);
        }
        75%{--gradient : linear-gradient(to right bottom , #80c342 60% , transparent 70% , transparent 80%  , #4d90fe 90%);
        }
    }
}

图形变换的动画成果

成果如下:

利用动画动静更改裁切元素的图形,文字依据裁切形态动静的进行排版变动

<div class="container">
     <div class="left"></div>
     <div class="right"></div>
     <p>
     这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。</p>
</div>
.container{
    width: 500px;
    height: 254px;
    border: 1px solid red;
    background: black;
    overflow: hidden;
    margin: 20px;
    padding-top: 40px; /* 设置头部内距,留出文字间隙 */
    >p{
        color: #fff;
        margin-top: -40px; /* 与父级 padding 数值相等,对消 padding */
    }
    .left{
        width: 200px;
        height: 200px;
        /* margin-top: 60px; */ /* 如果应用裁切动画则不能设置 margin,这个 margin 是给元素展现的本体用的,并不是给 shape-outside 裁切的形图形用的 */
        float: left;
        background: #ccc;
        animation: variants 4s infinite linear;
        background: linear-gradient(to right , #4ac6ff , #bd34fe);
    }
    .right{
        width: 200px;
        height: 200px;
        // margin-top: 60px;  
        float: right;
        background: #ccc;
        animation: variants 4s infinite linear;
        background: linear-gradient(to left , #4ac6ff , #bd34fe);
    }
    @keyframes variants {
        0%,5%,95%,100%{
            /* polygon 的参数数量必须统一,否则动画会生效 */
            clip-path: polygon(50% 0%, 62% 38%, 100% 50%, 62% 56%, 50% 100%, 37% 56%, 0 50%, 38% 38%);
            shape-outside: polygon(50% 0%, 62% 38%, 100% 50%, 62% 56%, 50% 100%, 37% 56%, 0 50%, 38% 38%);
        }
        45%{clip-path: polygon(50% 30%, 100% 0, 70% 50%, 100% 100%, 50% 70%, 0 100%, 30% 50%, 0 0);
            shape-outside: polygon(50% 30%, 100% 0, 70% 50%, 100% 100%, 50% 70%, 0 100%, 30% 50%, 0 0);
        }
        55%{clip-path: polygon(50% 30%, 100% 0, 70% 50%, 100% 100%, 50% 70%, 0 100%, 30% 50%, 0 0);
            shape-outside: polygon(50% 30%, 100% 0, 70% 50%, 100% 100%, 50% 70%, 0 100%, 30% 50%, 0 0);
        }
    }
}

这里有几个须要留神的中央:
1、给元素增加 shape-outside 后不能应用margin,因为margin 是给元素展现的本体应用的,并不是给 shape-outside 裁切的形图形用的,否者会呈现下图的成果:

2、动画中 shape-outsidepolygon的参数和 clip-path 的参数须要统一,否则动画无奈对应页面成果

3、因为 shape-outside 不能应用 margin,如果咱们想要挪动裁切的地位,为下面留两行文字的空间,给父级增加padding 即可,父级的内容应用 -margin 对消 padding 即可。


案例源码:https://gitee.com/wang_fan_w/css-diary

如果感觉这篇文章对你有帮忙,欢送点赞👍、珍藏💖、转发✨哦~

退出移动版