在 template 中
<view class="container">
<view class="external-shape">
<view class="face-box">
<view class="eye-box eye-left">
<view class="eyeball-box eyeball-left">
<span class="pupil-box"><span class="pupil-reflex"></span></span>
</view>
</view>
<view class="eye-box eye-right">
<view class="eyeball-box eyeball-right">
<span class="pupil-box"><span class="pupil-reflex"></span></span>
</view>
</view>
<view class="nose-box">
<view class="nostril-tip"></view>
<view class="nostril-tip"></view>
</view>
<view class="mouth-box">
<view class="upper-teeth"></view>
<view class="lower-teeth"></view>
</view>
</view>
</view>
</view>
在 style 中
.container {
$overall: #0097d9; // 整体背景
// 眼睛部分
$eyeBoxShadow: 8rpx 16rpx 10rpx rgba(0, 0, 0, 0.2); // 眼睛部分的阴影
$eyeLeftBg: linear-gradient(to bottom, #fdfdfd, #c3efea); // 左眼背景
$eyeRightBg: linear-gradient(to bottom, #fdfdfd, #e6d6f6); // 右眼背景
// 眼球部分
$eyeballLeftBg: linear-gradient(135deg, rgba(188, 248, 177, 0.7), #2fa38c 75%); // 左眼球背景
$eyeballRightBg: linear-gradient(135deg, #f1a183, #8535cd); // 右眼球背景
// 瞳孔部分
$pupilBg: #2c2f32; // 瞳孔部分的背景
$pupilBoxShadow: 0rpx 0rpx 20rpx rgba(0, 0, 0, 0.2); // 瞳孔部分的阴影
$pupilReflexBg: #ebebeb; // 瞳孔反射部分的背景
$pupilReflexBoxShadow: 20rpx 20rpx 20rpx rgba(255, 255, 255, 0.2); // 瞳孔反射部分的阴影
// 鼻子部分
$nostrilBg: rgba(0, 0, 0, 0.5); // 鼻孔的背景
$nostrilBoxShadow: 8rpx 16rpx 10rpx rgba(0, 0, 0, 0.1); // 鼻孔的阴影
// 嘴巴部分
$mouthBg: #810332; // 嘴巴背景
$mouthBorder: 50rpx solid #ffc333; // 嘴巴的边框
$mouthBoxShadow: 8rpx 16rpx 10rpx rgba(0, 0, 0, 0.2); // 嘴巴的阴影
$mouthBeforeBg: #400018; // 嘴巴内背景(在元素的内容前面插入新内容)[伪元素]
$mouthAfterBg: #dc1b50; // 嘴巴内舌头(在元素的内容之后插入新内容)[伪元素]
$upperBg: #fff; // 牙齿背景
position: fixed;
top: -70rpx;
right: -150rpx;
transform: scale(0.24);
-o-transform: scale(0.24); // Opera
-ms-transform: scale(0.24); // IE 9
-moz-transform: scale(0.24); // Firefox
-webkit-transform: scale(0.24); // Safari 和 Chrome
z-index: 9999;
.external-shape {
display: flex;
justify-content: center;
position: relative;
width: 340rpx;
height: 800rpx;
border-top-left-radius: 400rpx;
border-top-right-radius: 400rpx;
background-color: $overall;
box-shadow: 40rpx 40rpx 120rpx $overall;
transform: rotate(-50deg);
-o-transform: rotate(-50deg); // Opera
-ms-transform: rotate(-50deg); // IE 9
-moz-transform: rotate(-50deg); // Firefox
-webkit-transform: rotate(-50deg); // Safari 和 Chrome
}
.face-box {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
position: absolute;
top: 14%;
width: 75%;
height: 320rpx;
}
// 眼睛部分
.eye-box {
position: absolute;
top: -10%;
width: 130rpx;
height: 130rpx;
margin: 6rpx;
background: #fff;
transform: translateX(-50%);
-o-transform: translateX(-50%); // Opera
-ms-transform: translateX(-50%); // IE 9
-moz-transform: translateX(-50%); // Firefox
-webkit-transform: translateX(-50%); // Safari 和 Chrome
box-shadow: $eyeBoxShadow;
border-radius: 100%;
// 眼球部分
.eyeball-box {
position: absolute;
top: 25%;
left: 50%;
width: 55%;
height: 55%;
transform: translate(-50%);
-o-transform: translate(-50%); // Opera
-ms-transform: translate(-50%); // IE 9
-moz-transform: translate(-50%); // Firefox
-webkit-transform: translate(-50%); // Safari 和 Chrome
border-radius: 100%;
z-index: 100;
// 瞳孔部分
.pupil-box {
position: absolute;
top: 25%;
left: 50%;
width: 55%;
height: 55%;
background: $pupilBg;
transform: translate(-50%);
-o-transform: translate(-50%); // Opera
-ms-transform: translate(-50%); // IE 9
-moz-transform: translate(-50%); // Firefox
-webkit-transform: translate(-50%); // Safari 和 Chrome
box-shadow: $pupilBoxShadow;
border-radius: 100%;
.pupil-reflex {
position: absolute;
top: 10%;
left: 25%;
width: 14rpx;
height: 14rpx;
background: $pupilReflexBg;
transform: translate(-50%);
-o-transform: translate(-50%); // Opera
-ms-transform: translate(-50%); // IE 9
-moz-transform: translate(-50%); // Firefox
-webkit-transform: translate(-50%); // Safari 和 Chrome
box-shadow: $pupilReflexBoxShadow;
border-radius: 100%;
}
}
}
// 左眼球
.eyeball-left {
background: $eyeballLeftBg;
}
// 右眼球
.eyeball-right {
background: $eyeballRightBg;
}
}
.eye-left {
// 左眼
left: 10%;
background: $eyeLeftBg;
}
.eye-right {
// 右眼
left: 85%;
background: $eyeRightBg;
}
// 鼻子部分
.nose-box {
top: 50%;
display: flex;
justify-content: space-between;
width: 28%;
height: auto;
margin-bottom: 20rpx;
.nostril-tip {
width: 16rpx;
height: 24rpx;
background: $nostrilBg;
box-shadow: $nostrilBoxShadow;
border-radius: 40rpx;
}
}
// 嘴巴部分
.mouth-box {
display: flex;
align-items: center;
justify-content: center;
position: relative;
width: 100%;
height: 0%;
overflow: hidden;
background-color: $mouthBg;
animation: mouth-animate 1.75s infinite;
border: $mouthBorder;
box-shadow: $mouthBoxShadow;
box-sizing: border-box;
border-radius: 200rpx;
// 上牙齿
.upper-teeth {
position: absolute;
top: -60rpx;
width: 340rpx;
height: 60rpx;
background-color: $upperBg;
animation: upper-teeth-animate 1.75s infinite;
border-bottom-left-radius: 20rpx;
border-bottom-right-radius: 20rpx;
z-index: 100;
}
// 下牙齿
.lower-teeth {
position: absolute;
bottom: 0;
width: 200rpx;
height: 60rpx;
background-color: $upperBg;
animation: lower-teeth-animate 1.75s infinite;
border-top-left-radius: 20rpx;
border-top-right-radius: 20rpx;
z-index: 100;
}
}
.mouth-box::before {
content: "";
position: absolute;
width: 300rpx;
height: 160rpx;
background-color: $mouthBeforeBg;
border-radius: 200rpx;
}
.mouth-box::after {
content: "";
position: absolute;
bottom: -160rpx;
width: 320rpx;
height: 160rpx;
background-color: $mouthAfterBg;
border-top-left-radius: 50%;
border-top-right-radius: 50%;
animation: mouth-after-animate 1.75s infinite;
}
// 动画部分
@keyframes upper-teeth-animate {
0%,
10%,
80%,
100% {
top: -60rpx;
}
20% {
top: 0rpx;
}
30% {
top: -40rpx;
}
40% {
top: -0rpx;
}
50% {
top: -50rpx;
}
70% {
top: 0rpx;
}
}
@keyframes lower-teeth-animate {
0%,
10%,
80%,
100% {
bottom: -60rpx;
}
20% {
bottom: 0rpx;
}
30% {
bottom: -40rpx;
}
40% {
bottom: -0rpx;
}
50% {
bottom: -50rpx;
}
70% {
bottom: 0rpx;
}
}
@keyframes mouth-animate {
0%,
10%,
100% {
width: 100%;
height: 0%;
}
15% {
width: 90%;
height: 30%;
}
20% {
width: 50%;
height: 70%;
}
25% {
width: 70%;
height: 70%;
}
30% {
width: 80%;
height: 60%;
}
35% {
width: 60%;
height: 70%;
}
40% {
width: 55%;
height: 75%;
}
45% {
width: 50%;
height: 90%;
}
50% {
width: 40%;
height: 70%;
}
55% {
width: 70%;
height: 95%;
}
60% {
width: 40%;
height: 50%;
}
65% {
width: 100%;
height: 60%;
}
70% {
width: 100%;
height: 70%;
}
75% {
width: 90%;
height: 70%;
}
80% {
width: 50%;
height: 70%;
}
85% {
width: 90%;
height: 50%;
}
85% {
width: 40%;
height: 70%;
}
90% {
width: 90%;
height: 30%;
}
95% {
width: 100%;
height: 10%;
}
}
@keyframes mouth-after-animate {
0%,
20%,
100% {
bottom: -160rpx;
}
30%,
90% {
bottom: -80rpx;
}
40% {
bottom: -90rpx;
}
50% {
bottom: -100rpx;
}
70% {
bottom: -160rpx;
}
90% {
bottom: -80rpx;
}
}
}
完整源码
<!-- 会说话的小鸟 -->
<template>
<view>
<view class="container">
<view class="external-shape">
<view class="face-box">
<view class="eye-box eye-left">
<view class="eyeball-box eyeball-left">
<span class="pupil-box"><span class="pupil-reflex"></span></span>
</view>
</view>
<view class="eye-box eye-right">
<view class="eyeball-box eyeball-right">
<span class="pupil-box"><span class="pupil-reflex"></span></span>
</view>
</view>
<view class="nose-box">
<view class="nostril-tip"></view>
<view class="nostril-tip"></view>
</view>
<view class="mouth-box">
<view class="upper-teeth"></view>
<view class="lower-teeth"></view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {};
},
onLoad() {},
methods: {}
};
</script>
<style lang="scss" scoped>
.container {
$overall: #0097d9; // 整体背景
// 眼睛部分
$eyeBoxShadow: 8rpx 16rpx 10rpx rgba(0, 0, 0, 0.2); // 眼睛部分的阴影
$eyeLeftBg: linear-gradient(to bottom, #fdfdfd, #c3efea); // 左眼背景
$eyeRightBg: linear-gradient(to bottom, #fdfdfd, #e6d6f6); // 右眼背景
// 眼球部分
$eyeballLeftBg: linear-gradient(135deg, rgba(188, 248, 177, 0.7), #2fa38c 75%); // 左眼球背景
$eyeballRightBg: linear-gradient(135deg, #f1a183, #8535cd); // 右眼球背景
// 瞳孔部分
$pupilBg: #2c2f32; // 瞳孔部分的背景
$pupilBoxShadow: 0rpx 0rpx 20rpx rgba(0, 0, 0, 0.2); // 瞳孔部分的阴影
$pupilReflexBg: #ebebeb; // 瞳孔反射部分的背景
$pupilReflexBoxShadow: 20rpx 20rpx 20rpx rgba(255, 255, 255, 0.2); // 瞳孔反射部分的阴影
// 鼻子部分
$nostrilBg: rgba(0, 0, 0, 0.5); // 鼻孔的背景
$nostrilBoxShadow: 8rpx 16rpx 10rpx rgba(0, 0, 0, 0.1); // 鼻孔的阴影
// 嘴巴部分
$mouthBg: #810332; // 嘴巴背景
$mouthBorder: 50rpx solid #ffc333; // 嘴巴的边框
$mouthBoxShadow: 8rpx 16rpx 10rpx rgba(0, 0, 0, 0.2); // 嘴巴的阴影
$mouthBeforeBg: #400018; // 嘴巴内背景(在元素的内容前面插入新内容)[伪元素]
$mouthAfterBg: #dc1b50; // 嘴巴内舌头(在元素的内容之后插入新内容)[伪元素]
$upperBg: #fff; // 牙齿背景
position: fixed;
top: -70rpx;
right: -150rpx;
transform: scale(0.24);
-o-transform: scale(0.24); // Opera
-ms-transform: scale(0.24); // IE 9
-moz-transform: scale(0.24); // Firefox
-webkit-transform: scale(0.24); // Safari 和 Chrome
z-index: 9999;
.external-shape {
display: flex;
justify-content: center;
position: relative;
width: 340rpx;
height: 800rpx;
border-top-left-radius: 400rpx;
border-top-right-radius: 400rpx;
background-color: $overall;
box-shadow: 40rpx 40rpx 120rpx $overall;
transform: rotate(-50deg);
-o-transform: rotate(-50deg); // Opera
-ms-transform: rotate(-50deg); // IE 9
-moz-transform: rotate(-50deg); // Firefox
-webkit-transform: rotate(-50deg); // Safari 和 Chrome
}
.face-box {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
position: absolute;
top: 14%;
width: 75%;
height: 320rpx;
}
// 眼睛部分
.eye-box {
position: absolute;
top: -10%;
width: 130rpx;
height: 130rpx;
margin: 6rpx;
background: #fff;
transform: translateX(-50%);
-o-transform: translateX(-50%); // Opera
-ms-transform: translateX(-50%); // IE 9
-moz-transform: translateX(-50%); // Firefox
-webkit-transform: translateX(-50%); // Safari 和 Chrome
box-shadow: $eyeBoxShadow;
border-radius: 100%;
// 眼球部分
.eyeball-box {
position: absolute;
top: 25%;
left: 50%;
width: 55%;
height: 55%;
transform: translate(-50%);
-o-transform: translate(-50%); // Opera
-ms-transform: translate(-50%); // IE 9
-moz-transform: translate(-50%); // Firefox
-webkit-transform: translate(-50%); // Safari 和 Chrome
border-radius: 100%;
z-index: 100;
// 瞳孔部分
.pupil-box {
position: absolute;
top: 25%;
left: 50%;
width: 55%;
height: 55%;
background: $pupilBg;
transform: translate(-50%);
-o-transform: translate(-50%); // Opera
-ms-transform: translate(-50%); // IE 9
-moz-transform: translate(-50%); // Firefox
-webkit-transform: translate(-50%); // Safari 和 Chrome
box-shadow: $pupilBoxShadow;
border-radius: 100%;
.pupil-reflex {
position: absolute;
top: 10%;
left: 25%;
width: 14rpx;
height: 14rpx;
background: $pupilReflexBg;
transform: translate(-50%);
-o-transform: translate(-50%); // Opera
-ms-transform: translate(-50%); // IE 9
-moz-transform: translate(-50%); // Firefox
-webkit-transform: translate(-50%); // Safari 和 Chrome
box-shadow: $pupilReflexBoxShadow;
border-radius: 100%;
}
}
}
// 左眼球
.eyeball-left {
background: $eyeballLeftBg;
}
// 右眼球
.eyeball-right {
background: $eyeballRightBg;
}
}
.eye-left {
// 左眼
left: 10%;
background: $eyeLeftBg;
}
.eye-right {
// 右眼
left: 85%;
background: $eyeRightBg;
}
// 鼻子部分
.nose-box {
top: 50%;
display: flex;
justify-content: space-between;
width: 28%;
height: auto;
margin-bottom: 20rpx;
.nostril-tip {
width: 16rpx;
height: 24rpx;
background: $nostrilBg;
box-shadow: $nostrilBoxShadow;
border-radius: 40rpx;
}
}
// 嘴巴部分
.mouth-box {
display: flex;
align-items: center;
justify-content: center;
position: relative;
width: 100%;
height: 0%;
overflow: hidden;
background-color: $mouthBg;
animation: mouth-animate 1.75s infinite;
border: $mouthBorder;
box-shadow: $mouthBoxShadow;
box-sizing: border-box;
border-radius: 200rpx;
// 上牙齿
.upper-teeth {
position: absolute;
top: -60rpx;
width: 340rpx;
height: 60rpx;
background-color: $upperBg;
animation: upper-teeth-animate 1.75s infinite;
border-bottom-left-radius: 20rpx;
border-bottom-right-radius: 20rpx;
z-index: 100;
}
// 下牙齿
.lower-teeth {
position: absolute;
bottom: 0;
width: 200rpx;
height: 60rpx;
background-color: $upperBg;
animation: lower-teeth-animate 1.75s infinite;
border-top-left-radius: 20rpx;
border-top-right-radius: 20rpx;
z-index: 100;
}
}
.mouth-box::before {
content: "";
position: absolute;
width: 300rpx;
height: 160rpx;
background-color: $mouthBeforeBg;
border-radius: 200rpx;
}
.mouth-box::after {
content: "";
position: absolute;
bottom: -160rpx;
width: 320rpx;
height: 160rpx;
background-color: $mouthAfterBg;
border-top-left-radius: 50%;
border-top-right-radius: 50%;
animation: mouth-after-animate 1.75s infinite;
}
// 动画部分
@keyframes upper-teeth-animate {
0%,
10%,
80%,
100% {
top: -60rpx;
}
20% {
top: 0rpx;
}
30% {
top: -40rpx;
}
40% {
top: -0rpx;
}
50% {
top: -50rpx;
}
70% {
top: 0rpx;
}
}
@keyframes lower-teeth-animate {
0%,
10%,
80%,
100% {
bottom: -60rpx;
}
20% {
bottom: 0rpx;
}
30% {
bottom: -40rpx;
}
40% {
bottom: -0rpx;
}
50% {
bottom: -50rpx;
}
70% {
bottom: 0rpx;
}
}
@keyframes mouth-animate {
0%,
10%,
100% {
width: 100%;
height: 0%;
}
15% {
width: 90%;
height: 30%;
}
20% {
width: 50%;
height: 70%;
}
25% {
width: 70%;
height: 70%;
}
30% {
width: 80%;
height: 60%;
}
35% {
width: 60%;
height: 70%;
}
40% {
width: 55%;
height: 75%;
}
45% {
width: 50%;
height: 90%;
}
50% {
width: 40%;
height: 70%;
}
55% {
width: 70%;
height: 95%;
}
60% {
width: 40%;
height: 50%;
}
65% {
width: 100%;
height: 60%;
}
70% {
width: 100%;
height: 70%;
}
75% {
width: 90%;
height: 70%;
}
80% {
width: 50%;
height: 70%;
}
85% {
width: 90%;
height: 50%;
}
85% {
width: 40%;
height: 70%;
}
90% {
width: 90%;
height: 30%;
}
95% {
width: 100%;
height: 10%;
}
}
@keyframes mouth-after-animate {
0%,
20%,
100% {
bottom: -160rpx;
}
30%,
90% {
bottom: -80rpx;
}
40% {
bottom: -90rpx;
}
50% {
bottom: -100rpx;
}
70% {
bottom: -160rpx;
}
90% {
bottom: -80rpx;
}
}
}
</style>
参考:【会说话的小鸟】给你的微信小程序加一个宠物吧