uni-app 小宠物 - 会说话的小鸟

在 template 中

html 复制代码
<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 中

css 复制代码
.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;
    }
  }
}

完整源码

javascript 复制代码
<!-- 会说话的小鸟 -->
<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>

参考:【会说话的小鸟】给你的微信小程序加一个宠物吧

相关推荐
谢道韫6663 分钟前
今日总结 2024-12-27
开发语言·前端·javascript
xfxTab12 分钟前
uniapp中Nvue白屏问题 ReferenceError: require is not defined
uni-app
嘤嘤怪呆呆狗13 分钟前
【插件】vscode Todo Tree 简介和使用方法
前端·ide·vue.js·vscode·编辑器
ᥬ 小月亮26 分钟前
Js前端模块化规范及其产品
开发语言·前端·javascript
码小瑞41 分钟前
某些iphone手机录音获取流stream延迟问题 以及 录音一次第二次不录音问题
前端·javascript·vue.js
weixin_18943 分钟前
‌Vite和Webpack区别 及 优劣势
前端·webpack·vue·vite
半吊子伯爵44 分钟前
开发过程优化·自定义鼠标右键菜单
前端·javascript·自定义鼠标右键菜单
xcLeigh1 小时前
HTML5实现好看的喜庆圣诞节网站源码
前端·html·html5
Tirzano1 小时前
vue3 ts 简单动态表单 和表格
前端·javascript·vue.js
杰~JIE1 小时前
前端工程化概述(初版)
前端·自动化·工程化·前端工程化·sop