我希望在CSS中创建两个形状。第一个,左边的那个,我接近制作,但我的形状走得太远了。
第二种形状,我正在完全挣扎。
无论如何都要复制这些形状?反正有没有使用Psuedo元素/只作为一个div?
目标是使用CSS动画将第一个形状设为第二个,所以我不相信SVG是一个选项。
div
应从形状一开始,逐渐过渡到形状二。用我的方法来说,到目前为止我的问题还没有突出。
HTML
<div id="one"></div>
<div id="two"></div>
CSS
div {
width: 80px;
height: 80px;
background: black;
margin: 60px;
position: relative;
}
#one:before {
content: "";
display: block;
position: absolute;
border-radius: 55%;
width: 80px;
height: 80px;
background: black;
left: 0;
top: -34px;
}
答案 0 :(得分:4)
你可以使用Raphael或SVG变形bezier路径,但我不知道该怎么做。这应该是最干净的解决方案
我认为这可能有用: -
创建一个元素并将Overflow隐藏
设置伪元素的时间,动画边框半径和高度
使用伪元素的框阴影进行着色。
<强>&GT; Fiddle&lt;
body{
background: url("http://www.placekitten.com/g/600/400");
background-size: cover;
}
#rect {
height: 300px;
width: 100px;
border-top-left-radius: 50px 40px;
border-top-right-radius: 50px 40px;
position: relative;
overflow: hidden;
-webkit-animation: morph 1s linear 1;
-webkit-animation-fill-mode: forwards;
animation: morph 1s linear 1;
animation-fill-mode: forwards;
}
#rect:before {
position: absolute;
content: "";
width: 100px;
box-shadow: 0px 0px 0px 400px #A34;
-webkit-animation: morph2 1s linear 1;
-webkit-animation-delay: 1s;
-webkit-animation-fill-mode: forwards;
animation: morph2 1s linear 1;
animation-delay: 1s;
animation-fill-mode: forwards;
}
@-webkit-keyframes morph {
0%{
border-top-left-radius: 50px 40px;
border-top-right-radius: 50px 40px;
top:0px;
height: 300px;
}
100%{
border-top-left-radius: 40px 0px;
border-top-right-radius: 40px 0px;
top: 40px;
height: 260px;
}
}
@-webkit-keyframes morph2 {
0%{
height: 0px;
border-bottom-left-radius: 40px 0px;
border-bottom-right-radius: 40px 0px;
}
100%{
border-bottom-left-radius: 50px 40px;
border-bottom-right-radius: 50px 40px;
height: 40px;
}
}
/*FOR OTHER BROWSERS*/
@keyframes morph {
0%{
border-top-left-radius: 50px 40px;
border-top-right-radius: 50px 40px;
top:0px;
height: 300px;
}
100%{
border-top-left-radius: 40px 0px;
border-top-right-radius: 40px 0px;
top: 40px;
height: 260px;
}
}
@keyframes morph2 {
0%{
height: 0px;
border-bottom-left-radius: 40px 0px;
border-bottom-right-radius: 40px 0px;
}
100%{
border-bottom-left-radius: 50px 40px;
border-bottom-right-radius: 50px 40px;
height: 40px;
}
}
&#13;
<div id="rect">
</div>
&#13;
注意抱歉代码有点太大了,我写了大约一年后写的CSS和HTML!我认为可以缩短很多这种混乱。
答案 1 :(得分:3)
据我所知,没有使用伪元素就无法实现动画效果。以下是使用多个渐变和伪元素的一种可能(但非常复杂的方法)。形状由以下部分组成:
div
元素。它使用径向梯度和线性梯度的组合生成。父级的一半高度由径向渐变占据并产生透明切口,另一半(底部)半部由线性渐变占据并最终产生纯黑色。线性渐变实际上不产生任何渐变,而是仅产生纯色,因为纯色的颜色停止太靠近终点。这仍然是必需的,因为不使用渐变(作为图像),我们无法控制纯色占据的空间。:before
元素,它具有两个径向渐变,并产生两个半椭圆相互叠加的效果。顶部的一个是透明的半椭圆形(其余为黑色),而底部的一个是黑色半椭圆形(其余部分是透明的)。我们需要两个渐变,因为当我们为background-position
设置动画时,这看起来好像凸出的区域正在崩溃。:after
元素有一个径向渐变,产生一个纯黑色椭圆。此元素位于父元素上方的一半以产生凸出效果。:after
元素沿X轴旋转90度,这使得它看起来好像从视图中慢慢消失。在动画的第二部分期间,:before
元素的background-position
被动画化,使得黑色半椭圆偏离路径并且透明的半椭圆形到位。
div {
position: relative;
height: 80px;
width: 80px;
margin-top: 60px; /* safe to have half of parent height */
background: radial-gradient(ellipse at 50% 0%, transparent 70%, black 72%), linear-gradient(to bottom, black 99.9%, transparent 99.9%);
background-size: 100% 50%, 100% 50%; /* the height of first image will be same as height of transparent cut, height of second image is the rest */
background-position: 0% 0%, 0% 100%;
background-repeat: no-repeat;
}
div:before,
div:after {
position: absolute;
content: '';
width: 100%;
}
div:before {
height: 100%; /* height of first image on parent * 2 */
top: 0px;
background-image: radial-gradient(ellipse at 50% 0%, black 70%, transparent 72%), radial-gradient(ellipse at 50% 0%, transparent 70%, black 72%);
background-size: 100% 50%;
background-position: 0% 2px, 0% -38px;
background-repeat: no-repeat;
animation: morph-shape 2s 2s linear forwards;
}
div:after {
height: 50%; /* this should be same as height of first image on parent */
top: -38px; /* this is height of pseudo-element in % * height of parent - 2px */
background-image: radial-gradient(ellipse at 50% 50%, black 70%, transparent 72%);
background-size: 100% 200%;
background-repeat: no-repeat;
transform-origin: bottom;
animation: morph-shape2 2s linear forwards;
}
@keyframes morph-shape2 {
from {
transform: rotateX(0deg);
}
to {
transform: rotateX(90deg);
}
}
@keyframes morph-shape {
from {
background-position: 0% 2px, 0% -38px; /* the negative value is height of image - 2px = 50% of container height (which is 50% of 80px) - 2px*/
}
to {
background-position: 0% 100%, 0% 0%;
}
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div></div>
&#13;
仅为了说明,这里是三个元素在没有放在另一个上面时的样子。我已经离开动画了,你仍然可以感受到它到底发生了什么。此外,即使更改了父级的维度(如果评论中提到的计算正确完成),它似乎也能正常工作。
div {
position: relative;
height: 160px;
width: 120px;
margin-top: 80px;
background: radial-gradient(ellipse at 50% 0%, transparent 70%, black 72%), linear-gradient(to bottom, black 99.9%, transparent 99.9%);
background-size: 100% 40%, 100% 60%;
background-position: 0% 0%, 0% 100%;
background-repeat: no-repeat;
}
div:before,
div:after {
position: absolute;
content: '';
width: 100%;
}
div:before {
height: 80%;
top: 0px;
left: 150px;
background-image: radial-gradient(ellipse at 50% 0%, black 70%, transparent 72%), radial-gradient(ellipse at 50% 0%, transparent 70%, black 72%);
background-size: 100% 50%;
background-position: 0 2px, 0% -62px;
background-repeat: no-repeat;
animation: morph-shape 2s 2s linear forwards;
}
div:after {
height: 40%;
top: -62px;
left: 300px;
background-image: radial-gradient(ellipse at 50% 50%, black 70%, transparent 72%);
background-size: 100% 200%;
background-repeat: no-repeat;
transform-origin: bottom;
animation: morph-shape2 2s linear forwards;
}
@keyframes morph-shape2 {
from {
transform: rotateX(0deg);
}
to {
transform: rotateX(90deg);
}
}
@keyframes morph-shape {
from {
background-position: 0% 2px, 0% -62px;
}
to {
background-position: 0% 100%, 0% 0%;
}
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div></div>
&#13;
下面是容器和透明切口的不同尺寸的版本。
div {
position: relative;
height: 200px;
width: 150px;
margin-top: 100px;
background: radial-gradient(ellipse at 50% 0%, transparent 70%, black 72%), linear-gradient(to bottom, black 99.9%, transparent 99.9%);
background-size: 100% 30%, 100% 70%;
background-position: 0% 0%, 0% 100%;
background-repeat: no-repeat;
}
div:before,
div:after {
position: absolute;
content: '';
width: 100%;
}
div:before {
height: 60%;
top: 0px;
background-image: radial-gradient(ellipse at 50% 0%, black 70%, transparent 72%), radial-gradient(ellipse at 50% 0%, transparent 70%, black 72%);
background-size: 100% 50%;
background-position: 0% 2px, 0% -58px;
background-repeat: no-repeat;
animation: morph-shape 2s 2s linear forwards;
}
div:after {
height: 30%;
top: -58px;
background-image: radial-gradient(ellipse at 50% 50%, black 70%, transparent 72%);
background-size: 100% 200%;
background-repeat: no-repeat;
transform-origin: bottom;
animation: morph-shape2 2s linear forwards;
}
@keyframes morph-shape2 {
from {
transform: rotateX(0deg);
}
to {
transform: rotateX(90deg);
}
}
@keyframes morph-shape {
from {
background-position: 0% 2px, 0% -58px;
}
to {
background-position: 0% 100%, 0% 0%;
}
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div></div>
&#13;
答案 2 :(得分:0)
您可以使用伪元素和溢出隐藏
*{box-sizing: border-box}
html{text-align: center;padding: 60px 10px}
.fig{
margin: 20px auto;
width: 100px;
height: 200px;
position: relative
}
.fig:before{
content:'';
position: absolute;
top: -50px;
left:0;
width: 100px;
height: 100px;
border-radius: 50%
}
#one{background: black}
#two{overflow: hidden; box-shadow: inset 0 -150px black}
#one:before{background: black}
#two:before{box-shadow: 0 3em black}
&#13;
<div id=one class=fig></div>
<div id=two class=fig></div>
&#13;