这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战
介绍
本期我们要用css3与svg相结合做出一个简单实用的点赞效果动画,为什么说简单呢,我们将不依赖任何js逻辑代码,为什么说实用呢,我们如果想用仅通过checkbox标签就可判断他是否点赞。那么我们先来康康效果吧:
不知道看完效果后你有思路了么,我们本案例将会从,基础结构,基础样式,红心动画,扩散圆动画来分解讲起,这就出发啦~
正文
1.基础结构
<div class="app">
<div class="heart-icon">
<input type="checkbox" />
<svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg">
<path class="heart"
d="M512 854.9c-7.7 0-14.3-2.7-19.6-8.1L213.8 578.1c-3-2.3-7-6.3-12.3-11.6-5.2-5.4-13.4-15.1-24.8-29.2-11.3-14.2-21.4-28.6-30.3-43.6-8.9-14.8-16.9-32.9-23.8-54-7-21.1-10.5-41.7-10.5-61.6 0-65.4 18.9-116.7 56.7-153.6s90-55.4 156.7-55.4c18.5 0 37.3 3.2 56.4 9.6 19.2 6.4 37.1 15 53.6 25.9 16.5 10.9 30.7 21 42.6 30.6 11.9 9.5 23.2 19.6 33.9 30.3 10.7-10.7 22.1-20.8 33.9-30.3 11.9-9.5 26.1-19.7 42.6-30.6 16.5-10.9 34.4-19.5 53.6-25.9 19.2-6.4 38-9.6 56.4-9.6 66.7 0 118.9 18.5 156.7 55.4 37.8 36.9 56.7 88.1 56.7 153.6 0 65.8-34.1 132.8-102.3 200.9l-278 267.8c-5.3 5.4-11.9 8.1-19.6 8.1z">
</path>
</svg>
<div class="heart-circle"></div>
</div>
</div>
这就是整个html结构了,其中div.app作为主容器将会绘制一个铺满全屏使元素居中的弹性盒子作为主界面。
我们可以看出div.heart-icon就是点赞的主容器了,其中包含checkbox来判断是否点中,而svg则为红心的主体,这个图形,我们可以去iconfont下载一段svg代码即可,而最后面的是div.heart-circle他将作为那八个小圆的容器。
2.基础样式
.app{
width: 100%;
height: 100vh;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
background-image: linear-gradient(
109.5deg,
rgb(245, 248, 198) 11.2%,
rgb(255, 227, 198) 100.2%
);
}
.heart-icon {
width: var(--size);
position: relative;
--skin-color: rgb(245, 98, 110); // 红色
--gray-color: rgb(197, 197, 197); // 灰色
--size: 160px; // 尺寸
--path-dasharray: 3600; // 划线长度
input[type="checkbox"] {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 99;
opacity: 0;
}
svg{
width: 100%;
position: relative;
z-index: 9;
.heart {
fill: var(--gray-color);
stroke: var(--skin-color);
stroke-dasharray: var(--path-dasharray);
stroke-width: 50px;
stroke-dashoffset: var(--path-dasharray);
stroke-linecap: round;
}
}
.heart-circle {
position: absolute;
top: 50%;
left: 50%;
z-index: 1;
width: 1px;
height: 1px;
border-radius: 50%;
background-color: transparent;
}
}
我们在这里先设置了四个变量方便统一下面的颜色和划线,这里我们还发现,checkbox已经绝对定位放在最上层而且被隐藏了,目的就是让每次点击后,下面的心和圆再执行动画。后面的就很简单了,把颜色填充边线划线长度都付给svg心形。然后八个小圆的容器heart-circle做成1px的盒子用绝对定位定在心形中间。
3.红心动画
相信写过svg动画的小伙伴早就看出来动画怎么写了,对就是控制stroke-dashoffset去绘制边,然后绘制完成后再给他填充颜色。
@keyframes run {
0% {
stroke-dashoffset: var(--path-dasharray);
}
80% {
stroke-dashoffset: 0;
fill: var(--gray-color);
}
100% {
stroke-dashoffset: 0;
fill: var(--skin-color);
}
}
当然,我们点击的时候还有个抖动大小的效果,也用css3来完成。
@keyframes touch {
0%,
50%,
100% {
transform: scale(1);
}
25% {
transform: scale(0.75);
}
75% {
transform: scale(1.25);
}
}
现在动画都写完了,那么怎么让他触发呢,对,就是通过checkbox的checked属性。
input[type="checkbox"] {
&:checked+svg{
animation: touch 0.7s forwards ease-in;
.heart{
animation: run .75s 0.1s forwards linear;
}
}
}
这样通过判定checkbox一旦激活,那么他后面的兄弟元素就可以触发动画了,是不是很简单。
4.扩散圆动画
或许刚学习css的同学会产生疑惑,我们那个盛放圆的盒子没有任何元素,只是定位到了红心中间,怎么就可以做八个圆圈呢,如果用伪类最多也是做两个啊,接下来,就看下面的表演吧:
@keyframes circle-move {
0% {
box-shadow: -10px 0 0 3px var(--gray-color), 0 -10px 0 3px var(--gray-color),
0 10px 0 3px var(--gray-color), 10px 0 0 3px var(--gray-color),
7px 7px 0 3px var(--gray-color), -7px 7px 0 3px var(--gray-color),
7px -7px 0 3px var(--gray-color), -7px -7px 0 3px var(--gray-color);
opacity: 1;
}
45% {
box-shadow: -120px 0 0 5px var(--skin-color),
0 -120px 0 5px var(--skin-color), 0 120px 0 5px var(--skin-color),
120px 0 0 5px var(--skin-color), 90px 90px 0 5px var(--skin-color),
-90px 90px 0 5px var(--skin-color), 90px -90px 0 5px var(--skin-color),
-90px -90px 0 5px var(--skin-color);
opacity: .8;
}
80% {
box-shadow: -120px 0 0 7px var(--skin-color),
0 -120px 0 7px var(--skin-color), 0 120px 0 7px var(--skin-color),
120px 0 0 7px var(--skin-color), 90px 90px 0 7px var(--skin-color),
-90px 90px 0 7px var(--skin-color), 90px -90px 0 7px var(--skin-color),
-90px -90px 0 7px var(--skin-color);
opacity: .5;
}
100% {
box-shadow: -120px 0 0 3px var(--skin-color),
0 -120px 0 3px var(--skin-color), 0 120px 0 3px var(--skin-color),
120px 0 0 3px var(--skin-color), 90px 90px 0 3px var(--skin-color),
-90px 90px 0 3px var(--skin-color), 90px -90px 0 3px var(--skin-color),
-90px -90px 0 3px var(--skin-color);
opacity: 0;
}
}
发现了么我们可以通过box-shadow的前两个参数去设置x,y轴,第三个属性要赋0,然后第四个属性就他的尺寸了,最后赋颜色,这样写到css动画里,就会出现八个圆圈,移动变色消失了,而不必再创建新的元素。
input[type="checkbox"] {
&:checked ~ .heart-circle {
animation: circle-move 1s 0.2s linear;
}
}
当然,我们也要跟红心一样,在绑定checkbox激活时间后执行动画,这样我们这个完整的案例就实现了,在线演示
结语
这个案例是我早期的一个作品,虽然看着很简单,但是里面还是有很多东西去借鉴学习的,就拿出来分解一下。css本身不难但要反复练习与更新,有时候它可以用寥寥几句就可以完成js书写很长的逻辑操作。所以也不要看不起css,它也是前端技术的核心之一,是人用语言,而不是语言用人,切记。