更新记录

1.0.1(2025-05-15) 下载此版本

  • 优化:提高动画性能,减少内存占用
  • 优化:改进贴边交互体验,使拖动更加丝滑
  • 修复:修复在某些设备上音频播放问题
  • 修复:修复在小程序环境下的兼容性问题
  • 新增:增加 performanceMode 配置项,支持 'high', 'medium', 'low' 三种性能模式
  • 新增:增加连击检测和特效显示
  • 文档:完善使用文档,增小程序音频限制说明

平台兼容性

Vue2 Vue3
App 快应用 微信小程序 支付宝小程序 百度小程序 字节小程序 QQ小程序
HBuilderX 3.1.0 app-vue app-nvue
钉钉小程序 快手小程序 飞书小程序 京东小程序 鸿蒙元服务
×
H5-Safari Android Browser 微信浏览器(Android) QQ浏览器(Android) Chrome IE Edge Firefox PC-Safari

gp-muyu 木鱼组件

功德+999

快!给你的 App、小程序、H5应用集成一个木鱼组件吧!

介绍

gp-muyu 是一个功能丰富、高度可定制的木鱼组件,适用于 uni-app 多端开发。支持 H5、App 和小程序平台,提供丰富的自定义配置选项和多种动画效果。点击木鱼积累功德,同时伴随精美动画和音效(可配置)。

特性

  • 🚀 多端适配:支持 H5、App 和微信小程序等多个平台
  • 🎨 高度可定制:提供丰富的样式和行为配置选项
  • 🔄 仿生贴边设计:类似于悬浮球,贴边后不影响页面内其他功能
  • 🖼️ 矢量 SVG 图标:使用 SVG 实现木鱼图标,无需额外图片资源,不失真
  • 📱 性能优化:采用帧动画优化,保证高性能
  • 🎵 音效支持:点击时发出木鱼敲击声(可配置)
  • 🌈 主题支持:内置浅色和深色两种主题
  • 🔌 完整 API:包含完善的控制方法和事件回调

安装方式

uni_modules 安装

  1. 在 uni-app 插件市场页面点击右上角【使用 HBuilderX 导入插件】,或者【下载插件 ZIP】
  2. 在 HBuilderX 中的项目管理器选择项目,右键选择导入插件,选择下载的 zip 包
  3. 如果您通过 ZIP 下载,解压后将整个 gp-muyu 目录复制到您项目下的 uni_modules 目录中

基本用法

在 Vue 3 + TypeScript 中使用

<template>
  <view class="container">
    <!-- 页面其他内容 -->
    <gp-muyu @click="onMuyuClick" />
  </view>
</template>

<script setup lang="ts">
import { ref } from 'vue';

// 功德计数
const meritCount = ref<number>(0);

// 点击木鱼事件处理
const onMuyuClick = (payload: { hitCount: number, timestamp: number }): void => {
  console.log('点击木鱼', payload);
  meritCount.value++;
};
</script>

使用配置项

<template>
  <view class="container">
    <gp-muyu
      :size="60"
      theme="dark"
      text-content="功德+1"
      position="right"
      :random-position="true"
      :random-color="false"
      :text-color="textColor"
      :animation-duration="2000"
      :initial-pos-y="300"
      :play-audio="playAudio"
      :performance-mode="performanceMode"
      @click="onMuyuClick"
    />
  </view>
</template>

<script setup lang="ts">
import { ref } from 'vue';

// 配置项
const textColor = ref<string>('#FF6347');
const playAudio = ref<boolean>(true);
const performanceMode = ref<'high' | 'medium' | 'low'>('high');

// 点击木鱼事件处理
const onMuyuClick = (payload: { hitCount: number, timestamp: number }): void => {
  console.log('点击木鱼', payload);
};
</script>

配置项说明

