复杂的设计模式 - 重叠的透明形状?

时间:2018-03-31 12:03:23

标签: html css css3 css-shapes

我试图创建以下形状。

Pattern

我几乎尝试通过以下方式创建此图像。为了使用HTML和CSS创建此图像。我试着使用以下代码。



.left1{
  float:left;
  transform: rotate(180deg);
}
.halfCircleRight1{
   height: 70px;
   width: 70px;
   border-top-right-radius: 10em;
   border-bottom-right-radius: 10em;
   background: #326d7d;       
}

.halfCoverTop1 {
   height: 35px;
   width: 35px;
   border-bottom-right-radius: 10em;
   background: #ffffff;
   
}

.halfCoverBottom1{
   height: 35px;
   width: 35px;
   border-top-right-radius: 10em;
   background: #ffffff;
}
.left{
  float:left;
}
.halfCircleRight{
   height: 70px;
   width: 70px;
   border-top-right-radius: 10em;
   border-bottom-right-radius: 10em;
   background: #b1a51f;       
}

.halfCoverTop {
   height: 35px;
   width: 35px;
   border-bottom-right-radius: 10em;
   background: #ffffff;
}

.halfCoverBottom{
   height: 35px;
   width: 35px;
   border-top-right-radius: 10em;
   background: #ffffff;
}

<div class="left">
<div class="halfCircleRight">
  <div class="halfCoverTop"></div>
  <div class="halfCoverBottom"></div>
</div>
<div class="halfCircleRight">
  <div class="halfCoverTop"></div>
  <div class="halfCoverBottom"></div>
</div>
<div class="halfCircleRight">
  <div class="halfCoverTop"></div>
  <div class="halfCoverBottom"></div>
</div>
<div class="halfCircleRight">
  <div class="halfCoverTop"></div>
  <div class="halfCoverBottom"></div>
</div>
 </div>
<div class="left">
<div class="halfCircleRight">
  <div class="halfCoverTop"></div>
  <div class="halfCoverBottom"></div>
</div>
<div class="halfCircleRight">
  <div class="halfCoverTop"></div>
  <div class="halfCoverBottom"></div>
</div>
<div class="halfCircleRight">
  <div class="halfCoverTop"></div>
  <div class="halfCoverBottom"></div>
</div>
<div class="halfCircleRight">
  <div class="halfCoverTop"></div>
  <div class="halfCoverBottom"></div>
</div>
 </div>
<div class="left">
  <div class="halfCircleRight">
  <div class="halfCoverTop"></div>
  <div class="halfCoverBottom"></div>
</div>
<div class="halfCircleRight">
  <div class="halfCoverTop"></div>
  <div class="halfCoverBottom"></div>
</div>
<div class="halfCircleRight">
  <div class="halfCoverTop"></div>
  <div class="halfCoverBottom"></div>
</div>
<div class="halfCircleRight">
  <div class="halfCoverTop"></div>
  <div class="halfCoverBottom"></div>
</div>
 </div>
<div class="left">
  <div class="halfCircleRight">
  <div class="halfCoverTop"></div>
  <div class="halfCoverBottom"></div>
</div>
<div class="halfCircleRight">
  <div class="halfCoverTop"></div>
  <div class="halfCoverBottom"></div>
</div>
<div class="halfCircleRight">
  <div class="halfCoverTop"></div>
  <div class="halfCoverBottom"></div>
</div>
<div class="halfCircleRight">
  <div class="halfCoverTop"></div>
  <div class="halfCoverBottom"></div>
</div>
 </div>
<div class="left1">
<div class="halfCircleRight1">
  <div class="halfCoverTop1"></div>
  <div class="halfCoverBottom1"></div>
</div>
<div class="halfCircleRight1">
  <div class="halfCoverTop1"></div>
  <div class="halfCoverBottom1"></div>
</div>
<div class="halfCircleRight1">
  <div class="halfCoverTop1"></div>
  <div class="halfCoverBottom1"></div>
</div>
<div class="halfCircleRight1">
  <div class="halfCoverTop1"></div>
  <div class="halfCoverBottom1"></div>
</div>
 </div>
