【问题标题】:Complex design pattern - overlapping transparent shapes?复杂的设计模式——重叠的透明形状?
【发布时间】:2018-09-10 06:25:04
【问题描述】:

我正在尝试创建以下形状。

我几乎尝试通过以下方式创建此图像。为了使用 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>

但是有些地方我在实现我的愿望输出方面出错了。我无法弄清楚我的方法。任何人都可以请帮助实现我的实际输出。

【问题讨论】:

    标签: html css css-shapes


    【解决方案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,
      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;
      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;
    }
    
    .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 ;
    }
    .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;
    }
    .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;
    }
    <div class="box">
    <div class="intern"></div>
    </div>

    更新

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

    .container {
      position:relative;
      width:400px;
      z-index:0;
    }
    .bottom {
      position:absolute;
      z-index:-1;
      top:0;
      left:0;
      transform:translate(50px,50px);
    }
    
    .top    >div,
    .bottom >div{
      width:100px;
      height:100px;
      border-radius:50%;
      display:inline-block;
      background-size:100% 50%;
      background-position:top,bottom;
      background-repeat:no-repeat;
    }
    .top    >div {
      background-image:
        radial-gradient(circle at top left,   transparent 44%, rgb(177, 165, 31,0.8) 44.5%),
        radial-gradient(circle at bottom left,transparent 44%, rgb(177, 165, 31,0.8) 44.5%);
    }
    .bottom >div {
      background-image:
        radial-gradient(circle at top right,   transparent 44%, #326d7d 44.5%),
        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>

    【讨论】:

    • 我不想使用 SVG 图像。应该纯粹用 CSS 和 HTML 来完成
    • @ram 祝你好运 :) 我只在只使用 CSS 很疯狂的情况下才使用 SVG,而且是这样 ;)
    • @ram 我添加了另一种复杂的 CSS 方式 ;)
    【解决方案2】:

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

    基于 SVG 的方法:

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

    第 1 步:

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

    d 元素中只有一个属性d 用于定义形状。该属性本身包含一些简短的命令和一些使这些命令起作用所必需的参数。

    以下是创建此形状的必要代码:

    <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>

    输出图像:

    下面是第一步的输出:


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

    工作示例:

    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>

    输出图像:

    以下是目前的结果:


    第 3 步:

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

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

    <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)" />
    

    大部分代码与上面描述的类似。但是请注意&lt;use&gt; 元素的使用。我们没有在每个 pattern 元素中定义 path 元素,而是定义了它一次,然后使用 &lt;use&gt; 元素将其复制到其他两个地方。

    &lt;use&gt; 元素从 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>

    输出图像:

    下面是最终输出的图片:


    基于 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>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多