参数 类型 默认值 说明
show Boolean true 是否显示木鱼
size Number 40 木鱼图标大小 (20-200之间)
theme String 'light' 主题颜色,可选值为 'light' 或 'dark'
textContent String '功德+1' 点击木鱼后显示的文字
position String 'right' 木鱼初始位置,可选值为 'left' 或 'right'
randomPosition Boolean true 文字是否全屏随机位置飘动
initialPosY Number 200 初始Y轴位置(距离顶部的像素值)
performanceMode String 'high' 动画性能模式:'high', 'medium', 'low'
randomColor Boolean false 是否启用随机颜色
textColor String '' 自定义文字颜色(随机颜色关闭时生效)
colorList String '#FF6347,#FFA500,#FFD700,#32CD32,#1E90FF,#9370DB,#FF69B4' 随机颜色列表,用逗号分隔
animationDuration Number 2000 文字动画持续时间(毫秒)
playAudio Boolean false 是否播放音频

事件

事件名 说明 返回参数
@click 点击木鱼时触发 { hitCount: number, timestamp: number }

微信小程序音频限制说明

由于微信小程序的限制,小程序环境下不支持直接播放本地音频文件。组件内部已经做了平台判断,在小程序环境下会自动禁用音频播放功能。

如果您需要在微信小程序中实现敲击音效,可以通过以下方式:

  1. 监听木鱼组件的 @click 事件
  2. 在事件处理函数中使用微信小程序的音频 API 播放网络音频

微信小程序中实现音频播放示例

<template>
  <view class="container">
    <gp-muyu @click="onMuyuClick" />
  </view>
</template>

<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount } from 'vue';

// 音频上下文
let audioContext: any = null;

// 初始化音频
onMounted(() => {
  // #ifdef MP-WEIXIN
  // 在微信小程序中使用网络音频
  audioContext = wx.createInnerAudioContext();
  audioContext.src = 'https://example.com/muyu.mp3'; // 替换为您的网络音频地址
  audioContext.autoplay = false;
  // #endif
});

// 点击木鱼事件处理
const onMuyuClick = (): void => {
  // #ifdef MP-WEIXIN
  // 在微信小程序中播放网络音频
  if (audioContext) {
    audioContext.stop();
    audioContext.play();
  }
  // #endif
};

// 组件销毁前释放资源
onBeforeUnmount(() => {
  // #ifdef MP-WEIXIN
  if (audioContext) {
    audioContext.destroy();
  }
  // #endif
});
</script>

高级用法

连击效果

组件内部实现了连击检测,当快速点击木鱼时,会显示连击次数和特殊效果:

<template>
  <view class="container">
    <gp-muyu
      text-content="功德+"
      :performance-mode="'high'"
      @click="onMuyuClick"
    />
  </view>
</template>

<script setup lang="ts">
import { ref } from 'vue';

// 功德计数
const meritCount = ref<number>(0);

// 点击木鱼事件处理
const onMuyuClick = (payload: { hitCount: number, timestamp: number }): void => {
  // hitCount 是连击次数,可以用来显示特殊效果
  if (payload.hitCount > 5) {
    console.log(`连击 ${payload.hitCount} 次!`);
  }
  meritCount.value++;
};
</script>

自定义颜色和动画

<template>
  <view class="container">
    <gp-muyu
      :random-color="true"
      :color-list="'#FF0000,#00FF00,#0000FF,#FFFF00,#FF00FF'"
      :animation-duration="3000"
      @click="onMuyuClick"
    />
  </view>
</template>

<script setup lang="ts">
const onMuyuClick = (): void => {
  console.log('点击木鱼');
};
</script>

完整示例

以下是一个完整的示例,展示了如何使用木鱼组件的各种功能:

