如何使用CSS实现一个“我裂开”动画表情

事情的起因也是偶然在群里看到有人问如何使用CSS实现一个图片锯齿状裂开然后往两边倒的动画效果,也就是下面描述的效果

想了一下,感觉也不难,就尝试一下实现这个效果,主要思路还是 伪元素+clip-path+animation,这是最后实现的效果,codepen预览

实现思路

设置左右半边

首先是实现一左一右两个半边,使用伪元素+clip-path来实现

css 复制代码
&:after,
&:before {
	content: "🙂";
	font-size: 200px;
	display: flex;
	justify-content: center;
	position: absolute;
	inset: 0;
	transform-origin: bottom center;
}

&:after {
	clip-path: polygon(0 0, 50% 0, 50% 100%, 0% 100%);
}
&:before {
	clip-path: polygon(50% 0, 50% 100%, 100% 100%, 100% 0);
}

增加裂纹

然后修改clip-path来设置左右半边的裂纹,需要注意的是左右裂纹必须吻合,所以可以考虑提取成css变量公用

css 复制代码
--crack: 40% 10%, 60% 20%, 30% 30%, 65% 40%, 40% 50%, 60% 70%, 40% 70%, 60% 80%,
	40% 90%;

&:after,
&:before {
	content: "🙂";
	font-size: 200px;
	display: flex;
	justify-content: center;
	position: absolute;
	inset: 0;
	transform-origin: bottom center;
}

&:after {
	clip-path: polygon(0 0, 50% 0, var(--crack), 50% 100%, 0% 100%);
}
&:before {
	clip-path: polygon(50% 0, var(--crack), 50% 100%, 100% 100%, 100% 0);
}

将裂纹位置的变量插入合适的位置即可实现完全一致的裂纹边缘,下图中已经可以隐约看见表情中的裂纹

设置裂开动画

为左右半边设置动画,动画的原点都为底部中间,但是左右旋转方向不同,旋转方向一开始设置的90deg,但是实际效果发现90度在动画完成后锯齿边会凸出来,所以要设置为比90大的角度。 需要设置animation-fill-mode: forwards来保证动画完成后图片保持状态,否则完成后会恢复第一帧的状态

css 复制代码
&:after {
	clip-path: polygon(0 0, 50% 0, var(--crack), 50% 100%, 0% 100%);
	animation: rotate-left 2s linear;
	animation-delay: 1s;
	animation-fill-mode: forwards;
}
&:before {
	clip-path: polygon(50% 0, var(--crack), 50% 100%, 100% 100%, 100% 0);
	animation: rotate-right 2s linear;
	animation-delay: 1s;
	animation-fill-mode: forwards;
}

@keyframes rotate-left {
	from {
		transform: rotate(0deg);
	}
	to {
		transform: rotate(-110deg);
	}
}

@keyframes rotate-right {
	from {
		transform: rotate(0deg);
	}
	to {
		transform: rotate(110deg);
	}
}

完整代码

css 复制代码
div {
	position: relative;
	width: 200px;
	height: 200px;
	border: 1px solid;
	overflow: hidden;

	--crack: 40% 10%, 60% 20%, 30% 30%, 65% 40%, 40% 50%, 60% 70%, 40% 70%, 60% 80%,
		40% 90%;

	&:after,
	&:before {
		content: "🙂";
		font-size: 200px;
		display: flex;
		justify-content: center;
		position: absolute;
		inset: 0;
		transform-origin: bottom center;
	}

	&:after {
		clip-path: polygon(0 0, 50% 0, var(--crack), 50% 100%, 0% 100%);
		animation: rotate-left 2s linear;
		animation-delay: 1s;
		animation-fill-mode: forwards;
	}
	&:before {
		clip-path: polygon(50% 0, var(--crack), 50% 100%, 100% 100%, 100% 0);
		animation: rotate-right 2s linear;
		animation-delay: 1s;
		animation-fill-mode: forwards;
	}
}

@keyframes rotate-left {
	from {
		transform: rotate(0deg);
	}
	to {
		transform: rotate(-110deg);
	}
}

@keyframes rotate-right {
	from {
		transform: rotate(0deg);
	}
	to {
		transform: rotate(110deg);
	}
}
相关推荐
golitter.1 分钟前
Ajax和axios简单用法
前端·ajax·okhttp
雷特IT21 分钟前
Uncaught TypeError: 0 is not a function的解决方法
前端·javascript
长路 ㅤ   43 分钟前
vite学习教程02、vite+vue2配置环境变量
前端·vite·环境变量·跨环境配置
亚里士多没有德7751 小时前
强制删除了windows自带的edge浏览器,重装不了怎么办【已解决】
前端·edge
micro2010141 小时前
Microsoft Edge 离线安装包制作或获取方法和下载地址分享
前端·edge
.生产的驴1 小时前
Electron Vue框架环境搭建 Vue3环境搭建
java·前端·vue.js·spring boot·后端·electron·ecmascript
awonw1 小时前
[前端][easyui]easyui select 默认值
前端·javascript·easyui
九圣残炎1 小时前
【Vue】vue-admin-template项目搭建
前端·vue.js·arcgis
柏箱2 小时前
使用JavaScript写一个网页端的四则运算器
前端·javascript·css
TU^2 小时前
C语言习题~day16
c语言·前端·算法