JSFiddle - React, Tailwind, and code Playground
by HDL52
HTML
<div class="g-emoji">
<div class="g-foo"></div>
<div class="g-bar"></div>
<div class="g-baz"></div>
</div>
CSS
.g-emoji {
position: relative;
width: 200px;
height: 200px;
perspective: 2000px;
transform-style: preserve-3d;
font-size: 200px;
animation: rotate 2s alternate infinite ease-in-out, fall .6s alternate infinite cubic-bezier(.22, .16, .04, .99) forwards;
&::before,
&::after {
content: var(--emoji, "\1F600");
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 200px;
height: 200px;
}
&::after {
transform: translate(-50%, -50%) translateZ(-4px);
}
.g-foo,
.g-bar,
.g-baz {
position: absolute;
inset: 0;
transform-style: preserve-3d;
}
.g-foo::before,
.g-foo::after,
.g-bar::before,
.g-bar::after,
.g-baz::before,
.g-baz::after {
content: var(--emoji, "\1F600");
position: absolute;
top: 50%;
left: 50%;
width: 200px;
height: 200px;
}
.g-foo::before {
transform: translate(-50%, -50%) translateZ(-8px);
opacity: .95;
}
.g-foo::after {
transform: translate(-50%, -50%) translateZ(-12px);
opacity: .9;
}
.g-bar::before {
transform: translate(-50%, -50%) translateZ(-16px);
opacity: .85;
}
.g-bar::after {
transform: translate(-50%, -50%) translateZ(-20px);
opacity: .8;
}
.g-baz::before {
transform: translate(-50%, -50%) translateZ(-24px);
opacity: .75;
}
.g-baz::after {
transform: translate(-50%, -50%) translateZ(-28px);
opacity: .7;
}
}
@keyframes rotate {
0% {
transform: rotateY(-45deg);
}
100% {
transform: rotateY(45deg);
}
}
@keyframes fall {
0% {
scale: 1.25 0.75;
translate: 0 150px;
}
25% {
scale: 1 1;
}
100% {
scale: 1 1;
translate: 0 0;
}
}
JavaScript
// https://www.cnblogs.com/coco1s/p/17595727.html
const emoji = document.querySelectorAll('.g-emoji')[0];
let curTranslate = 0;
let lastTranslate = 0;
let diff = 0;
function aniFun() {
curTranslate = window.getComputedStyle(emoji, null).getPropertyValue("translate").split(' ')[1].slice(0, -2) - 0;
// 翻转
if (diff > 0 && (curTranslate - lastTranslate < 0)) {
emoji.style = `--emoji: "${generateRandomEmoji()}"`;
}
window.requestAnimationFrame(aniFun);
diff = curTranslate - lastTranslate;
lastTranslate = curTranslate;
}
function generateRandomEmoji() {
// 开始的 Emoji 编码
var emojiStart = 0x1F600;
var emojiStart2 = 0x1F900;
// 结束的 Emoji 编码
var emojiEnd = 0x1F64F;
var emojiEnd2 = 0x1F9FF;
var randomCode = Math.random() > 0.5 ?
Math.floor(Math.random() * (emojiEnd - emojiStart + 1)) + emojiStart :
Math.floor(Math.random() * (emojiEnd2 - emojiStart2 + 1)) + emojiStart2;
var emoji = String.fromCodePoint(randomCode);
return emoji;
}
window.requestAnimationFrame(aniFun);