我刚刚发现了一个GitHub Repo,上面有一个button
的酷炫动画,但是对于Android来说。
这是Animation
:
但是,我希望在我的网站上使用它,所以我开始自己设计。
首先,我broke the gif down by frames。然后,根据这些要点,我制定了路线图,这就是我在编写代码时遵循的路线:
scale()
下沉。scale()
向上逐渐覆盖星星。background-color
(在这种情况下为白色),也通过scale()
向上逐渐覆盖了上一个圆圈。scale()
)而逐渐z-index
再次出现,这次是橙色(指示其选定状态)。这是我到目前为止所做的:
svg {
position: absolute;
top: 0;
width: 100px;
height: 100px;
transition: 0.5s;
fill:gray;
}
svg:hover {
animation: up-svg 1s;
fill: darkorange;
z-index: 1;
}
svg:hover~.svg {
animation: up-one 0.5s;
display: block;
}
svg:hover~.svg1 {
animation: up-two 1s;
display: block;
}
.svg {
position: absolute;
top: 0;
border-radius: 50%;
width: 100px;
height: 100px;
background-color: orange;
display: none;
transform: scale(0.9);
transition: 0.5s;
}
.svg1 {
position: absolute;
top: 0;
border-radius: 50%;
width: 100px;
height: 100px;
background-color: white;
display: none;
transition: 0.5s;
}
@keyframes up-one {
0% {
transform: scale(0);
}
40% {
transform: scale(0);
}
100% {
transform: scale(0.9);
}
}
@keyframes up-two {
0% {
transform: scale(0);
}
37.5% {
transform: scale(0);
}
50% {
transform: scale(0.25);
}
62.5% {
transform: scale(0.5);
}
75% {
transform: scale(0.75);
}
87.5% {
transform: scale(0.9);
}
100% {
transform: scale(1);
}
}
@keyframes up-svg {
0% {
transform: scale(1);
fill: gray;
z-index: 0;
}
70% {
transform: scale(0);
fill: darkorange;
z-index: 1;
}
100% {
transform: scale(1);
fill: darkorange;
z-index: 1;
}
}
<svg id="s-tt" class="s-icon" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M23.954 4.569c-.885.389-1.83.654-2.825.775 1.014-.611 1.794-1.574 2.163-2.723-.951.555-2.005.959-3.127 1.184-.896-.959-2.173-1.559-3.591-1.559-2.717 0-4.92 2.203-4.92 4.917 0 .39.045.765.127 1.124C7.691 8.094 4.066 6.13 1.64 3.161c-.427.722-.666 1.561-.666 2.475 0 1.71.87 3.213 2.188 4.096-.807-.026-1.566-.248-2.228-.616v.061c0 2.385 1.693 4.374 3.946 4.827-.413.111-.849.171-1.296.171-.314 0-.615-.03-.916-.086.631 1.953 2.445 3.377 4.604 3.417-1.68 1.319-3.809 2.105-6.102 2.105-.39 0-.779-.023-1.17-.067 2.189 1.394 4.768 2.209 7.557 2.209 9.054 0 13.999-7.496 13.999-13.986 0-.209 0-.42-.015-.63.961-.689 1.8-1.56 2.46-2.548l-.047-.02z"/></svg>
<div class="svg"></div>
<div class="svg1"></div>
我已经尽力了,但是看起来仍然不像预期的那样,我也陷入了那些分散的圈子中。
颜色不是当前优先考虑的事情。现在,我坚持使用hover
属性(以便可以一次又一次地观看动画而无需重新加载),直到动画完成为止。
我已经在Google和SO上进行过搜索,但到目前为止还没有运气。
有人可以帮我做那种动画吗?
答案 0 :(得分:8)
这是我不完善的想法,我将仅依靠CSS和少量元素。我将单独详细介绍每个部分,然后将其组合成一个动画。
对于图标部分(星形),我会做同样的事情,但我可能会考虑使用grayscale
滤镜,该滤镜具有适用于任何元素和任何颜色的通用效果。
.magic i{
color:red;
filter:grayscale(100%);
}
.magic:hover i{
animation:change 1s forwards;
}
@keyframes change{
50% {
transform:scale(0);
filter:grayscale(100%);
}
51% {
filter:grayscale(0%);
}
100% {
transform:scale(1);
filter:grayscale(0%);
}
}
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css">
<span class="magic">
<i class="fas fa-star fa-5x"></i>
</span>
对于圆圈,我将仅考虑一个元素,这里的技巧是依靠边框着色与背景着色。我们最初将高度/宽度设置为0
,并且只有边框,因此它将是一个完整的圆。然后,我们简单地减小边框的厚度,同时保持整体宽度不变。因此,我们将这样做:
0
和边框宽度0
.circle {
display:inline-block;
width:0px;
height:0px;
border-radius:50%;
border-color:orange;
border-style:solid;
border-width:0px;
box-sizing:border-box;
}
body:hover .circle {
animation:change 1s forwards;
}
@keyframes change {
50% {
border-width:25px;
}
100% {
border-width:0;
width:50px;
height:50px;
}
}
body {
min-height:100px;
}
<span class="circle"></span>
此解决方案有一个小缺点,因为它将使元素从左上角开始而不是从中心开始增加。我们可以通过使用比例尺而不是更改宽度/高度来纠正此问题:
.circle {
display:inline-block;
width:50px;
height:50px;
border-radius:50%;
border-color:orange;
border-style:solid;
border-width:25px;
transform:scale(0);
box-sizing:border-box;
}
body:hover .circle {
animation:change 1s linear forwards;
}
@keyframes change {
50% {
transform:scale(1);
border-width:25px;
}
100% {
transform:scale(1);
border-width:0;
}
}
body {
min-height:100px;
}
<span class="circle"></span>
我们仍然可以简化一个简单的过渡:
.circle {
display:inline-block;
width:50px;
height:50px;
border-radius:50%;
border-color:orange;
border-style:solid;
border-width:25px;
transform:scale(0);
box-sizing:border-box;
transition:
transform 0.5s,
border-width 0.5s 0.5s;
}
body:hover .circle {
border-width:0;
transform:scale(1);
}
body {
min-height:100px;
}
<span class="circle"></span>
现在棘手的部分和小圆圈。为此,我将依靠radial-gradient
和规模。想法是在一个元素内创建带有渐变的小圆圈,并使用比例尺来创建扩展效果。
.small {
display:inline-block;
width:100px;
height:100px;
background:
/*4 reds*/
radial-gradient(circle,red 50%,transparent 60%),
radial-gradient(circle,red 50%,transparent 60%),
radial-gradient(circle,red 50%,transparent 60%),
radial-gradient(circle,red 50%,transparent 60%),
/*4 oranges*/
radial-gradient(circle,orange 50%,transparent 60%),
radial-gradient(circle,orange 50%,transparent 60%),
radial-gradient(circle,orange 50%,transparent 60%),
radial-gradient(circle,orange 50%,transparent 60%);
background-size:16px 16px;
background-position:
calc(50% - 30px) calc(50% - 30px),
calc(50% + 30px) calc(50% - 30px),
calc(50% - 30px) calc(50% + 30px),
calc(50% + 30px) calc(50% + 30px),
calc(50% + 0px) calc(50% + 40px),
calc(50% + 40px) calc(50% + 0px),
calc(50% - 40px) calc(50% + 0px),
calc(50% + 0px) calc(50% - 40px);
background-repeat:no-repeat;
border-radius:50%;
}
<span class="small"></span>
我已经创建了8个圆,并通过使其偏离中心的方式放置了它们(请查看此答案以获取有关background-position
的工作方式的更多详细信息:https://stackoverflow.com/a/51734530/8620333)。您只需要根据需要调整圆圈的大小,位置和颜色即可。
这是动画:
.small {
display:inline-block;
width:100px;
height:100px;
background:
/*4 reds*/
radial-gradient(circle,red 50%,transparent 60%),
radial-gradient(circle,red 50%,transparent 60%),
radial-gradient(circle,red 50%,transparent 60%),
radial-gradient(circle,red 50%,transparent 60%),
/*4 oranges*/
radial-gradient(circle,orange 50%,transparent 60%),
radial-gradient(circle,orange 50%,transparent 60%),
radial-gradient(circle,orange 50%,transparent 60%),
radial-gradient(circle,orange 50%,transparent 60%);
background-size:16px 16px;
background-position:
calc(50% - 30px) calc(50% - 30px),
calc(50% + 30px) calc(50% - 30px),
calc(50% - 30px) calc(50% + 30px),
calc(50% + 30px) calc(50% + 30px),
calc(50% + 0px) calc(50% + 40px),
calc(50% + 40px) calc(50% + 0px),
calc(50% - 40px) calc(50% + 0px),
calc(50% + 0px) calc(50% - 40px);
background-repeat:no-repeat;
border-radius:50%;
transform:scale(0);
transition:transform 0.5s,opacity 0.4s 0.4s;
}
body {
min-height:200px;
}
body:hover .small {
transform:scale(1);
opacity:0;
}
<span class="small"></span>
如果您想要更精确的动画,还可以考虑通过减少background-size
来减少圆圈。
.small {
display:inline-block;
width:100px;
height:100px;
background:
/*4 reds*/
radial-gradient(circle,red 50%,transparent 60%),
radial-gradient(circle,red 50%,transparent 60%),
radial-gradient(circle,red 50%,transparent 60%),
radial-gradient(circle,red 50%,transparent 60%),
/*4 oranges*/
radial-gradient(circle,orange 50%,transparent 60%),
radial-gradient(circle,orange 50%,transparent 60%),
radial-gradient(circle,orange 50%,transparent 60%),
radial-gradient(circle,orange 50%,transparent 60%);
background-size:16px 16px; /*at least 2x7px */
background-position:
calc(50% - 30px) calc(50% - 30px),
calc(50% + 30px) calc(50% - 30px),
calc(50% - 30px) calc(50% + 30px),
calc(50% + 30px) calc(50% + 30px),
calc(50% + 0px) calc(50% + 40px),
calc(50% + 40px) calc(50% + 0px),
calc(50% - 40px) calc(50% + 0px),
calc(50% + 0px) calc(50% - 40px);
background-repeat:no-repeat;
border-radius:50%;
transform:scale(0);
transition:transform 0.5s,opacity 0.4s 0.4s,background-size 0.5s 0.4s;
}
body {
min-height:200px;
}
body:hover .small {
transform:scale(1);
opacity:0;
background-size:0 0;
}
<span class="small"></span>
现在,您只需更改某些值即可对其他小圆圈执行相同的操作。
.magic {
display:inline-block;
margin:50px;
position:relative;
}
.magic i{
color:orange;
filter:grayscale(100%);
position:relative;
}
.magic:hover i{
animation:change 1s forwards;
}
@keyframes change{
50% {
transform:scale(0);
filter:grayscale(100%);
}
51% {
filter:grayscale(0%);
}
100% {
transform:scale(1);
filter:grayscale(0%);
}
}
/**/
.magic:before {
content:"";
position:absolute;
top:calc(50% - 45px);
left:calc(50% - 45px);
width:90px;
height:90px;
border-radius:50%;
border-color:orange;
border-style:solid;
border-width:45px;
transform:scale(0);
box-sizing:border-box;
}
.magic:hover::before {
transition:
transform 0.5s,
border-width 0.5s 0.5s;
border-width:0;
transform:scale(1);
}
/**/
.magic::after {
content:"";
position:absolute;
width:160px;
height:160px;
left:calc(50% - 80px);
top:calc(50% - 80px);
background:
/*4 reds*/
radial-gradient(circle,red 50%,transparent 60%),
radial-gradient(circle,red 50%,transparent 60%),
radial-gradient(circle,red 50%,transparent 60%),
radial-gradient(circle,red 50%,transparent 60%),
/*4 oranges*/
radial-gradient(circle,orange 50%,transparent 60%),
radial-gradient(circle,orange 50%,transparent 60%),
radial-gradient(circle,orange 50%,transparent 60%),
radial-gradient(circle,orange 50%,transparent 60%);
background-size:16px 16px;
background-position:
calc(50% - 50px) calc(50% - 50px),
calc(50% + 50px) calc(50% - 50px),
calc(50% - 50px) calc(50% + 50px),
calc(50% + 50px) calc(50% + 50px),
calc(50% + 0px) calc(50% + 70px),
calc(50% + 70px) calc(50% + 0px),
calc(50% - 70px) calc(50% + 0px),
calc(50% + 0px) calc(50% - 70px);
background-repeat:no-repeat;
border-radius:50%;
transform:scale(0);
}
.magic:hover:after {
transform:scale(1);
opacity:0;
background-size:0 0;
transition:
transform 0.5s 0.5s,
opacity 0.4s 0.9s,
background-size 0.5s 0.9s;
}
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css">
<span class="magic">
<i class="fas fa-star fa-5x"></i>
</span>
<span class="magic">
<i class="fas fa-user fa-5x"></i>
</span>
就像我说的那样,它并不完美,但是非常接近您想要的内容,只需要较少的元素和所需的细节,因此您可以轻松地调整不同的值。使用任何图标也很容易,因为您只需在图标上添加包装即可。
为了简单起见,我没有添加小圆圈,但是我们可以考虑使用另一个伪元素并轻松添加它们:
.magic {
display:inline-block;
margin:50px;
position:relative;
}
.magic i{
color:orange;
filter:grayscale(100%);
}
.magic:hover i{
animation:change 1s forwards;
}
@keyframes change{
50% {
transform:scale(0);
filter:grayscale(100%);
}
51% {
filter:grayscale(0%);
}
100% {
transform:scale(1);
filter:grayscale(0%);
}
}
/**/
.magic:before {
content:"";
position:absolute;
top:calc(50% - 45px);
left:calc(50% - 45px);
width:90px;
height:90px;
border-radius:50%;
border-color:orange;
border-style:solid;
border-width:45px;
transform:scale(0);
box-sizing:border-box;
}
.magic:hover::before {
border-width:0;
transform:scale(1);
transition:
transform 0.5s,
border-width 0.5s 0.5s;
}
/**/
.magic::after,
.magic i::after{
content:"";
position:absolute;
width:160px;
height:160px;
left:calc(50% - 80px);
top:calc(50% - 80px);
background:
/*4 reds*/
radial-gradient(circle,red 50%,transparent 60%),
radial-gradient(circle,red 50%,transparent 60%),
radial-gradient(circle,red 50%,transparent 60%),
radial-gradient(circle,red 50%,transparent 60%),
/*4 oranges*/
radial-gradient(circle,orange 50%,transparent 60%),
radial-gradient(circle,orange 50%,transparent 60%),
radial-gradient(circle,orange 50%,transparent 60%),
radial-gradient(circle,orange 50%,transparent 60%);
background-size:16px 16px;
background-position:
calc(50% - 50px) calc(50% - 50px),
calc(50% + 50px) calc(50% - 50px),
calc(50% - 50px) calc(50% + 50px),
calc(50% + 50px) calc(50% + 50px),
calc(50% + 0px) calc(50% + 70px),
calc(50% + 70px) calc(50% + 0px),
calc(50% - 70px) calc(50% + 0px),
calc(50% + 0px) calc(50% - 70px);
background-repeat:no-repeat;
border-radius:50%;
transform:scale(0);
}
.magic i::after {
background-size:10px 10px;
transform:rotate(10deg) scale(0);
}
.magic:hover:after {
transform:scale(1);
opacity:0;
background-size:0 0;
transition:transform 0.5s 0.5s,opacity 0.4s 0.9s,background-size 0.5s 0.9s;
}
.magic:hover i:after {
transform:rotate(10deg) scale(1);
opacity:0;
background-size:0 0;
transition:transform 0.5s 0.5s,opacity 0.4s 0.9s,background-size 0.5s 0.9s;
}
/**/
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css">
<span class="magic">
<i class="fas fa-star fa-5x"></i>
</span>
<span class="magic">
<i class="fas fa-user fa-5x"></i>
</span>
更新
这是对代码的改进,其中考虑了一些CSS变量,并使用了更多的可伸缩单元来轻松控制尺寸:
.magic {
display:inline-block;
margin:50px;
position:relative;
--r:45px;
}
.magic i{
color:orange;
filter:grayscale(100%);
}
.magic:hover i{
animation:change 1s forwards;
}
@keyframes change{
50% {
transform:scale(0);
filter:grayscale(100%);
}
51% {
filter:grayscale(0%);
}
100% {
transform:scale(1);
filter:grayscale(0%);
}
}
/**/
.magic:before {
content:"";
position:absolute;
top:calc(50% - var(--r));
left:calc(50% - var(--r));
width:calc(2*var(--r));
height:calc(2*var(--r));
border-radius:50%;
border:solid orange var(--r);
transform:scale(0);
box-sizing:border-box;
}
.magic:hover::before {
border-width:0;
transform:scale(1);
transition:
transform 0.5s,
border-width 0.5s 0.5s;
}
/**/
.magic::after,
.magic i::after{
content:"";
position:absolute;
width: calc(4*var(--r));
height:calc(4*var(--r));
left:calc(50% - 2*var(--r));
top: calc(50% - 2*var(--r));
--c1:radial-gradient(circle,red 50% ,transparent 60%);
--c2:radial-gradient(circle,orange 50%,transparent 60%);
background:
/*4 reds*/
var(--c1),var(--c1),var(--c1),var(--c1),
/*4 oranges*/
var(--c2),var(--c2),var(--c2),var(--c2);
background-size:calc(var(--r)/3) calc(var(--r)/3);
background-position:
calc(50% - var(--r)) calc(50% - var(--r)),
calc(50% + var(--r)) calc(50% - var(--r)),
calc(50% - var(--r)) calc(50% + var(--r)),
calc(50% + var(--r)) calc(50% + var(--r)),
calc(50% + 0px) calc(50% + var(--r)*1.414),
calc(50% + var(--r)*1.414) calc(50% + 0px),
calc(50% - var(--r)*1.414) calc(50% + 0px),
calc(50% + 0px) calc(50% - var(--r)*1.414);
background-repeat:no-repeat;
transform:scale(0);
}
.magic i::after {
background-size:calc(var(--r)/5) calc(var(--r)/5);
transform:rotate(55deg) scale(0);
}
.magic:hover:after {
transform:scale(1);
opacity:0;
background-size:0 0;
transition:
transform 0.5s 0.5s,
opacity 0.4s 0.9s,
background-size 0.5s 0.9s;
}
.magic:hover i:after {
transform:rotate(55deg) scale(1);
opacity:0;
background-size:0 0;
transition:
transform 0.5s 0.5s,
opacity 0.4s 0.9s,
background-size 0.5s 0.9s;
}
/**/
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css">
<span class="magic" style="--r:80px;">
<i class="fas fa-star fa-10x"></i>
</span>
<span class="magic">
<i class="fas fa-user fa-5x"></i>
</span>
<span class="magic" style="--r:20px;">
<i class="far fa-bell fa-3x"></i>
</span>
基本上,变量r
将定义整个形状的半径,您可以根据图标的大小轻松地进行更改。