<div class="left1">
<div class="halfCircleRight1">
  <div class="halfCoverTop1"></div>
  <div class="halfCoverBottom1"></div>
</div>
<div class="halfCircleRight1">
  <div class="halfCoverTop1"></div>
  <div class="halfCoverBottom1"></div>
</div>
<div class="halfCircleRight1">
  <div class="halfCoverTop1"></div>
  <div class="halfCoverBottom1"></div>
</div>
<div class="halfCircleRight1">
  <div class="halfCoverTop1"></div>
  <div class="halfCoverBottom1"></div>
</div>
 </div>
<div class="left1">
  <div class="halfCircleRight1">
  <div class="halfCoverTop1"></div>
  <div class="halfCoverBottom1"></div>
</div>
<div class="halfCircleRight1">
  <div class="halfCoverTop1"></div>
  <div class="halfCoverBottom1"></div>
</div>
<div class="halfCircleRight1">
  <div class="halfCoverTop1"></div>
  <div class="halfCoverBottom1"></div>
</div>
<div class="halfCircleRight1">
  <div class="halfCoverTop1"></div>
  <div class="halfCoverBottom1"></div>
</div>
 </div>
<div class="left1">
  <div class="halfCircleRight1">
  <div class="halfCoverTop1"></div>
  <div class="halfCoverBottom1"></div>
</div>
<div class="halfCircleRight1">
  <div class="halfCoverTop1"></div>
  <div class="halfCoverBottom1"></div>
</div>
<div class="halfCircleRight1">
  <div class="halfCoverTop1"></div>
  <div class="halfCoverBottom1"></div>
</div>
<div class="halfCircleRight1">
  <div class="halfCoverTop1"></div>
  <div class="halfCoverBottom1"></div>
</div>
 </div>
&#13;
&#13;
&#13;

但有些地方我出错了以达到我的欲望输出。我无法弄清楚我的做法。任何人都可以帮助我实现我的实际输出。

2 个答案:

答案 0 :(得分:2)

创建此形状有多种可能性。每个人都有自己的优点和缺点。您可以决定哪种最适合您的需求。

基于SVG的方法:

SVG是创建此类形状的推荐且更合适的方式。

第1步:

这个想法是绘制一个在你的形状中重复的小组件,然后使用SVG的模式重复它。我们可以使用SVG的path元素来创建这个形状,并用一些颜色,渐变或图案填充它。

只有一个属性d用于定义path元素中的形状。该属性本身包含许多短命令和很少的参数,这些命令是这些命令工作所必需的。

以下是创建此形状所需的代码:

<path d="M 0,.125
         Q .110,.114 .125,0
         A .125,.125 0 0 1 .125,.250
         Q .110,.136 0,.125" />

我在路径元素中使用了3个命令。以下是简要说明:

  • M命令用于定义起点。它出现在开头,并指定绘图应该从哪里开始。
  • Q命令用于绘制曲线。
  • A命令也用于绘制曲线。

工作示例:

body {
  background-color: #ececec;
}
svg {
  margin: 10px auto;
  display: block;
}
<svg width="170" height="170" viewBox="0 0 50 50">
    <path d="M 0,25
             Q 22,22 25,0
             A 25,25 0 0 1 25,50
             Q 22,28 0,25" fill="#aba219" fill-opacity="inherit" />

</svg>

输出图片:

以下是第一步的输出:

Tile Image

第2步:

现在我们将创建一个将重复此形状的模式。在创建之后,我们将更接近最终输出。

考虑以下代码:

<defs>
    <pattern id="pattern1" x="0" y="0" width="25%" height="25%"
             patternUnits="objectBoundingBox"
             patternContentUnits="objectBoundingBox">
        <path id="tile" fill="inherit" fill-opacity="inherit"
              d="M 0,.125
                 Q .110,.114 .125,0
                 A .125,.125 0 0 1 .125,.250
                 Q .110,.136 0,.125" />
    </pattern>
</defs>

<rect x="0" y="0" width="200" height="200" fill="url(#pattern1)" />

