创建响应式云形

时间:2015-06-18 15:03:21

标签: html css css3 svg css-shapes

我一直在尝试在CSS中为项目创建响应式云形状。由于HTTP请求和响应性要求,我试图不使用图像,CSS或内联SVG。

有问题的形状是这样的:(但可以是相似的 - 稍微变化/改进会很酷):

Cloud Shape

我找到了这两个问题,但它们似乎并不适合我的确切需求:

我尝试(并且失败)使用borderbox-shadow创建云,并且需要知道这是否可以使用CSS或作为替代内联SVG。我也看过Canvas也是一个选项,但我宁愿远离它,因为它可能会非常复杂。

这是我的穷人尝试



body {
  background: skyblue;
}

.cloud {
  width: 15%;
  height: 10vh;
  background: white;
  position: relative;
  margin: 100px 100px;
  border-radius: 65px;
  box-shadow: black 0 0 10px 10px;
}
.cloud:after {
  content: '';
  position: absolute;
  width: 150px;
  height: 150px;
  top: -60px;
  left: 100px;
  border-radius: 75px;
  background: white;
}
.cloud:before {
  content: '';
  position: absolute;
  width: 70px;
  height: 70px;
  background: white;
  left: 50px;
  top: -30px;
  border-radius: 35px;
}

<div class="cloud"></div>
&#13;
&#13;
&#13;

正如您所看到的,我在响应能力方面遇到了麻烦,并且确切地计算了所需的高度/宽度。

我也试图将HTML的数量保持在绝对最小值,因此我更喜欢使用单个div或短SVG代码。

2 个答案:

答案 0 :(得分:23)

可以使用SVG在SVG中使用单个path元素创建云形状。 SVG本质上是可扩展的,不会对形状造成任何扭曲。 browser support for SVG非常好,IE8可以回退,使用VML可以提供更低的(如果需要)。

形状创建

