Effect preview
Before realizing the transition effect, you need to understand the attributes first css
. clip-path
This attribute is the core attribute to realize the transition. clip-path
The attribute can use the clipping method to create the displayable area of the element. The part inside the area is displayed, and the part outside the area is hidden. That is to say, the cropped size will not exceed the actual size, the excess will be hidden, and the actual size will be displayed.
clip-path
The attributes are as follows:
Attributes | illustrate |
---|---|
inset() | Four parameters, top right bottom left, define an inset rectangle. |
circle( ) | Define a circle, Syntax: circle(x-axis (size) at x-axis coordinate y-axis coordinate); after at is the cutting position, the first parameter is left and right, the second parameter is up and down |
ellipse(); | Define an ellipse (using two radii and a center location). Syntax: ellipse(x-axis offset y-axis offset at x-axis coordinate y-axis coordinate) |
polygon(); | Define a polygon (using an SVG fill rule and a set of vertices). Four parameters, up, right, down, left, the first parameter of each position represents the left and right offset, and the second parameter represents the up and down offset |
path(); | Defines an arbitrary shape (defined with an optional SVG fill rule and an SVG path). |
For details, please see the document: https://developer.mozilla.org/zh-CN/docs/Web/CSS/clip-path
Here is circle()
a demonstration of attributes. circle
You can define a circle (using a radius and a center position). The first parameter is the radius, which is the size, and the second parameter is the center position, which is the coordinates of the axis x、y
.
After understanding this, you can start writing the transition animation. First, define the original display element vue.svg
. When the mouse moves into vue.svg
the element, the animation after the transition will be displayed vite.svg
, and the animation after the transition (vite.svg) should cover the original animation (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%。 */
}
border animation
Another implementation of clip-path: border animation
clip-path
Only the clipped area will be displayed, and animation
the animation and dynamically modified clip-path
values can be used to achieve the visual effect of element movement. Effect diagram:
After realizing the effect, add a mask above the animation to cover the unnecessary parts to realize the border animation.
<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 implementation: border animation
Similar border animation effects can also be achieved using box-shadow.
.box{
box-show : 0px 0px 0px 0px #ccc;
}
box-show
has 5 parameters
- The first parameter: Control the left and right positions of the element shadow
- The second parameter: Control the upper and lower positions of the element shadow
- The third parameter: Controls the blurring of element shadows
- The fourth parameter: Control the size of the element shadow (zoom in & zoom out)
- The fifth parameter: set the color of the element shadow
Move the position where the shadow is displayed at an oblique angle, and hide the part beyond the red border.
<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; /* 左 */
}
}
Case source code: https://gitee.com/wang_fan_w/css-diary
If you think this article is helpful to you, please like, bookmark and forward~