以下是上述代码的简要说明:

  • SVG的<defs>元素用于定义图形/元素供以后使用。 defs中定义的对象不会立即在屏幕上绘制。它们将来会被代码的其他部分引用。
  • <pattern>元素定义了一个图形对象,可以在重复的x和y坐标间隔(“平铺”)重绘以覆盖区域。此模式将由图形元素的fill / stroke属性引用。
  • <rect>元素用于在屏幕上绘制矩形区域。请注意此元素上使用的fill属性。此属性引用了上面<defs>部分中定义的模式。现在我们实际上使用这个模式来填充矩形区域。

工作示例:

body {
  background-color: #ececec;
}
svg {
  margin: 0 auto;
  display: block;
}
<svg width="200" height="200" viewBox="0 0 200 200">
    <defs>
        <path id="tile" fill="inherit" fill-opacity="inherit"
              d="M 0,.125
                 Q .110,.114 .125,0
                 A .125,.125 0 0 1 .125,.250
                 Q .110,.136 0,.125" />

        <pattern id="pattern1" x="0" y="0" width="25%" height="25%"
                 patternUnits="objectBoundingBox"
                 patternContentUnits="objectBoundingBox">
            <use href="#tile" fill="#aba219" />
        </pattern>
    </defs>
    <rect x="0" y="0" width="200" height="200" fill="url(#pattern1)" />
</svg>

输出图片:

以下是迄今为止的结果:

Pattern

第3步:

最后,我们将创建两个模式并将其应用于2个不同的<rect>元素以创建最终输出。

以下代码模式将用于创建最终输出:

<defs>
    <path id="tile" d="..." />

    <pattern id="pattern1">
        <use href="#tile" fill="#aba219" />
    </pattern>
    <pattern id="pattern2" patternTransform="scale(-1)">
        <use href="#tile" fill="#023e54" />
    </pattern>
</defs>
<rect width="200" height="880" fill="url(#pattern1)" />
<rect width="200" height="200" fill="url(#pattern2)" />

大多数代码与上述类似。但请注意<use>元素的使用。我们不是在每个path元素中定义pattern元素,而是将其定义一次并使用<use>元素将其复制到其他两个位置。

<use>元素从SVG文档中获取节点,并将其复制到其他位置。

工作示例:

body {
  background-color: #ececec;
}
svg {
  margin: 0 auto;
  display: block;
}
<svg width="190" height="190" viewBox="0 0 990 990">
    <defs>
        <path id="tile" fill="inherit" fill-opacity="inherit"
              d="M 0,.125
                 Q .110,.114 .125,0
                 A .125,.125 0 0 1 .125,.250
                 Q .110,.136 0,.125" />

        <pattern id="pattern1" x="0" y="0" width="25%" height="25%"
                 patternUnits="objectBoundingBox"
                 patternContentUnits="objectBoundingBox">
            <use href="#tile" fill="#aba219" />
        </pattern>

        <pattern id="pattern2" x="0" y="0" width="25%" height="25%"
                 patternUnits="objectBoundingBox"
                 patternContentUnits="objectBoundingBox"
                 patternTransform="scale(-1)">
            <use href="#tile" fill="#023e54" fill-opacity="0.7" />
        </pattern>
    </defs>

    <rect x="0" y="0" width="880" height="880" fill="url(#pattern1)" />
    <rect x="110" y="110" width="880" height="880" fill="url(#pattern2)" />
</svg>

输出图片:

以下是最终输出图像:

Pattern

基于HTML / CSS的方法:

虽然可行,但我不建议这样做,因为创建这种形状需要很多元素,这不是一种有效的方法。

工作示例:

body {
  background-color: #ececec;
}
.tile-list {
  list-style: none;
  margin: 0 auto;
  width: 225px;
  padding: 0;
}

.tile-list li {
  display: flex;
}
.tile-list li:nth-child(even) {
  position: relative;
  padding-left: 25px;
  margin: -25px 0;
  z-index: 1;
}

