先来看一下最终效果,如下图
一、大爱心的动画实现拆解
1.先使用path路径画爱心,填充色为gray,此时在浏览器上你将看到一个大大的灰心
<svg height="320" width="320" class="like">
<path class="path" d="M 160 145 c 15 -90 170 -20 0 90 m 0 -90 c -15 -90 -170 -20 0 90" fill="gray"/>
</svg>
2.给body一个好看的背景色,使用线性渐变linear-gradient
*{
margin: 0;
padding: 0;
}
body {
background-image:linear-gradient(-10deg, #7028e4 0%, #e5b2ca 100%);
width: 100vw;
height: 100vh;
}
线性渐变,具体的语法这里不讨论,因为篇幅实在太长,请移步获取更详细的信息:
3.写心的css样式,先把心居中(绝对定位)
svg.like {
position: fixed;
top:calc(50vh - 160px);
left:calc(50vw - 160px);
}
4.再给心加一个圆框黑色背景色及阴影
svg.like {
border-radius: 100%;
background-color: #212121;
cursor: pointer;
transform: scale(0.3);
}
5.点击爱心,大爱心动画拆解
-
放大爱心
-
background-color变色(黑色-紫色-品红色)
-
box-shadow由黑色变黄色
-
灰色爱心变白
点击爱心的时候,给body添加一个liked类,再次点击的时候再去掉liked类,
使用classList.toggle
<svg height="320" width="320" class="like" onclick="document.body.classList.toggle('liked')">
在body有liked类的时候才开始动画
.liked svg.like {
animation: blink 1s forwards;
}
.liked svg.like path {
fill:#fff; <!-- 白色 -->
}
@keyframes blink{
10%{
transform: scale(.42);
background-color: #8815b7 ; <!-- 紫色 -->
box-shadow: 0 0 250px #f1e794; <!-- 浅黄 -->
}
100% {
background-color: #e01f4f; <!-- 品红 -->
box-shadow: 0 0 250px #FFEB3B <!-- 柠檬黄 -->
}
}
此时的效果如下图
二、周围小圆点动画拆解
在点击爱心的时候,即body有likded的时候,这些小圆点才会出现,并从上向四周旋转。所以动画开始后:我们需要在爱心周围 每隔(360/8=45deg)放置一颗圆点,如图:
html如下:
<body>
<svg height="320" width="320" class="like" onclick="document.body.classList.toggle('liked')">
<path class="path" d="M 160 145 c 15 -90 170 -20 0 90 m 0 -90 c -15 -90 -170 -20 0 90" fill="gray"/>
</svg>
<div class="dot dot-1"></div>
<div class="dot dot-2"></div>
<div class="dot dot-3"></div>
<div class="dot dot-4"></div>
<div class="dot dot-5"></div>
<div class="dot dot-6"></div>
<div class="dot dot-7"></div>
<div class="dot dot-8"></div>
</body>
dot类画圆的样式,dot-1 ~dot-8类调整旋转位置
1.先把这8个白色圆点绝对定位到居中
div.dot {
width: 12px;
height: 12px;
border-radius: 100%;
background-color: #fff;
position: fixed;
top: calc(50vh - 6px);
left: calc(50vw - 6px);
}
2.使用伪元素,画出上面的另外两个点,细微调整一下大小,使3个点在垂直方向尽量在一条直线上。
div.dot::before {
content:'';
position: absolute;
top:-20px;
left: 2px;
width: 8px;
height: 8px;
border-radius: 100%;
background-color: #fff;
}
div.dot::after {
content:'';
position: absolute;
top:-160px;
left: 1px;
width: 11px;
height: 11px;
border-radius: 100%;
background-color: #fff;
}
此时,效果如下:
3.动画开始的时候,让3个点整体向上位移100px,并改变非伪元素的颜色为浅蓝色
.liked div.dot {
transform: translateY(-100px);
background-color: #00e5ff;
transition: all 1s;
}
最后,要让3个点渐变消失,加上 opacity:0
.liked div.dot {
opacity: 0;
}
我们发现,一开始的时候这三个点的看不见的,只有点击后才出现,所以我们给.dot设置一下z-index这个属性为-1
div.dot {
z-index: -1;
}
这时,我们又发现.dot::after由于太高,没被黑色爱心盖住,怎么办呢?
给.dot::after加上display:none,等动画开始后再让它出现
div.dot::after {
display: none;
}
body.liked div.dot:after {
display: block;
}
此时效果为下图:从无到有再到无
4.剩下的,我们只需要安排dot-2 ~dot-8 这 8个点的位置了,相隔45deg。
.liked div.dot-2 {
transform: rotate(45deg) translateY(-100px);
}
.liked div.dot-3 {
transform: rotate(90deg) translateY(-100px);
}
.liked div.dot-4 {
transform: rotate(135deg) translateY(-100px);
}
.liked div.dot-5 {
transform: rotate(180deg) translateY(-100px);
}
.liked div.dot-6 {
transform: rotate(225deg) translateY(-100px);
}
.liked div.dot-7 {
transform: rotate(270deg) translateY(-100px);
}
.liked div.dot-8 {
transform: rotate(315deg) translateY(-100px);
}
此时,我们看到的效果为:下图
我们需要让颜色opacity:0再爱心归位后再慢慢消失,所以给opacity 延迟1s后在0.5s内过渡执行。
.liked div.dot {
transition: transform 1s,opacity .5s 1s,background-color .2s .4s;
}
最终效果如下图,小圆点动画完成!
三、大爱心四周8颗爱心的动画
观察到:这8个爱心由中心向四周扩散,4个蓝色爱心在快抵达位置前变成白色并且变大了,最后这8个爱心都消失。
1.先做8个40px的爱心,让它们向像上面的点一样居中并隐藏。
html:
<svg height="40" width="40" viewBox="0 0 320 320" class="h h-1">
<path class="path" d="M 160 145 c 15 -90 170 -20 0 90 m 0 -90 c -15 -90 -170 -20 0 90"/>
</svg>
<svg height="40" width="40" viewBox="0 0 320 320" class="h h-2">
<path class="path" d="M 160 145 c 15 -90 170 -20 0 90 m 0 -90 c -15 -90 -170 -20 0 90"/>
</svg>
<svg height="40" width="40" viewBox="0 0 320 320" class="h h-3">
<path class="path" d="M 160 145 c 15 -90 170 -20 0 90 m 0 -90 c -15 -90 -170 -20 0 90"/>
</svg>
<svg height="40" width="40" viewBox="0 0 320 320" class="h h-4">
<path class="path" d="M 160 145 c 15 -90 170 -20 0 90 m 0 -90 c -15 -90 -170 -20 0 90"/>
</svg>
<svg height="40" width="40" viewBox="0 0 320 320" class="h h-5">
<path class="path" d="M 160 145 c 15 -90 170 -20 0 90 m 0 -90 c -15 -90 -170 -20 0 90"/>
</svg>
<svg height="40" width="40" viewBox="0 0 320 320" class="h h-6">
<path class="path" d="M 160 145 c 15 -90 170 -20 0 90 m 0 -90 c -15 -90 -170 -20 0 90"/>
</svg>
<svg height="40" width="40" viewBox="0 0 320 320" class="h h-7">
<path class="path" d="M 160 145 c 15 -90 170 -20 0 90 m 0 -90 c -15 -90 -170 -20 0 90"/>
</svg>
<svg height="40" width="40" viewBox="0 0 320 320" class="h h-8">
<path class="path" d="M 160 145 c 15 -90 170 -20 0 90 m 0 -90 c -15 -90 -170 -20 0 90"/>
</svg>
css
并且把偶数的爱心设置为蓝色,奇数的设置为黄色
.h {
position: fixed;
top:calc(50vh - 20px);
left: calc(50vw - 20px);
transform: scale(1);
z-index: -1;
}
.h:nth-child(odd) {
fill: skyblue;
}
.h:nth-child(even) {
fill:yellow;
}
2.动画部分:先让这8个爱心挪到自己应该的位置,根据计算调整margin
.liked .h-1{
margin-top:-200px;
}
.liked .h-5{
margin-top:200px;
}
.liked .h-3{
margin-left:200px;
}
.liked .h-7{
margin-left:-200px;
}
.liked .h-2{
margin-top:-140px;
margin-left:140px;
}
.liked .h-8{
margin-top:-140px;
margin-left:-140px;
}
.liked .h-4{
margin-top:140px;
margin-left:140px;
}
.liked .h-6{
margin-top:140px;
margin-left:-140px;
}
此时的效果为下图:
现在我们就缺给这8个爱心的加上过渡,最后让它们消失
.liked .h {
opacity: 0;
transition: margin 1.5s,opacity 0.5s 1.5s;
}
最后给偶数心加上变色和变大,再让这两个效果 延迟1.3s再执行,给margin 自己调整一下
cubic-bezier,可在浏览器里自行调整,找到理想的速度。
.liked .h {
opacity: 0;
transition: margin 1.5s cubic-bezier(0.13, 0.7, 0.32, 0.92) ,opacity 0.5s 1.5s,fill 0.2s 1.3s,transform 0.2s 1.3s;
}
.liked .h:nth-child(odd) { fill: white;
transform: scale(1.5);
}
可能,此时你需要不断调整动画里的执行时间与延迟时间,来达到你想要的理想效果。
此时,加上上面的小圆点,动画效果为下图:
三、4个蓝色爱心动画
有了上面的经验,这个便很容易了!
1.先搞4个蓝色爱心,给每个爱心110px
<svg height="110" width="110" viewBox="0 0 320 320" class="fly fly-1">
<path class="path" d="M 160 145 c 15 -90 170 -20 0 90 m 0 -90 c -15 -90 -170 -20 0 90"/>
</svg>
<svg height="110" width="110" viewBox="0 0 320 320" class="fly fly-2">
<path class="path" d="M 160 145 c 15 -90 170 -20 0 90 m 0 -90 c -15 -90 -170 -20 0 90"/>
</svg>
<svg height="110" width="110" viewBox="0 0 320 320" class="fly fly-3">
<path class="path" d="M 160 145 c 15 -90 170 -20 0 90 m 0 -90 c -15 -90 -170 -20 0 90"/>
</svg>
<svg height="110" width="110" viewBox="0 0 320 320" class="fly fly-4">
<path class="path" d="M 160 145 c 15 -90 170 -20 0 90 m 0 -90 c -15 -90 -170 -20 0 90"/>
</svg>
2.让这4个爱心居中并隐藏,给个蓝色!
.fly {
position: fixed;
top:calc(50vh - 55px);
left: calc(50vw - 55px);
fill: skyblue;
z-index: -1;
transform: scale(0.5);
}
3.先给第一个爱心做动画
.liked .fly-1 {
animation: fly-1 1s 0.1s;
}
@keyframes fly-1{
25% {
margin-top:-100px;
margin-left:100px;
transform: scale(0.9);
}
50%{
transform: scale(0.5);
}
75%{
margin-top: 100px;
margin-left: -100px;
transform: scale(0.9);
}
100%{
transform: scale(0.5);
}
}
4.同理搞定其余3个!哈哈
最终完成!完整效果及代码,请戳
更多爱心动画教程即将出炉,欢迎围观!