绘制形状及其含义时使用的命令如下:

  • M 25,60 - 此命令将笔移动到X轴上原点(0,0)前方25px处和Y轴原点前方60px处的点。 (注意:该命令以大写字母书写,表示absolute移动而不是relative移动。
  • a 20,20 1 0,0 0,40 - 此命令创建一个X和Y半径为20px的弧。弧起点为(25,60),终点为(25,100)(即X轴偏离0px,Y轴偏离40px)。
  • h 50 - 此命令绘制一条相对于起点前方50px的水平线。由于它是相对的,终点将是(75,100)。
  • a 20,20 1 0,0 0,-40 - 与第二个命令类似,这会创建另一个弧,其半径在任一轴上为20px,其终点相对于前一个点为40px。所以从本质上讲,这将创建一个从(75,100)到(75,60)的弧。这和第二个命令一起形成云的两侧的弧。
  • a 10,10 1 0,0 -15,-10 - 另一个弧命令,用于创建云的弯曲顶部的一部分。半径为10px,弧度为(75,60)到(60,50)。
  • a 15,15 1 0,0 -35,10 - 完成云端的最后一个弧线。半径为15px,弧度为(60,50)至(25,60)。 (25,60)是原始起点,因此完成了形状。
  • z - 关闭路径。

svg {
  height: 50%;
  width: 50%;
}
path {
  fill: white;
  stroke: black;
  stroke-width: 2;
  stroke-linejoin: round;
}
path:hover {
  fill: aliceblue;
  stroke: lightskyblue;
}
<svg viewBox='0 0 105 105'>
  <path d='M 25,60 
           a 20,20 1 0,0 0,40 
           h 50 
           a 20,20 1 0,0 0,-40 
           a 10,10 1 0,0 -15,-10 
           a 15,15 1 0,0 -35,10  
           z' />
</svg>

使用SVG的优点

  • 它们易于创建和维护
  • 这些命令很容易理解,不需要复杂的定位或黑客攻击
  • 默认情况下,它们是可扩展的(响应式)
  • 只要SVG内联
  • ,就不需要额外的HTTP请求
  • 更好地控制弧线,半径等
  • 只有当鼠标位于形状的边界内时,才能限制悬停效果(如下面的代码段所示)。
  • 可以轻松添加额外效果。也就是说,您可以模仿屏幕上绘制的形状等行为。

额外效果 - 云绘制动画

下面是一个带有云绘制动画的示例代码段,其中通过重复递减路径的stroke-dashoffset属性来绘制路径,直到它变为0.初始偏移值等于路径的总长度使用getTotalLength()方法计算。云形状也添加了模糊阴影。

使用window.requestAnimationFrame方法实现动画。

window.onload = function() {
  var offset;
  var path = document.getElementsByTagName('path')[0];
  var len = path.getTotalLength();

  function paint() {
    path.style.strokeDashoffset = len;
    path.style.strokeDasharray = len + ',' + len;
    animate();
  }

  function animate() {
    if (!offset) offset = len;
    offset -= 0.5;
    path.style.strokeDashoffset = offset;
    if (offset < 0)
      window.cancelAnimationFrame(anim);
    else anim = window.requestAnimationFrame(function() {
      animate();
    });
  }

  paint();
};
svg {
  height: 40%;
  width: 40%;
}
path {
  fill: white;
  stroke: black;
  stroke-width: 2;
  stroke-linejoin: round;
}
path:hover {
  fill: aliceblue;
  stroke: lightskyblue;
}
<svg viewBox='0 0 105 105'>
  <filter id='shadow'>
    <feGaussianBlur in='SourceAlpha' stdDeviation='2' />
    <feOffset dx='2' dy='0' result='blur' />
    <feMerge>
      <feMergeNode in='blur' />
      <feMergeNode in='SourceGraphic' />
    </feMerge>
  </filter>
  <path d='M 25,60 
           a 20,20 1 0,0 0,40 
           h 50 
           a 20,20 1 0,0 0,-40 
           a 10,10 1 0,0 -15,-10 
           a 15,15 1 0,0 -36,10  
           z' filter='url(#shadow)' />
</svg>

答案 1 :(得分:14)

浮云和彩虹。

  

免责声明:此处没有彩虹

但是,下面是一个基本的“云”,由单个元素组成,并且由于它使用的是.cloud { height: 30vw; width: 90vw; background: lightgray; border-radius: 40vw; border: 5px solid black; position: relative; margin-top: 20vw; } .cloud:before { content: ""; position: absolute; top: -10vw; box-sizing: border-box; height: 20vw; width: 20vw; left: 15vw; border-radius: 50%; border: 5px solid black; border-bottom-color: transparent; border-right-color: transparent; background: lightgray; transform: rotate(40deg); } .cloud:after { content: ""; position: absolute; height: 40vw; width: 40vw; top: -20vw; left: 32vw; border-radius: 50%; box-sizing: border-box; border: 5px solid black; border-bottom-color: transparent; background: lightgray; border-right-color: transparent; transform: rotate(55deg); }单位,因此它也具有相当的响应性。

它使用两个伪元素,形状为圆圈,在顶部创建云的“泡芙”。这也允许使用边框,因为您可以旋转圆圈并将边框颜色应用到两个边。

<div class="cloud"></div>
path

  

虽然这个答案是使用CSS,但使用CSS可能更有用   SVG,如果您需要更多控制云形状的输出。

或者,SVG也可以使用<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve"> <g> <path d="M320,128c52,0,95,42,96,94c-0,1-0,3-0.5,5l-0.812,23l22,7 C462,268,480,293,480,320c0,35-28,64-64,64H96c-35,0-64-28-64-64c0-34,28-63,63-64 c1,0,3,0,4,0l24,1l8-22C140,209,165,192,192,192c3,0,6,0,11,1 l22,4.031l11-19C253.875,146,285,128,320,128 M320,96c-47,0-89,26-111,65 C203,160.719,197,160,192,160c-41,0-77.219,27-90.281,64.563C99.813,224.438,97.969,224,96,224c-53,0-96,43-96,96 s43,96,96,96h320c53,0,96-43,96-96c0-41-27-77-64-90C447.5,227.75,448,225.938,448,224 C448,153,390,96,320,96L320,96z" /> </g> </svg>声明来实现这样的形状(请注意这是生成的,而不是手动创建的,所以我不相信它)

{{1}}