<template>
  <view class="muyu-page" :class="{ 'theme-dark': muyuTheme === 'dark' }">
    <view class="header">
      <text class="title">木鱼组件示例</text>
    </view>

    <view class="content">
      <view class="section">
        <view class="section-title">配置项</view>
        <view class="section-content config-section">
          <!-- 大小设置 -->
          <view class="config-item">
            <text class="config-label">大小:</text>
            <slider
              class="config-slider"
              min="20"
              max="120"
              step="10"
              :value="muyuSize"
              show-value
              @change="onSizeChange"
            />
          </view>

          <!-- 主题设置 -->
          <view class="config-item">
            <text class="config-label">主题:</text>
            <view class="theme-selector">
              <view
                class="theme-option light"
                :class="{ active: muyuTheme === 'light' }"
                @click="muyuTheme = 'light'"
              >
                <text>浅色</text>
              </view>
              <view
                class="theme-option dark"
                :class="{ active: muyuTheme === 'dark' }"
                @click="muyuTheme = 'dark'"
              >
                <text>深色</text>
              </view>
            </view>
          </view>

          <!-- 随机位置 -->
          <view class="config-item">
            <text class="config-label">随机飘动:</text>
            <view class="config-description">
              <switch
                :checked="randomPosition"
                @change="onRandomChange"
                :color="muyuTheme === 'light' ? '#8B4513' : '#A0522D'"
              />
              <text class="config-desc-text">{{ randomPosition ? '全屏随机位置' : '木鱼位置上方' }}</text>
            </view>
          </view>

          <!-- 播放音频 -->
          <view class="config-item">
            <text class="config-label">播放音效:</text>
            <view class="config-description">
              <switch
                :checked="playAudio"
                @change="(e) => playAudio = e.detail.value"
                :color="muyuTheme === 'light' ? '#8B4513' : '#A0522D'"
              />
              <text class="config-desc-text">{{ playAudio ? '开启音效' : '关闭音效' }}</text>
            </view>
          </view>
        </view>
      </view>

      <view class="section">
        <view class="section-title">功德计数</view>
        <view class="section-content merit-counter">
          <text class="merit-count">{{ meritCount }}</text>
          <text class="merit-label">功德</text>
        </view>
      </view>
    </view>

    <!-- 木鱼组件 -->
    <gp-muyu
      :size="muyuSize"
      :theme="muyuTheme"
      :text-content="muyuText"
      :position="muyuPosition"
      :random-position="randomPosition"
      :play-audio="playAudio"
      @click="onMuyuClick"
    />
  </view>
</template>

<script setup lang="ts">
import { ref } from 'vue';

// 状态定义
const muyuSize = ref<number>(60);
const muyuTheme = ref<'light' | 'dark'>('light');
const muyuText = ref<string>('功德+1');
const muyuPosition = ref<'left' | 'right'>('right');
const randomPosition = ref<boolean>(true);
const playAudio = ref<boolean>(true);
const meritCount = ref<number>(0);

// 点击木鱼事件
const onMuyuClick = (): void => {
  meritCount.value++;
};

// 大小变更
const onSizeChange = (e: any): void => {
  muyuSize.value = e.detail.value;
};

// 随机位置变更
const onRandomChange = (e: any): void => {
  randomPosition.value = e.detail.value;
};
</script>

注意事项

  1. 音频播放:

    • 组件默认不播放音频(playAudio 默认为 false)
    • H5 和 App 环境下,组件会使用 /uni_modules/gp-muyu/static/muyu.mp3 作为音效文件
    • 微信小程序环境下,由于平台限制,不支持直接播放本地音频,需要通过事件监听自行实现
  2. 性能优化:

    • 如果在低性能设备上出现卡顿,可以将 performanceMode 设置为 'medium' 或 'low'
    • 'low' 模式下会减少动画效果和同时显示的文字数量
  3. 样式覆盖:

    • 组件默认使用 z-index: 9999,如有特殊需求请在样式中覆盖
    • 可以通过自定义主题颜色来匹配您的应用风格
  4. 事件处理:

    • 点击事件会返回连击次数 hitCount 和时间戳 timestamp,可用于实现自定义逻辑

示例与效果

  1. 贴边状态:木鱼贴在屏幕边缘,只显示一个小圆点
  2. 展开状态:点击贴边后,木鱼图标完全展示
  3. 点击木鱼:播放音效(如果启用),显示自定义文字的飘动特效
  4. 连击效果:快速点击木鱼会显示连击次数和特殊动画效果

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

许可协议

MIT协议

使用中有什么不明白的地方,就向插件作者提问吧~ 我要提问