.tile {
  border-radius: 100%;
  position: relative;
  overflow: hidden;
  height: 50px;
  width: 50px;
}
.tile .left {
  position: absolute;
  overflow: hidden;
  height: 50%;
  width: 50%;
  left: 0;
  top: 0;
}
.tile .left.bottom {
  bottom: 0;
  top: auto;
}
.tile .left::before {
  box-shadow: 0 0 0 10px #aba219;
  border-radius: 100%;
  position: absolute;
  overflow: hidden;
  content: '';
  height: 200%;
  width: 200%;
  left: -100%;
  top: -100%;
}
.tile .left.bottom::before {
  bottom: -100%;
  top: auto;
}
.tile .right {
  position: absolute;
  overflow: hidden;
  height: 100%;
  width: 100%;
  left: 50%;
  top: 0;
}
.tile .right::before {
  background-color: #aba219;
  position: absolute;
  height: 100%;
  content: '';
  width: 100%;
  left: -50%;
  top: 0;
}
.tile-list li:nth-child(even) .tile {
  transform: scale(-1);
}
.tile-list li:nth-child(even) .tile .right::before {
  background-color: rgb(2, 62, 84, 0.7);
}
.tile-list li:nth-child(even) .tile .left::before {
  box-shadow: 0 0 0 10px rgb(2, 62, 84, 0.7);
}
<ul class="tile-list">
  <li>
    <div class="tile">
      <div class="left top"></div>
      <div class="left bottom"></div>
      <div class="right"></div>
    </div>
    <div class="tile">
      <div class="left top"></div>
      <div class="left bottom"></div>
      <div class="right"></div>
    </div>
    <div class="tile">
      <div class="left top"></div>
      <div class="left bottom"></div>
      <div class="right"></div>
    </div>
    <div class="tile">
      <div class="left top"></div>
      <div class="left bottom"></div>
      <div class="right"></div>
    </div>
  </li>
  <li>
    <div class="tile">
      <div class="left top"></div>
      <div class="left bottom"></div>
      <div class="right"></div>
    </div>
    <div class="tile">
      <div class="left top"></div>
      <div class="left bottom"></div>
      <div class="right"></div>
    </div>
    <div class="tile">
      <div class="left top"></div>
      <div class="left bottom"></div>
      <div class="right"></div>
    </div>
    <div class="tile">
      <div class="left top"></div>
      <div class="left bottom"></div>
      <div class="right"></div>
    </div>
  </li>
  <li>
    <div class="tile">
      <div class="left top"></div>
      <div class="left bottom"></div>
      <div class="right"></div>
    </div>
    <div class="tile">
      <div class="left top"></div>
      <div class="left bottom"></div>
      <div class="right"></div>
    </div>
    <div class="tile">
      <div class="left top"></div>
      <div class="left bottom"></div>
      <div class="right"></div>
    </div>
    <div class="tile">
      <div class="left top"></div>
      <div class="left bottom"></div>
      <div class="right"></div>
    </div>
  </li>
  <li>
    <div class="tile">
      <div class="left top"></div>
      <div class="left bottom"></div>
      <div class="right"></div>
    </div>
    <div class="tile">
      <div class="left top"></div>
      <div class="left bottom"></div>
      <div class="right"></div>
    </div>
    <div class="tile">
      <div class="left top"></div>
      <div class="left bottom"></div>
      <div class="right"></div>
    </div>
    <div class="tile">
      <div class="left top"></div>
      <div class="left bottom"></div>
      <div class="right"></div>
    </div>
  </li>
  <li>
    <div class="tile">
      <div class="left top"></div>
      <div class="left bottom"></div>
      <div class="right"></div>
    </div>
    <div class="tile">
      <div class="left top"></div>
      <div class="left bottom"></div>
      <div class="right"></div>
    </div>
    <div class="tile">
      <div class="left top"></div>
      <div class="left bottom"></div>
      <div class="right"></div>
    </div>
    <div class="tile">
      <div class="left top"></div>
      <div class="left bottom"></div>
      <div class="right"></div>
    </div>
  </li>
  <li>
    <div class="tile">
      <div class="left top"></div>
      <div class="left bottom"></div>
      <div class="right"></div>
    </div>
<div class="tile">
<div class="left top"></div>
<div class="left bottom"></div>
<div class="right"></div>
</div>
<div class="tile">
<div class="left top"></div>
<div class="left bottom"></div>
<div class="right"></div>
</div>
<div class="tile">
<div class="left top"></div>
<div class="left bottom"></div>
<div class="right"></div>
</div>
</li>
</ul>

