成果预览
在实现转场成果之前,须要先理解 css
的clip-path
属性,该属性就是实现转场的外围属性,clip-path
属性能够应用裁剪形式创立元素的可显示区域。区域内的局部显示,区域外的暗藏。也就是说裁切的大小不会超过理论的大小,超出的暗藏,理论大小内的显示。clip-path
的属性有上面几个:
| 属性 | 阐明 |
| — | — |
| inset() | 四个参数,上右下左,定义一个 inset 矩形。|
| circle() | 定义一个圆形,语法:circle(x 轴(大小)at x 轴坐标 y 轴坐标); at 后为剪切的地位,第一个参数左右,第二个参数高低 |
| ellipse(); | 定义一个椭圆(应用两个半径和一个圆心地位)。语法:ellipse(x 轴偏移 y 轴偏移 at x 轴坐标 y 轴坐标) |
| polygon(); | 定义一个多边形(应用一个 SVG 填充规定和一组顶点)。四个参数,上右下左,每个地位的第一个参数代表左右偏移,第二个参数代表高低偏移 |
| path(); | 定义一个任意形态(应用一个可选的 SVG 填充规定和一个 SVG 门路定义)。|
具体阐明请看文档:https://developer.mozilla.org/zh-CN/docs/Web/CSS/clip-path
这里以 circle()
属性做演示,circle
能够定义一个圆形(应用一个半径和一个圆心地位),第一个参数为半径也就是大小,第二个参数为圆心地位,也就是 x、y
轴的坐标。
理解了这个之后就能够开始写转场动画了,先定义原始的展现元素 vue.svg
,当鼠标移入vue.svg
元素时显示转场后的动画vite.svg
,并且转场后的动画(vite.svg)要笼罩原动画(vue.svg)。
<div class="fillAnimation" @mouseenter="touch">
<img src="../assets/vue.svg" style="width:200px;" alt="">
<!-- 转场后的动画 -->
<div :class="touchStatus ?'touch clipPathAnimation':'clipPathAnimation'">
<img src="../assets/vite.svg" style="width:200px;" alt="">
</div>
</div>
// js 局部
// 鼠标移入
const touchStatus = ref(false)
const touch = () => touchStatus.value = true
.fillAnimation{
width: 300px;
height: 200px;
border-radius: 10px;
overflow: hidden;
position: relative;
background-color: cadetblue;
display: flex;
justify-content: space-around;
align-items: center;
}
.clipPathAnimation{
width: 300px;
height: 200px;
position: absolute;
top: 0;
left: 0;
display: flex;
justify-content: space-around;
align-items: center;
background-image: linear-gradient(to right, #12c2e9 , #c471ed);
clip-path: circle(0px at 0 0px); /* 初始的时候大小为 0,不显示 */
}
/* 鼠标移入触发 */
.touch{animation: clipPathAn 2s forwards; /* forwards 放弃动画完结时的成果 */}
@keyframes clipPathAn {from { clip-path: circle(0px at 0 0px); }
to {clip-path: circle(200% at 0 200px); } /* 完结时大小变为 200%,超出理论大小的暗藏,所以这里还是显示的原大小,也就是 100%,这里变为 200% 是因为锚点在最左侧,100% 只能显示原图的一半,所以要写成 200%。*/
}
边框动画
clip-path 的另一种实现:边框动画
clip-path
只有裁剪的区域才会显示,利用 animation
动画,动静批改 clip-path
的值来实现元素挪动的视觉效果。成果示意图:
实现该成果后,在动画上方增加一个蒙版,将不须要的局部遮住即可实现边框动画。
<div class="borderLine">
<div class="borderCenter">
<div class="innerButton"> 按钮 </div>
</div>
</div>
.borderLine{
width: 150px;
height: 70px;
margin: 30px;
position: relative;
border-radius: 6px;
overflow: hidden;
/* 外部的盒子 - 遮住动画不须要的局部 */
.borderCenter{
position: absolute;
top: 2px;
left: 2px;
width: calc(100% - 4px - 12px);
height: calc(100% - 4px - 12px);
text-align: center;
border:6px solid white;
border-radius: 4px;
background-color: #fff;
z-index: 10;
.innerButton{
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: space-around;
color: #fff;
border-radius: 4px;
background-color: #15c0e9;
}
}
&::before,
&::after
{
content: "";
display: inline-block;
width: 150px;
height: 70px;
position: absolute;
background-color: #15c0e9;
animation: insetRound 3s infinite linear; /* linear 从开始到完结的速度雷同的动画 */
}
&::after{animation: insetRound 3s infinite -1.5s linear; /* insetRound 动画 继续 3s 有限循环 提前 1.5s(正数提前, 负数提早) 匀速播放 */
}
}
@keyframes insetRound {
0%,100%{clip-path: inset(0 0 96% 0); /* x 轴左上 */
}
25%{clip-path: inset(0 0 0 98%); /* x 轴左上 */
}
50%{clip-path: inset(96% 0 0 0); /* x 轴左上 */
}
75%{clip-path: inset(0 98% 0 0); /* x 轴左上 */
}
}
box-shadow 实现:边框动画
相似的边框动画成果,应用 box-shadow 也能够实现。
.box{box-show : 0px 0px 0px 0px #ccc;}
box-show
有 5 个参数
- 第一个参数:管制元素暗影的左右地位
- 第二个参数:管制元素暗影的高低地位
- 第三个参数:管制元素暗影的含糊水平
- 第四个参数:管制元素暗影的大小(放大 & 放大)
- 第五个参数:设置元素暗影的色彩
斜角度挪动暗影显示的地位,将超出红色边框的局部暗藏即可。
<div class="borderShow">
<div class="borderShowCenter"> 按钮 </div>
</div>
.borderShow{
width: 150px;
height: 70px;
margin: 30px;
position: relative;
border-radius: 6px;
overflow: hidden;
border: 1px solid red;
display: flex;
justify-content: space-around;
align-items: center;
&::before,
&::after
{
content: '';
position: absolute;
top: 2px;
left: 2px;
width: calc(100% - 4px - 12px);
height: calc(100% - 4px - 12px);
text-align: center;
border:6px solid white;
border-radius: 4px;
background-color: #fff;
animation: showRound 3s infinite linear;
}
&::after{animation: showRound 3s infinite -1.5s linear; /* insetRound 动画 继续 3s 有限循环 提前 1.5s(正数提前, 负数提早) 匀速播放 */
}
/* 外部的盒子 */
.borderShowCenter{
position: absolute;
top: 8px;
left: 8px;
width: calc(100% - 4px - 12px);
height: calc(100% - 4px - 12px);
text-align: center;
border-radius: 4px;
display: flex;
justify-content: space-around;
align-items: center;
color: #fff;
background-color: #c073ed;
z-index: 10; /* 笼罩伪元素 */
}
}
@keyframes showRound {
/* box-shadow : x 轴 y 轴 含糊 放大 色彩; */
0%,100%{box-shadow: 0px -66px 0px 0px #c073ed; /* 上 */}
25%{box-shadow: 146px 0px 0px 0px #c073ed; /* 右 */}
50%{box-shadow: 0px 66px 0px 0px #c073ed; /* 下 */}
75%{box-shadow: -146px 0px 0px 0px #c073ed; /* 左 */}
}
案例源码:https://gitee.com/wang_fan_w/css-diary
如果感觉这篇文章对你有帮忙,欢送点赞、珍藏、转发哦~