在剪辑路径中生成平滑曲线:多边形

问题描述 投票:0回答:3

我有一个 div 元素,我想在其中使用剪辑路径添加内部曲线:多边形 css ...

我已经达到了基本形状,但无法平滑曲线。

HTML:

<div id="clip_element">
</div>

CSS:

#clip_element {
  background-image: -webkit-linear-gradient(bottom, #c0c0c0, #adadad, #9a9a9a, #888888, #767676);
  background-image: -o-linear-gradient(bottom, #c0c0c0, #adadad, #9a9a9a, #888888, #767676);
  background-image: linear-gradient(to top, #c0c0c0, #adadad, #9a9a9a, #888888, #767676);  
  -webkit-border-radius: 15px;
  -moz-border-radius: 15px;
  -webkit-clip-path: polygon(0% 0%,100% 0%,100% 70%,90% 80%,80% 90%,70% 100%,0% 100%);
  clip-path: polygon(0% 0%,100% 0%,100% 70%,90% 80%,80% 90%,70% 100%,0% 100%);
  }

如何使用 clip-path:polygon 使曲线平滑?

css clip-path
3个回答
3
投票

你可以通过使用伪元素

:after
来拥有它。这是使用它的答案。希望对您有所帮助。

#clip_element {
width:200px;
height:75px;
  background-image: -webkit-linear-gradient(bottom, #c0c0c0, #adadad, #9a9a9a, #888888, #767676);
  background-image: -o-linear-gradient(bottom, #c0c0c0, #adadad, #9a9a9a, #888888, #767676);
  background-image: linear-gradient(to top, #c0c0c0, #adadad, #9a9a9a, #888888, #767676);  
  -webkit-border-radius: 15px;
  -moz-border-radius: 15px;
  position:relative;  
  }
  div#clip_element:after {
    content: "";
    position: absolute;
    width: 60px;
    height: 60px;
    background: #fff;
    right: -10px;
    bottom: -30px;
    border-radius: 50%;
}
<div id="clip_element">
</div>


1
投票

或者,您可以使用 svg 剪辑路径或将 svg 转换为 css 剪辑路径。所以,多边形采用 svg 格式。

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 200.1 100.1" xml:space="preserve">
<style type="text/css">
    .smooth_polygon{fill:#ababab;}
</style>
<path class="smooth_polygon" d="M200.1,15.7v40.9c-13.8-4.5-29.5-3-42.7,5.6c-13.4,8.8-21.1,23-22.2,37.9H15.6C7,100.1,0,93.1,0,84.5V15.6  C0,7,7,0,15.6,0h168.9C193.1,0.1,200.1,7.1,200.1,15.7z"/>
</svg>

创建并导出 svg 后,您可以直接在我们的 css 样式中使用带有“clip-path”属性和值路径(“d 属性值”)的路径标记 d 属性值。下面给出的例子,

.smooth_curve_box
{
  width:210.1px;
  height: 100.1px;
  clip-path: path("M200.1,15.7v40.9c-13.8-4.5-29.5-3-42.7,5.6c-13.4,8.8-21.1,23-22.2,37.9H15.6C7,100.1,0,93.1,0,84.5V15.6  C0,7,7,0,15.6,0h168.9C193.1,0.1,200.1,7.1,200.1,15.7z");
  background-image: linear-gradient(to top, #c0c0c0, #adadad, #9a9a9a, #888888, #767676);  
}
<div class="smooth_curve_box">
</div>

但是那个被剪裁的路径没有响应,这意味着 svg 的宽度和高度只有那个宽度和高度只剪裁在元素上。上面的示例显示 svg 的宽度为 200.1px,但元素“smooth_curve_box”的宽度为 210.1px。所以,只有 200.1px 宽度的区域只被裁剪,剩下的都是空的。

如果我们想要响应式裁剪区域,那么我们需要将 svg 路径 d 属性值从绝对路径转换为相对路径。

转换后可以得到路径d属性值如“M1,0.157 v0.409 c-0.069,-0.045,-0.147,-0.03,-0.213,0.056 c-0.067,0.088,-0.105,0.23,-0.111, 0.379 H0.078 C0.035,1,0,0.93,0,0.844 V0.156 C0,0.07,0.035,0,0.078,0 h0.844 C0.965,0.001,1,0.071,1,0.157”。

但是不能直接用到css中。因此,我们需要在下面给出的 html 示例中添加一些代码。

.clip_svg
{
  position: absolute;
  pointer-events: none;
}
.smooth_curve_box_2 {
  width: 100%;
  height: 100.1px;
  background-image: linear-gradient(to top, #c0c0c0, #adadad, #9a9a9a, #888888, #767676);
  clip-path: url(#clip-path-id);
  margin-bottom: 2rem;
}

.smooth_curve_box_3 {
  width: 200.1px;
  height: 100.1px;
  background-image: linear-gradient(to top, #c0c0c0, #adadad, #9a9a9a, #888888, #767676);
  clip-path: url(#clip-path-id);
}
<svg class="clip_svg">
  <clipPath id="clip-path-id" clipPathUnits="objectBoundingBox"><path d="M1,0.157 v0.409 c-0.069,-0.045,-0.147,-0.03,-0.213,0.056 c-0.067,0.088,-0.105,0.23,-0.111,0.379 H0.078 C0.035,1,0,0.93,0,0.844 V0.156 C0,0.07,0.035,0,0.078,0 h0.844 C0.965,0.001,1,0.071,1,0.157"></path></clipPath>
</svg>

<div class="smooth_curve_box_2"></div>
<div class="smooth_curve_box_3"></div>

以上示例,第二个元素看起来不错,但第一个元素不是。这里发生了什么?因为响应式剪辑路径仅基于宽高比工作。

如果我们只想在部分区域响应,那么我们需要另一个 svg 路径到 css 剪辑路径转换器here.

这里是使用上述在线 svg 路径转换器将 svg 路径转换为 css 剪辑路径的示例,其中部分区域仅响应。

.smooth_curve_box_4
{
  width:100%;
  height: 300px;
  clip-path: polygon(calc(100% - 0px) 15.7px, calc(100% - 0px) calc(100% - 43.5px), calc(100% - 0px) calc(100% - 43.5px), calc(100% - 4.1926px) calc(100% - 44.6689px), calc(100% - 8.4727999999999px) calc(100% - 45.4712px), calc(100% - 12.8142px) calc(100% - 45.9003px), calc(100% - 17.1904px) calc(100% - 45.9496px), calc(100% - 21.575px) calc(100% - 45.6125px), calc(100% - 25.9416px) calc(100% - 44.8824px), calc(100% - 30.2638px) calc(100% - 43.7527px), calc(100% - 34.5152px) calc(100% - 42.2168px), calc(100% - 38.6694px) calc(100% - 40.2681px), calc(100% - 42.7px) calc(100% - 37.9px), calc(100% - 42.7px) calc(100% - 37.9px), calc(100% - 46.5481px) calc(100% - 35.1027px), calc(100% - 50.0488px) calc(100% - 32.0096px), calc(100% - 53.1967px) calc(100% - 28.6489px), calc(100% - 55.9864px) calc(100% - 25.0488px), calc(100% - 58.4125px) calc(100% - 21.2375px), calc(100% - 60.4696px) calc(100% - 17.2432px), calc(100% - 62.1523px) calc(100% - 13.0941px), calc(100% - 63.4552px) calc(100% - 8.8184px), calc(100% - 64.3729px) calc(100% - 4.4443px), calc(100% - 64.9px) calc(100% - 1.4210854715202E-14px), 15.6px calc(100% - 0px), 15.6px calc(100% - 0px), 13.0734px calc(100% - 0.20459999999999px), 10.6752px calc(100% - 0.79679999999998px), 8.4378px calc(100% - 1.7442px), 6.3936px calc(100% - 3.0144px), 4.575px calc(100% - 4.575px), 3.0144px calc(100% - 6.3936px), 1.7442px calc(100% - 8.4378px), 0.7968px calc(100% - 10.6752px), 0.2046px calc(100% - 13.0734px), 2.5884498452564E-31px calc(100% - 15.6px), 0px 15.6px, 0px 15.6px, 0.2046px 13.0734px, 0.7968px 10.6752px, 1.7442px 8.4378px, 3.0144px 6.3936px, 4.575px 4.575px, 6.3936px 3.0144px, 8.4378px 1.7442px, 10.6752px 0.7968px, 13.0734px 0.2046px, 15.6px 2.5884498452564E-31px, calc(100% - 15.6px) 0px, calc(100% - 15.6px) 0px, calc(100% - 13.0734px) 0.2317px, calc(100% - 10.6752px) 0.8456px, calc(100% - 8.4378px) 1.8099px, calc(100% - 6.3936px) 3.0928px, calc(100% - 4.575px) 4.6625px, calc(100% - 3.0144px) 6.4872px, calc(100% - 1.7442px) 8.5351px, calc(100% - 0.79680000000002px) 10.7744px, calc(100% - 0.2046px) 13.1733px, calc(100% - 2.8421709430404E-14px) 15.7px); 
  background-image: linear-gradient(to top, #c0c0c0, #adadad, #9a9a9a, #888888, #767676);
}
<div class="smooth_curve_box_4"></div>


0
投票

对于这个形状,我们也可以使用 svg

mask
– 使用 primitives
<rect>
<circle>
.

由于这些基元支持相对单位——我们可以创建一个流体宽度的掩码。

首先,我们需要创建一个具有响应式/流体布局的

<svg>

svg 不会在调整大小时挤压/扭曲圆角或圆圈。

body{
  background:#333;
  color:#fff;
}

*{
  box-sizing:border-box;
}

.resize{
  resize:both;
  overflow:auto;
  border: 1px solid #ccc;
  width:50%;
  padding:1em;
}
<p>Resize me</p>
<div class="resize">
  <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
      <rect x="0" y="0" rx='20' ry='20' width="100%" height="100%" fill="white" />
      <circle cx="100%" cy="100%" r="50" transform="translate(-30 0)" />
      </svg>
</div>

然后我们需要将元素转换为

<mask>
元素:

<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
    <mask id="mask">
      <rect x="0" y="0" width="100%" height="100%" fill="white" />
      <circle cx="100%" cy="100%" r="50" transform="translate(-30 0)" />
    </mask>
    <rect mask="url(#mask)" x="0" y="0" width="100%" height="100%" rx='20' ry='20' fill="white" />
  </svg>

现在我们可以将此 svg 转换为数据 URI,例如使用 Yoksel 的转换器.
与基于多边形的 css 剪辑路径相比,我们得到了一个非常紧凑的 css 规则,因为我们不需要通过很多多边形顶点来近似曲线。:

  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100%25' height='100%25'%3E%3Cmask id='mask' %3E%3Crect x='0' y='0' width='100%25' height='100%25' fill='white'/%3E%3Ccircle cx='100%25' cy='100%25' r='50' transform='translate(-30 0)' /%3E%3C/mask%3E%3Crect mask='url(%23mask)' x='0' y='0' width='100%25' height='100%25' rx='20' ry='20' fill='white'/%3E%3C/svg%3E");

示例:作为数据 URI 的 svg 掩码

body {
  background: #333;
  color: #fff;
}

* {
  box-sizing: border-box;
}

.resize {
  resize: both;
  overflow: auto;
  border: 1px solid #ccc;
  width: 50%;
  padding: 1em;
}

svg {
  display: block;
}

.clip_element {
  display: block;
  width: 100%;
  height: 10em;
  min-height: 100%;
  background-image: linear-gradient(to top, #c0c0c0, #adadad, #9a9a9a, #888888, #767676);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100%25' height='100%25'%3E%3Cmask id='mask' %3E%3Crect x='0' y='0' width='100%25' height='100%25' fill='white'/%3E%3Ccircle cx='100%25' cy='100%25' r='50' transform='translate(-30 0)' /%3E%3C/mask%3E%3Crect mask='url(%23mask)' x='0' y='0' width='100%25' height='100%25' rx='20' ry='20' fill='white'/%3E%3C/svg%3E");
  -webkit-mask-size: 100%;
  mask-type: luminance;
  margin-bottom: 1em;
}

.w200x150 {
  width: 200px;
  height: 150px;
}

.w500x100 {
  width: 500px;
  height: 100px;
}
<p>Mask svg</p>
<div style="width:1000px">
  <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
    <mask id="mask">
      <rect x="0" y="0" width="100%" height="100%" fill="white" />
      <circle cx="100%" cy="100%" r="50" transform="translate(-30 0)" />
    </mask>
    <rect mask="url(#mask)" x="0" y="0" width="100%" height="100%" rx='20' ry='20' fill="white" />
  </svg>
</div>

<p>Mask applied by data-uri</p>

<div class="resize">
  <div class="clip_element">
  </div>
</div>

<div class="clip_element w200x150">
</div>

<div class="clip_element w500x100">
</div>

© www.soinside.com 2019 - 2024. All rights reserved.