我一直在尝试在CSS中为项目创建响应式云形状。由于HTTP请求和响应性要求,我试图不使用图像,CSS或内联SVG。
有问题的形状是这样的:(但可以是相似的 - 稍微变化/改进会很酷):
我找到了这两个问题,但它们似乎并不适合我的确切需求:
我尝试(并且失败)使用border
或box-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;
正如您所看到的,我在响应能力方面遇到了麻烦,并且确切地计算了所需的高度/宽度。
我也试图将HTML的数量保持在绝对最小值,因此我更喜欢使用单个div或短SVG代码。
答案 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>
下面是一个带有云绘制动画的示例代码段,其中通过重复递减路径的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}}