{"id":51237009,"url":"https://github.com/xun19/easy-ring","last_synced_at":"2026-06-28T21:09:39.509Z","repository":{"id":44823488,"uuid":"373510464","full_name":"xun19/easy-ring","owner":"xun19","description":"a general, versatile and cool front-end sound 🔔 component～","archived":false,"fork":false,"pushed_at":"2022-10-27T02:36:22.000Z","size":3396,"stargazers_count":13,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-19T10:43:52.171Z","etag":null,"topics":["component","front-end","js","react","ring","sound","vue"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xun19.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-06-03T13:06:54.000Z","updated_at":"2025-03-17T02:57:56.000Z","dependencies_parsed_at":"2023-01-20T16:00:37.904Z","dependency_job_id":null,"html_url":"https://github.com/xun19/easy-ring","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/xun19/easy-ring","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xun19%2Feasy-ring","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xun19%2Feasy-ring/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xun19%2Feasy-ring/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xun19%2Feasy-ring/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xun19","download_url":"https://codeload.github.com/xun19/easy-ring/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xun19%2Feasy-ring/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34903886,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-28T02:00:05.809Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["component","front-end","js","react","ring","sound","vue"],"created_at":"2026-06-28T21:09:38.668Z","updated_at":"2026-06-28T21:09:39.501Z","avatar_url":"https://github.com/xun19.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/vue-ring component---\" alt=\"vue ring component\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/style-easy---\" alt=\"easy\"\u003e\n\u003c/p\u003e\n\n## Choose Language/选择语言\n- [中文](#user-content-chinese)\n- [English](#user-content-english)\n\n\u003ca name=\"chinese\"\u003e\u003c/a\u003e\n\n## -中文文档\n\n## 介绍\n\n这是一个**使用简单、通用、酷炫**的前端铃声🔔组件～\n\n可用于铃声、消息提示音、交互音效等诸多场景。\n\n## 特点\n- 支持多种开发环境。可在Vue、React、纯js（ES6+）中使用\n- 支持多种调用风格。有Vue组件、React组件、以及js函数调用三种风格\n- 可自定义音频源\n- 支持使用简谱来自定义乐曲音效\n- 内置默认音效\n- 循环播放/单播放\n\n## 参数\n\n| 参数名 | 类型    |  必须  | 默认值 | 说明                                                         |\n| ------ | ------- | ------- | ------------------ | ------------------------------------------------------------ |\n| open   | Boolean | √ | false  | 开启组件。将其设为true是使用本组件的前提 |\n| ring   | Boolean | √ |false  | 是否开始播放音效。当设置为false时，则为关闭音效 |\n| src    | String  | × | ''    | 铃声音频文件的地址，可以是网络资源或者项目内资源。项目内资源需传入绝对路径。如果不清楚如何获取绝对路径，可参见下文《关于音效.自定义音频源》一节，这其实非常简单             |\n| loop    | Boolean | × |  true    |  是否循环播放               |\n|   defaultMusic  | String  | × |'EZIOS_FAMILY'    | 默认铃声曲目。目前可选值：'LITTLE_STAR' \\| 'TWO_TIGERS' \\| 'EZIOS_FAMILY' \\| 'CASTLE_IN_THE_SKY'               |\n|  musicText   | String  | × | ''    |     以简谱来自定义音效。详见下文《关于音效.自定义简谱音效》一节           |\n|  log   | Boolean  | × |true    | 是否打印日志               |\n|  ended   | Function  | × |function() {}   | 音频（一次）播放结束事件回调              |\n|  setRing   | Function  | √ (React) | -   | 对于React组件为必传。传入的值为使用useState Hook后，ring所对应的状态更新函数。具体可参考《使用.React组件形式》里的例子              |\n\n\n## 安装\n\n```javascript\nnpm i easy-ring\n```\n\n## 使用\n使用easy-ring只需要简单的三个操作，\n- ① 开启组件。\n- ② 播放音效。可以让组件开始响起。\n- ③ 暂停音效。可以让组件安静下来。\n\n不同风格的使用方式基本都遵循这三个操作，只是在使用细节上有一些差异。\n\n### 1）Vue组件形式\n当作一般的Vue组件引入、使用即可。主要通过open、ring参数进行控制。\n\n- ① 开启组件：将open参数设置为true。\n***PS：这一步需要放到一个交互（比如：按钮点击）里进行触发，这是为了规避目前浏览器的限制。详细可参见下文 《关于open参数以及浏览器限制的解释》一章***\n- ② 播放音效：将ring参数设置为true\n- ③ 暂停音效：将ring参数设置为false\n\n根据自己的需求和想要的效果，自行决定何时播放、暂停音效，只需在对应的逻辑代码下控制ring参数值的更新即可\n\n这里分别提供了Vue2、Vue3的例子进行参考：\n\n#### Vue2的写法\n\n```javascript\n\u003ctemplate\u003e\n    \u003ceasy-ring\n        :open=\"open\"\n        :ring.sync=\"ring\" // 注意：这里需要使用双向绑定 \n        :src=\"yourAudio\"\n    /\u003e\n\u003c/template\u003e\n\n\u003cscript\u003e\nimport { EasyRingVueComponent as EasyRing } from 'easy-ring'\nimport yourAudio from '@/assets/yourAudio.wav'\nimport msg from 'msg'\n\nexport default {\n    components: {\n        EasyRing\n    }\n    data() {\n        return {\n            open: false,\n            ring: false\n        }\n    },\n    methods: {\n        openComponent() {\n            if (confirm('我们需要您同意开启声音')) {\n                this.open = true // ① 开启组件\n            }\n        }\n    },\n    mounted() {\n        this.openComponent()\n\n        msg.listening()\n\n        msg.onReceived(() =\u003e {\n            this.ring = true // ② 播放音效\n        })\n\n        msg.onRead(() =\u003e {\n            this.ring = false // ③ 暂停音效\n        })\n    }\n}\n\u003c/script\u003e\n```\n#### Vue3的写法\n```javascript\n\u003ctemplate\u003e\n    \u003ceasy-ring\n        :open=\"open\"\n        v-model:ring=\"ring\" // 注意：这里需要使用双向绑定 \n        :src=\"yourAudio\"\n    /\u003e\n\u003c/template\u003e\n\n\u003cscript setup\u003e\nimport { ref } from 'vue'\nimport { EasyRingVueComponent as EasyRing } from 'easy-ring'\nimport yourAudio from '@/assets/yourAudio.wav'\nimport msg from 'msg'\n\nconst open = ref(false)\nconst ring = ref(false)\nconst openComponent = () =\u003e {\n    if (confirm('我们需要您同意开启声音')) {\n        open.value = true // ① 开启组件\n    }\n}\n\nopenComponent()\nmsg.listening()\nmsg.onReceived(() =\u003e {\n    ring.value = true // ② 播放音效\n})\n\nmsg.onRead(() =\u003e {\n    ring.value = false // ③ 暂停音效\n})\n\n\u003c/script\u003e\n```\nVue2 DEMO项目地址：https://github.com/xun19/easy-ring/tree/master/easy-ring-demo-vue2\nVue3 DEMO项目地址：https://github.com/xun19/easy-ring/tree/master/easy-ring-demo-vue3\n\n### 2）React组件形式\n当作一般的React组件引入、使用即可。主要通过open、ring参数进行控制。\n\n- ① 开启组件：将open参数设置为true。\n***PS：这一步需要放到一个交互（比如：按钮点击）里进行触发，这是为了规避目前浏览器的限制。详细可参见下文 《关于open参数以及浏览器限制的解释》一章***\n- ② 播放音效：将ring参数设置为true\n- ③ 暂停音效：将ring参数设置为false\n\n根据自己的需求和想要的效果，自行决定何时播放、暂停音效，只需在对应的逻辑代码下控制ring参数值的更新即可\n\nPS: 另外，不要忘记传入一个setRing参数，它实际就是ring参数所对应的状态更新函数，easy-ring将用它来做一些状态自动更新的操作。这将让easy-ring使用起来更傻瓜、更自动化。\n\n这里提供了一个可供参考的例子：\n\n```javascript\nimport { useState, useEffect } from 'react'\nimport { EasyRingReactComponent as EasyRing } from 'easy-ring'\nimport msg from 'msg'\n\nexport default Demo = () =\u003e {\n    const [open, setOpen] = useState(false)\n    const [ring, setRing] = useState(false)\n\n    const getMsg = () =\u003e {\n        msg.listening()\n        msg.onReceived(() =\u003e {\n            setRing(true) // ② 播放音效\n        })\n\n        msg.onRead(() =\u003e {\n            setRing(false) // ③ 暂停音效\n        })\n    }\n    const openComponent = () =\u003e {\n        if (confirm('我们需要您同意开启声音')) {\n            setOpen(true) // ① 开启组件\n        }\n    }\n\n    useEffect(() =\u003e {\n        this.openComponent()\n        this.getMsg()\n    }, [])\n\n    return (\n        \u003cdiv\u003e\n          \u003cEasyRing \n            open={this.state.open} \n            ring={this.state.ring}\n            setRing={setRing} //  注意：请记得传入这个参数\n          \u003e\u003c/EasyRing\u003e\n        \u003c/div\u003e\n    )\n}\n```\nDEMO项目地址：https://github.com/xun19/easy-ring/tree/master/easy-ring-demo-react\n### 3）js函数调用的形式\neasy-ring提供了一个CommonEasyRing类，该类的实例有4个方法：open( )、ring( )、stop( )、close( )，分别用于开启组件、播放音效、暂停音效、关闭组件。\n\n- ① 开启组件：open( )\n***PS：这一步需要放到一个交互（比如：按钮点击）里进行触发，这是为了规避目前浏览器的限制。详细可参见下文 《关于open参数以及浏览器限制的解释》一章***\n- ② 播放音效：ring( )\n- ③ 暂停音效：stop( )\n- ④ 关闭组件：close( )\n\n下面是一个可供参考的例子：\n\n```javascript\nconst myEasyring = new CommonEasyRing()  \n\nbutton.addEventListener('click', () =\u003e {\n    if (confirm('我们需要您同意开启声音 ｜ We need your consent to turn on sound')) {\n        myEasyring.open() // ① 开启组件\n    }\n})\n\nmsg.listening()\n\nmsg.onReceived(() =\u003e {\n    myEasyring.ring() // ② 播放音效\n})\n\nmsg.onRead(() =\u003e {\n    myEasyring.stop() // ③ 暂停音效\n})\n\nmsg.onUnmount(() =\u003e {\n    myEasyring.close() // ④ 关闭组件\n})\n```\n\n## 关于音效\n本组件有三种音效的使用方式：自定义音频源、自定义简谱音效、内置默认音效。可根据需求选择自己喜欢的方式。\n\n这三种音效的播放优先级为: 自定义音频源 \u003e 自定义简谱音效 \u003e 内置默认音效\n\n### 1）自定义音频源\n将你的音频文件地址传给组件的src参数，即可使用自定义音频源。可以是网络资源或者项目内资源。\n\n项目内资源采用的是绝对路径，因为使用相对路径容易在本地构建或者打包过程中出现问题，且作为第三方组件的easy-ring无法从你项目里的相对路径找到音频文件。\n\n获取绝对路径其实非常简单，在Vue或者React环境（可能也包括其他构建环境）中使用下列方式：\n```javascript\nimport yourAudio from '@/assets/yourAudio.wav'\n```\n此时yourAudio变量就是你音频文件的绝对路径，将这个变量传给src参数即可。\n\n### 2）自定义简谱音效\n将一串简谱的字符串传给musicText参数，即可使用自定义简谱音效。\n\n例如下面例子展示了怎么使用《小星星》的音效：\n```javascript\n    /* in Vue */\n    \u003cEasyRing\n      :open=\"open\"\n      :ring=\"ring\"\n      musicText=\"1 1 5 5 6 6 5 - 4 4 3 3 2 2 1 - 5 5 4 4 3 3 2 - 5 5 4 4 3 3 2 - 1 1 5 5 6 6 5 - 4 4 3 3 2 2 1 - - - -\"\n    /\u003e\n\n    /* in React */\n    \u003cEasyRing\n      open={this.state.open}\n      ring={this.state.ring}\n      musicText=\"1 1 5 5 6 6 5 - 4 4 3 3 2 2 1 - 5 5 4 4 3 3 2 - 5 5 4 4 3 3 2 - 1 1 5 5 6 6 5 - 4 4 3 3 2 2 1 - - - -\"\n    /\u003e\n\n    /* in JS */\n    const myEasyring = new CommonEasyRing({\n        musicText: '1 1 5 5 6 6 5 - 4 4 3 3 2 2 1 - 5 5 4 4 3 3 2 - 5 5 4 4 3 3 2 - 1 1 5 5 6 6 5 - 4 4 3 3 2 2 1 - - - -'\n    })\n```\nmusicText参数的值需要是一串字符串，里面主要由数字、\"-\"组成，并以一个空格进行间隔区分。\n| 字符 | 对应| 说明                                                         |\n| ------ | ------- | ------ |\n| .1 ~ .7  | 低音 | 注意前面的符号是\".\"  |\n| 1 ~ 7  | 中音 |   |\n| 1. ~ 7.  | 高音 |  注意前面的符号是\".\" |\n| -  | 一个停顿单位 | 停顿单位连续得越多，代表停顿时间越长。比如： \"- - -\"代表停顿三个单位 |\n\n下面是目前本组件内置的几首简谱乐曲，可用于参考：\n| 曲名 |       musicText值                                           |\n| ------ | ------- |\n| 小星星（LITTLE_STAR） | '1 1 5 5 6 6 5 - 4 4 3 3 2 2 1 - 5 5 4 4 3 3 2 - 5 5 4 4 3 3 2 - 1 1 5 5 6 6 5 - 4 4 3 3 2 2 1 - - - -' |\n| 两只老虎（TWO_TIGERS） | '1 2 3 1 - 1 2 3 1 - 3 4 5 - 3 4 5 - - 5 6 5 4 3 - 1 - 5 6 5 4 3 - 1 - 2 - .5 - 1 - - 2 - .5 - 1 - - - -' |\n| 艾吉奥之家（EZIOS_FAMILY） | '.6 - 1 - 2 - 3 - .6 - 1 - 2 - 1 - .6 - 1 - 2 - 3 - .6 - 1 - 2 - 1 - .6 - 1 - 2 - 3 - 6 - 7 - 1. - 2. - 3. - - - - - -' |\n| 天空之城（CASTLE_IN_THE_SKY） | '.6 .7 1 - - .7 1 - 3 - .7 - - - - .3 .3 .6 - - .5 .6 - 1 - .5 - - - - .3 .3 .4 - - .3 .4 - 1 - .3 - - - - 1 1 1 .7 - - .4 .4 - .7 - .7 - - - - -' |\n\n\n### 3）内置默认音效\n如果没有给src参数、musicText参数传递值的时候，组件会使用默认音效。目前的默认音效为《Ezio's Family》，这是游戏《刺客信条》的一首主题曲。\n\n你也可以通过设置defaultMusic的值来更换默认音效曲目，目前支持的可选值为：'LITTLE_STAR'、'TWO_TIGERS'、'EZIOS_FAMILY'、'CASTLE_IN_THE_SKY'。\n\n这实际上跟自定义简谱音效功能的实现使用了同一种技术（Web Audio API）。如果你有更好、更动听的旋律简谱，也欢迎在我的github或者博客里进行分享，后续会考虑将更多内置音效放到组件里。😊\n## 关于open参数以及浏览器限制的解释\n\n当前大多数浏览器不支持自动播放音频，这需要用户自己主动触发交互后才能播放。因此，本组件才会增加一个open参数，用于（提醒开发者）实现这一操作。\n\n我们需要把“将open参数设置为true”的这一控制逻辑，放在触发用户交互行为的事件回调里，例如：按钮的click事件、switch开关的change事件等。\n\n但是，你可以通过一些交互设计来淡化这一过程，从而提升用户体验。比如：\n- 在用户点击“登录”按钮时，在click回调里设置open参数为true\n- 设置一个音效开关，在change回调里设置open参数为true\n- 点击导航菜单的时候，在click回调里设置open参数为true\n- 在点击打开消息弹窗时，在click回调里设置open参数为true\n\n上面的例子不太适用于刷新页面后的情况，刷新页面情景下，个人认为较好的方式可能是：\n- 弹出一个询问“是否允许开启音效”的弹窗\n\n## 感谢\n自定义简谱音效功能的实现，要感谢张鑫旭大佬【https://www.zhangxinxu.com/wordpress/2017/06/html5-web-audio-api-js-ux-voice/ 】的启发 、以及王睿\n大佬【https://www.jianshu.com/p/4f4c8bbd9775、https://www.zhanhu56.com/h5/music_box/、https://github.com/chchlsh/MusicBox 】MusicBox组件的功能支持👍，他们的灵感和帮助让这个组件有了更多拓展性和乐趣。\n\n## 项目地址\nhttps://github.com/xun19/easy-ring\n\n如果你觉得本组件给你带来了帮助，欢迎来给个Star~ 😊 也欢迎提供宝贵意见\n\n\n\u003ca name=\"english\"\u003e\u003c/a\u003e\n## - Document in English \n\n## Introduction\nThis is a **general, versatile** and **cool** front-end sound 🔔 component~\n\nIt can be used in many scenarios such as ringtones, message sounds, interactive sounds, and so on.\n\n## Feature\n- Multiple development environments. Available in **Vue, React, VanillaJS/Native JS (ES6+)**.\n- Multiple styles for using. You can use this component as **a Vue Component , React Component, and even a JS Object**.\n- Customizable audio source.\n- Support for **using NMN（Numbered musical notation） to customize song sounds.**\n- Built-in default sound effects.\n- Loop and non-loop playing.\n\n## params\n\n\n| name | type    | required | default | remark                                                         |\n| ------ | ------- | ------ | ------------------ | ------------------------------------------------------------ |\n| open   | Boolean | √ | false  | Open the component. Setting it to 'true' is a prerequisite for using this component. |\n| ring   | Boolean | √ |false  | Whether to start playing the sound effect. When set to 'false', the sound effect will turn off. |\n| src    | String  | × | ''    |  The src of the audio file, which can be a network resource or an intra-project resource. Resources in the project need provide a absolute path. If you are not sure how to get the absolute path, please read the section \"About Sound Effects - Custom Audio Source\".You will find that it's very easy.             |\n| loop    | Boolean | × |  true    |  Whether to loop or not.               |\n|   defaultMusic  | String  | × |'EZIOS_FAMILY'    | The default sound effect which you can use  directly. Currently an optional value：'LITTLE_STAR' \\| 'TWO_TIGERS' \\| 'EZIOS_FAMILY' \\| 'CASTLE_IN_THE_SKY'               |\n|  musicText   | String  | × | ''    |     Customize the sound effects with useing a NMN（Numbered musical notation）string. Read the section \"About Sound Effects - Custom NMN（Numbered musical notation） Sound Effects\" for more details.          |\n|  log   | Boolean  | × |true    | Whether to output the log.               |\n|  ended   | Function  | × |function() {}   | A function which be called when the audio end playing ( This refers to the termination of each  playing round of the \\\u003caudio /\u003e, not the end of the component ).        |\n|  setRing   | Function  | √(React) | -   | Required for React components. The value is the state-updating function corresponding to the 'ring' variable after using the React Hook 'useState'. For more details, please refer to the section \"Use as a React Component\"              |\n\n\n## Installation\n```javascript\nnpm i easy-ring\n```\n## Usage\nUsing easy-ring requires only 3 easy operations,\n- ① Open the component.\n- ② Play the sound effect. Lets the component start ringing.\n- ③ Pause the sound effect. Quiets the component.\n\nDifferent styles of use basically follow these 3 operations, but there are some differences in the details of use.\n\n### 1）Use as an Vue Component\nIt can be imported and used as a general Vue component. It is mainly controlled by the 'open' and 'ring' parameters.\n\n- ① Open component: Set the 'open' to true.\n***PS: This step needs to be triggered in an interaction (e.g. button click), which is to circumvent the limitations of the current browser. See the chapter \"Explanation of the open parameter and browser limitations\" below for details.***\n- ② Play Sound Effect: Set the 'ring' to true\n\n- ③ Pause Sound Effect: Set the 'ring' to false\n\nAccording to your own needs or effects, decide when to play and pause the sound effect, and control the update of the 'ring' parameter value under the corresponding logic code\n\nHere are examples in Vue2 and Vue3 for reference:\n#### Vue2\n\n```javascript\n\u003ctemplate\u003e\n    \u003ceasy-ring\n        :open=\"open\"\n        :ring.sync=\"ring\" // Note: Bidirectional binding is required here \n        :src=\"yourAudio\"\n    /\u003e\n\u003c/template\u003e\n\n\u003cscript\u003e\nimport { EasyRingVueComponent as EasyRing } from 'easy-ring'\nimport yourAudio from '@/assets/yourAudio.wav'\nimport msg from 'msg'\n\nexport default {\n    components: {\n        EasyRing\n    }\n    data() {\n        return {\n            open: false,\n            ring: false\n        }\n    },\n    methods: {\n        openComponent() {\n            if (confirm('We need your consent to turn on sound')) {\n                this.open = true // ① Open the component.\n            }\n        }\n    },\n    mounted() {\n        this.openComponent()\n\n        msg.listening()\n\n        msg.onReceived(() =\u003e {\n            this.ring = true // ② Play Sound Effect.\n        })\n\n        msg.onRead(() =\u003e {\n            this.ring = false // ③ Pause Sound Effect.\n        })\n    }\n}\n\u003c/script\u003e\n```\n#### Vue3\n```javascript\n\u003ctemplate\u003e\n    \u003ceasy-ring\n        :open=\"open\"\n        v-model:ring=\"ring\" // Note: Bidirectional binding is required here \n        :src=\"yourAudio\"\n    /\u003e\n\u003c/template\u003e\n\n\u003cscript setup\u003e\nimport { ref } from 'vue'\nimport { EasyRingVueComponent as EasyRing } from 'easy-ring'\nimport yourAudio from '@/assets/yourAudio.wav'\nimport msg from 'msg'\n\nconst open = ref(false)\nconst ring = ref(false)\nconst openComponent = () =\u003e {\n    if (confirm('We need your consent to turn on sound')) {\n        open.value = true // ① Open the component.\n    }\n}\n\nopenComponent()\nmsg.listening()\nmsg.onReceived(() =\u003e {\n    ring.value = true // ② Play Sound Effect.\n})\n\nmsg.onRead(() =\u003e {\n    ring.value = false // ③ Pause Sound Effect.\n})\n\n\u003c/script\u003e\n```\nVue2 DEMO：https://github.com/xun19/easy-ring/tree/master/easy-ring-demo-vue2\nVue3 DEMO：https://github.com/xun19/easy-ring/tree/master/easy-ring-demo-vue3\n\n### 2）Use as a React Component\nIt can be imported and used as a general React component. It is mainly controlled by the 'open' and 'ring' parameters.\n\n- ① Open component: Set the 'open' to true.\n***PS: This step needs to be triggered in an interaction (e.g. button click), which is to circumvent the limitations of the current browser. See the chapter \"Explanation of the open parameter and browser limitations\" below for details.***\n- ② Play Sound Effect: Set the 'ring' to true\n\n- ③ Pause Sound Effect: Set the 'ring' to false\n\nAccording to your own needs or effects, decide when to play and pause the sound effect, and control the update of the ring parameter value under the corresponding logic code\n\nPS: Don't forget to provide a 'setRing' parameter, which is actually the state-updating function corresponding to the 'ring' parameter, and easy-ring will use it to do some automatic state-updating operations. This will make easy-ring more Fool-style and automated.\n\nRefer to the following example:\n\n```javascript\nimport { useState, useEffect } from 'react'\nimport { EasyRingReactComponent as EasyRing } from 'easy-ring'\nimport msg from 'msg'\n\nexport default Demo = () =\u003e {\n    const [open, setOpen] = useState(false)\n    const [ring, setRing] = useState(false)\n\n    const getMsg = () =\u003e {\n        msg.listening()\n\n        msg.onReceived(() =\u003e {\n            setRing(true) // ② Play Sound Effect.\n        })\n        msg.onRead(() =\u003e {\n            setRing(false) // ③ Pause Sound Effect.\n        })\n    }\n    const openComponent = () =\u003e {\n        if (confirm('We need your consent to turn on sound')) {\n            setOpen(true) // ① Open the component.\n        }\n    }\n\n    useEffect(() =\u003e {\n        this.openComponent()\n        this.getMsg()\n    }, [])\n\n    return (\n        \u003cdiv\u003e\n          \u003cEasyRing \n            open={this.state.open} \n            ring={this.state.ring}\n            setRing={setRing} // NOTE: Remember provide this prop.\n          \u003e\u003c/EasyRing\u003e\n        \u003c/div\u003e\n    )\n}\n```\nDEMO：https://github.com/xun19/easy-ring/tree/master/easy-ring-demo-react\n\n### 3）Use with Javascript Function\neasy-ring provides a CommonEasyRing class with 4 methods: open( ), ring( ), ,stop ( ) and close( ), which are used to open the component, play the sound effect, pause the sound effect and close the component.\n\n- ① Open component: open( )\n***PS: This step needs to be triggered in an interaction (e.g. button click), which is to circumvent the limitations of the current browser. See the chapter \"Explanation of the open parameter and browser limitations\" below for details.***\n- ② Play Sound Effect: ring( )\n\n- ③ Pause Sound Effect: stop ( )\n\n- ④ Close the component: close( )\n\nRefer to the following example:\n\n```javascript\nconst myEasyring = new CommonEasyRing()  \n\nbutton.addEventListener('click', () =\u003e {\n    if (confirm('We need your consent to turn on sound')) {\n        myEasyring.open() // ① Open the component.\n    }\n})\n\nmsg.listening()\n\nmsg.onReceived(() =\u003e {\n    myEasyring.ring() // ② Play Sound Effect.\n})\n\nmsg.onRead(() =\u003e {\n    myEasyring.stop() // ③ Pause Sound Effect.\n})\n\nmsg.onUnmount(() =\u003e {\n    myEasyring.close() // ④ Close the component.\n})\n```\n\n## About sound effects\nThis component has three ways to use sound effects: **Custom Audio Source**, **Custom NMN（Numbered musical notation） Sound Effects**, and **Built-in default sounds**. You can choose your favorite way according to your needs.\n\nThe playback priorities for these three sound effects are: **Custom Audio Source \u003e Custom NMN（Numbered musical notation） Sound Effects \u003e Built-in default sounds**\n\n### 1）Custom Audio Source\nPass your audio file address to the component's src parameter to use a custom audio source.\n\nAbsolute paths are used because using relative paths is prone to problems during local builds or packaging, and easy-ring, as a third-party component, cannot find audio files from relative paths in your project.\n\nGetting the absolute path is actually quite straightforward, using the following methods in a Vue or React environment (and possibly other build environments):\n```javascript\nimport yourAudio from '@/assets/yourAudio.wav'\n```\nAt this point, the yourAudio variable is the absolute path to your audio file, and you can pass this variable to the src parameter.\n\n### 2）Custom NMN（Numbered musical notation） Sound Effects\nPass a string of NMN（Numbered musical notation） to the musicText parameter to use a custom notation sound effect.\n\nFor example, the following example shows how to use the sound effects of Little Star:\n```javascript\n    /* in Vue */\n    \u003cEasyRing\n      :open=\"open\"\n      :ring=\"ring\"\n      musicText=\"1 1 5 5 6 6 5 - 4 4 3 3 2 2 1 - 5 5 4 4 3 3 2 - 5 5 4 4 3 3 2 - 1 1 5 5 6 6 5 - 4 4 3 3 2 2 1 - - - -\"\n    /\u003e\n\n    /* in React */\n    \u003cEasyRing\n      open={this.state.open}\n      ring={this.state.ring}\n      musicText=\"1 1 5 5 6 6 5 - 4 4 3 3 2 2 1 - 5 5 4 4 3 3 2 - 5 5 4 4 3 3 2 - 1 1 5 5 6 6 5 - 4 4 3 3 2 2 1 - - - -\"\n    /\u003e\n\n    /* in JS */\n    const myEasyring = new CommonEasyRing({\n        musicText: '1 1 5 5 6 6 5 - 4 4 3 3 2 2 1 - 5 5 4 4 3 3 2 - 5 5 4 4 3 3 2 - 1 1 5 5 6 6 5 - 4 4 3 3 2 2 1 - - - -'\n    })\n```\nThe value of the musicText parameter needs to be a string consisting mainly of numbers, \"-\", and spaced by a space.\n| character | interpretation | remark                                                         |\n| ------ | ------- | ------ |\n| .1 ~ .7  | bass | Note that the preceding symbol is \".\"  |\n| 1 ~ 7  | mediant |   |\n| 1. ~ 7.  | treble |  Note that the preceding symbol is \".\" |\n| -  | A paused unit | The more consecutive pause units there are, the longer the pause time. For example: \"---\" represents a pause of three units. |\n\nHere are a few of the notation songs currently built into this component for reference:\n| name |       musicText                                          |\n| ------ | ------- |\n| 小星星（LITTLE_STAR） | '1 1 5 5 6 6 5 - 4 4 3 3 2 2 1 - 5 5 4 4 3 3 2 - 5 5 4 4 3 3 2 - 1 1 5 5 6 6 5 - 4 4 3 3 2 2 1 - - - -' |\n| 两只老虎（TWO_TIGERS） | '1 2 3 1 - 1 2 3 1 - 3 4 5 - 3 4 5 - - 5 6 5 4 3 - 1 - 5 6 5 4 3 - 1 - 2 - .5 - 1 - - 2 - .5 - 1 - - - -' |\n| 艾吉奥之家（EZIOS_FAMILY） | '.6 - 1 - 2 - 3 - .6 - 1 - 2 - 1 - .6 - 1 - 2 - 3 - .6 - 1 - 2 - 1 - .6 - 1 - 2 - 3 - 6 - 7 - 1. - 2. - 3. - - - - - -' |\n| 天空之城（CASTLE_IN_THE_SKY） | '.6 .7 1 - - .7 1 - 3 - .7 - - - - .3 .3 .6 - - .5 .6 - 1 - .5 - - - - .3 .3 .4 - - .3 .4 - 1 - .3 - - - - 1 1 1 .7 - - .4 .4 - .7 - .7 - - - - -' |\n\n### 3）Built-in default sound effects\nIf no value is passed to the src parameter or the musicText parameter, the component will use the default sound effect. The current default sound effect is Ezio's Family, a theme song for the game Assassin's Creed.\n\nYou can also change the default sound track by setting the default Music value, the currently supported optional values are: 'LITTLE_STAR', 'TWO_TIGERS', 'EZIOS_FAMILY', 'CASTLE_IN_THE_SKY'.\n\nThis is actually the same technology used in the implementation of the custom notation sound function (the Web Audio API). If you have a better, more beautiful melodic notation, please feel free to share it on my github or blog, and consider putting more built-in sound effects into the component in the future. 😊\n## Explanation of the open parameter and browser limitations\n\nMost browsers do not currently support autoplay audio, which requires the user to actively trigger the interaction before it can be played. Therefore, the component adds an open parameter to (remind the developer) to do this.\n\nWe need to put the control logic of \"setting the open parameter to true\" in the event callback that triggers the user's interaction behavior, such as the click event of the button, the change event of the switch switch, and so on.\n\nHowever, you can play down this process with some interaction design to improve the user experience. Like what:\n- When the user clicks the \"Login\" button, set the open parameter to true in the click callback\n- Set a sound switch and set the open parameter to true in the change callback\n- When clicking on the navigation menu, set the open parameter to true in the click callback\n- When clicking to open the message pop-up, set the open parameter to true in the click callback.\n\nThe above example is not very suitable for the situation after refreshing the page, in the case of refreshing the page, I personally think that the better way may be:\n- Show a dialog asking for \"Allow me to turn on sound effects?\"\n\n## Thanks\nThe implementation of the custom sheet music effect is thanks to the inspiration of Zhang Xinxu 【https://www.zhangxinxu.com/wordpress/2017/06/html5-web-audio-api-js-ux-voice/ 】and Wang Rui\nwho supports the MusicBox component 👍 【 https://www.jianshu.com/p/4f4c8bbd9775, https://www.zhanhu56.com/h5/music_box/, https://github.com/chchlsh/MusicBox 】, and their inspiration and help make this component more expansive and fun.\n\n## github\nhttps://github.com/xun19/easy-ring\n\nIf you think this component has brought you help, welcome to star and provide valuable advice ~ 😊","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxun19%2Feasy-ring","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxun19%2Feasy-ring","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxun19%2Feasy-ring/lists"}