如何使用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);
	}
}
相关推荐
徐小夕5 分钟前
花了4个月时间,我写了一款支持AI的协同Word文档编辑器
前端·vue.js·后端
岁月向前1 小时前
小组件获取主App数据的几种方案
前端
用户47949283569151 小时前
TypeScript 和 JavaScript 的 'use strict' 有啥不同
前端·javascript·typescript
恒创科技HK1 小时前
香港服务器速度快慢受何影响?
运维·服务器·前端
bubiyoushang8882 小时前
MATLAB实现直流电法和大地电磁法的一维正演计算
前端·javascript·matlab
Mintopia2 小时前
🧠 AIGC模型的增量训练技术:Web应用如何低成本迭代能力?
前端·javascript·aigc
Mintopia2 小时前
🧩 Next.js在国内环境的登录机制设计:科学、务实、又带点“国风味”的安全艺术
前端·javascript·全栈
qq. 28040339842 小时前
react hooks
前端·javascript·react.js
LHX sir3 小时前
什么是UIOTOS?
前端·前端框架·编辑器·团队开发·个人开发·web
Gazer_S3 小时前
【前端状态管理技术解析:Redux 与 Vue 生态对比】
前端·javascript·vue.js