index.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. import './style.scss'
  2. type PLAY_STATE = 'play' | 'pause';
  3. // soundjs loader
  4. const script = document.createElement('script');
  5. script.src = 'https://cdn.bootcdn.net/ajax/libs/SoundJS/1.0.2/soundjs.min.js';
  6. script.type = 'text/javascript';
  7. // 控制按钮
  8. const musicSvgImg = '<?xml version="1.0"?><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="36px" height="36px" fill="#fff"> <path d="M 11 3 L 11 4 L 11 8 L 11 14.541016 A 4 4 0 0 0 9 14 A 4 4 0 0 0 5 18 A 4 4 0 0 0 9 22 A 4 4 0 0 0 13 18 L 13 8 L 19 8 L 19 3 L 11 3 z"/></svg>'
  9. const controlsDom = document.createElement('div');
  10. controlsDom.className = 'y-bg-music-controls';
  11. controlsDom.innerHTML = musicSvgImg
  12. type BgMusicOptions = {
  13. /** 音频文件 mp3 */
  14. src: string,
  15. /** 循环次数,默认 999 */
  16. loop?: number
  17. /** 控制按钮 */
  18. controls?: boolean
  19. }
  20. export const useBgMusic = (options: BgMusicOptions) => {
  21. if (typeof options.controls === 'undefined') {
  22. options.controls = true;
  23. }
  24. if (typeof options.loop === 'undefined') {
  25. options.loop = 999;
  26. }
  27. let musicLoadComplete = false;
  28. let musicInstance: any = null;
  29. // 动态加载音频库
  30. script.onload = () => {
  31. // 注册音频加载完成事件
  32. createjs.Sound.alternateExtensions = ['mp3'];
  33. createjs.Sound.on('fileload', () => {
  34. musicLoadComplete = true;
  35. }, window);
  36. // 注册音频
  37. createjs.Sound.registerSound(options.src, 'sound');
  38. }
  39. // 预防重复加载
  40. if (script.parentElement === null) {
  41. document.body.appendChild(script);
  42. }
  43. if (controlsDom.parentElement === null) {
  44. document.body.appendChild(controlsDom);
  45. if (options.controls) {
  46. controlsDom.classList.add('y-bg-music-controls__show');
  47. controlsDom.onclick = () => {
  48. if (getState() === 'play') {
  49. pause();
  50. } else {
  51. play();
  52. }
  53. }
  54. }
  55. }
  56. // 触摸自动播放
  57. document.addEventListener('touchend', () => {
  58. play();
  59. }, { once: true });
  60. /** 获取播放状态 */
  61. function getState():PLAY_STATE {
  62. if (!musicInstance) {
  63. return 'pause';
  64. }
  65. return musicInstance.paused ? 'pause' : 'play';
  66. }
  67. /**
  68. * 播放
  69. *
  70. * 请放到 wx.ready 回调中调用
  71. */
  72. function play() {
  73. // 存在音频实例,直接恢复播放
  74. if (musicInstance) {
  75. musicInstance.paused = false;
  76. controlsDom.classList.add('y-bg-music-controls__player');
  77. return;
  78. }
  79. // 不存在音频实例,等待音频加载完成后播放
  80. const timer = setInterval(() => {
  81. if (window.createjs && musicLoadComplete) {
  82. clearInterval(timer);
  83. musicInstance = createjs.Sound.play('sound');
  84. musicInstance.loop = options.loop;
  85. controlsDom.classList.add('y-bg-music-controls__player');
  86. }
  87. }, 300);
  88. }
  89. /**
  90. * 暂停
  91. */
  92. function pause() {
  93. musicInstance.paused = true
  94. controlsDom.classList.remove('y-bg-music-controls__player');
  95. }
  96. /**
  97. * 销毁
  98. */
  99. function destroy() {
  100. musicInstance.stop();
  101. musicInstance = null;
  102. controlsDom.classList.remove('y-bg-music-controls__show');
  103. }
  104. return {
  105. getState,
  106. play,
  107. pause,
  108. destroy
  109. }
  110. }