答案 1 :(得分:1)

使用一些SVG,伪元素和多个背景的另一个想法怎么样:

.box {
  margin:60px;
  width:450px;
  height:250px;
  background:
  url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="10 10 75 80" width="100"><path d="M50 10 C 100 10, 100 90, 50 90 C 50 65, 35 50, 10 50 C 35 50, 50 35, 50 10"  fill="rgb(177, 165, 31,0.8)"/></svg>') -50px -50px /100px 100px repeat,
  url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="-90 10 75 80" width="100"><path d="M50 10 C 100 10, 100 90, 50 90 C 50 65, 35 50, 10 50 C 35 50, 50 35, 50 10"  fill="%23326d7d"  transform="scale(-1,1)"/></svg>') 0px 0px/100px 100px repeat ;
  position:relative;
}
.box:before {
  content:"";
  position:absolute;
  top:-50px;
  height:50px;
  left:0;
  right:0;
  background:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="10 10 75 80" width="100"><path d="M50 10 C 100 10, 100 90, 50 90 C 50 65, 35 50, 10 50 C 35 50, 50 35, 50 10"  fill="rgb(177, 165, 31,0.8)"/></svg>') 50px 0 /100px 100px repeat;
}

.box:after {
  content:"";
  position:absolute;
  bottom:-50px;
  height:50px;
  left:0;
  right:0;
  background:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="-90 10 75 80" width="100"><path d="M50 10 C 100 10, 100 90, 50 90 C 50 65, 35 50, 10 50 C 35 50, 50 35, 50 10"  fill="%23326d7d"  transform="scale(-1,1)"/></svg>')0px -50px/100px 100px repeat;
}
.intern {
  height:100%;
  position:relative;
}
.intern:before {
  content:"";
  position:absolute;
  top:-50px;
  bottom:0;
  left:-50px;
  width:50px;
  background:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="10 10 75 80" width="100"><path d="M50 10 C 100 10, 100 90, 50 90 C 50 65, 35 50, 10 50 C 35 50, 50 35, 50 10"  fill="rgb(177, 165, 31,0.8)"/></svg>') 0 0 /100px 100px repeat
}
.intern:after {
  content:"";
  position:absolute;
  top:0;
  bottom:-50px;
  right:-50px;
  width:50px;
  background:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="-90 10 75 80" width="100"><path d="M50 10 C 100 10, 100 90, 50 90 C 50 65, 35 50, 10 50 C 35 50, 50 35, 50 10"  fill="%23326d7d"  transform="scale(-1,1)"/></svg>')-50px 0/100px 100px repeat
}
<div class="box">
<div class="intern"></div>
</div>

<强>更新

这是另一种不使用SVG而只使用CSS的想法(我将依赖径向渐变):

.container {
  position:relative;
  z-index:0;
}
.top,.bottom  {
  width:400px;
}
.bottom {
  position:absolute;
  top:50px;
  left:50px;
  z-index:-1;
}

.top >div {
  width:100px;
  height:100px;
  border-radius:50%;
  overflow:hidden;
  position:relative;
  display:inline-block;
}
.top >div:before,.top >div:after {
  content:"";
  position:absolute;
  left:0;
  right:0;
  height:50%;
}
.top >div:before {
  top:0;
  background:radial-gradient(circle at top left,transparent 44%, rgb(177, 165, 31,0.8) 44.5%);
}
.top >div:after {
  bottom:0;
  background:radial-gradient(circle at bottom left,transparent 44%, rgb(177, 165, 31,0.8) 44.5%);
}

.bottom >div {
  width:100px;
  height:100px;
  border-radius:50%;
  overflow:hidden;
  position:relative;
  display:inline-block;
}
.bottom >div:before,.bottom >div:after {
  content:"";
  position:absolute;
  left:0;
  right:0;
  height:50%;
}
.bottom >div:before {
  top:0;
  background:radial-gradient(circle at top right,transparent 44%, #326d7d 44.5%);
}
.bottom >div:after {
  bottom:0;
  background:radial-gradient(circle at bottom right,transparent 44%, #326d7d 44.5%);
}
<div class="container"> 
<div class="top">
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</div>
<div class="bottom">
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</div>
</div>