├── .gitattributes
├── .gitignore
├── README.md
├── config.rb
├── index.html
├── lib
├── wx-audio.css
└── wx-audio.js
├── package-lock.json
├── package.json
├── src
├── assets
│ ├── pause.png
│ └── playing.gif
├── index.js
├── lib
│ ├── wx-audio.js
│ └── wx-audio.less
└── style.less
├── tea.yaml
├── webpack.config.js
└── yarn.lock
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.js linguist-language=javascript
2 | *.css linguist-language=javascript
3 | *.html linguist-language=javascript
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | dist/
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # wx-audio
2 | 微信公众号音乐播放器
3 |
4 | #### 基于原生js写的一款仿微信公众号的音乐组件
5 |
6 | ## 演示地址
7 | http://www.daiwei.org/components/wx-audio/
8 |
9 | ## 手机预览
10 |
11 | ### 安装
12 | npm 安装
13 | ```js
14 | npm install @dw/wx-audio
15 | ```
16 |
17 | ### 引入
18 | ```js
19 | import WxAudio from '@dw/wx-audio/lib/wx-audio.css'
20 | import WxAudio from '@dw/wx-audio'
21 | ```
22 |
23 | 普通资源引入,先将lib文件下的目录放到自己的项目中,然后根据路径引入
24 | ```html
25 |
26 |
27 | ```
28 |
29 | ### 实例化 音乐组件
30 | ```js
31 | var wxAudio = new WxAudio({
32 | ele: '#textaudio1',
33 | title: '河山大好',
34 | disc: '许嵩',
35 | src: 'http://oiq8j9er1.bkt.clouddn.com/%E8%AE%B8%E5%B5%A9%20-%20%E6%B2%B3%E5%B1%B1%E5%A4%A7%E5%A5%BD1.mp3',
36 | width: '320px',
37 | autoplay: true,
38 | loop: true,
39 | ended: function () {
40 | alert('播放结束')
41 | }
42 | });
43 | ```
44 |
45 | ### 属性
46 | - ele dom对象
47 | - title 音乐标题
48 | - disc 描述,可以当做显示歌手名称
49 | - src 地址
50 | - width 显示的宽度
51 | - loop 是否循环(当循环状态下时候,ended事件不会执行)
52 | - ended 方法,是一个回调,可在音乐播放结束之后执行其他的代码
53 | - autoplay 属性, 是否自动播放,这个只能在微信浏览器以及只设置静态src才能自动播放
54 | ### 方法
55 | ```js
56 | // 实例化的wxAudio可以这样操作
57 | wxAudio.audioPlay() // 播放
58 |
59 | wxAudio.audioPause() // 暂停
60 |
61 | wxAudio.audioPlayPause() // 播放暂停
62 |
63 | wxAudio.showLoading(bool) //显示加载状态 参数bool
64 |
65 | wxAudio.audioCut(src,title,disc) 实现音频切换的效果
66 | ```
67 |
68 | ### 新增 音乐组件切歌方法
69 | 通过实例化的wxAudio的audioCut(src,title,disc) 实现音频切换的效果 示例代码如下
70 | ```js
71 | var src = 'http://oiq8j9er1.bkt.clouddn.com/%E6%9E%97%E4%BF%8A%E6%9D%B0%20-%20%E5%A5%B9%E8%AF%B41.mp3'
72 | var title = '她说'
73 | var disc = '林俊杰'
74 | wxAudio.audioCut(src, title, disc)
75 | ```
76 |
--------------------------------------------------------------------------------
/config.rb:
--------------------------------------------------------------------------------
1 | require 'compass/import-once/activate'
2 | # Require any additional compass plugins here.
3 |
4 | # Set this to the root of your project when deployed:
5 | http_path = "/"
6 | css_dir = "css"
7 | sass_dir = "sass"
8 | images_dir = "images"
9 | javascripts_dir = "js"
10 |
11 | # You can select your preferred output style here (can be overridden via the command line):
12 | # output_style = :expanded or :nested or :compact or :compressed
13 |
14 | # To enable relative paths to assets via compass helper functions. Uncomment:
15 | # relative_assets = true
16 |
17 | # To disable debugging comments that display the original location of your selectors. Uncomment:
18 | # line_comments = false
19 |
20 |
21 | # If you prefer the indented syntax, you might want to regenerate this
22 | # project again passing --syntax sass, or you can uncomment this:
23 | # preferred_syntax = :sass
24 | # and then run:
25 | # sass-convert -R --from scss --to sass sass scss && rm -rf sass && mv scss sass
26 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Wx-audio
6 |
8 |
9 |
10 | es6 wx-audio
11 |
12 | 播放
13 | 暂停
14 | 切歌
15 |
16 |
--------------------------------------------------------------------------------
/lib/wx-audio.css:
--------------------------------------------------------------------------------
1 | @keyframes slidein {
2 | 0% {
3 | -webkit-transform: translateX(-50%);
4 | -moz-transform: translateX(-50%);
5 | -ms-transform: translateX(-50%);
6 | -o-transform: translateX(-50%);
7 | transform: translateX(-50%);
8 | }
9 | 100% {
10 | -webkit-transform: translateX(0);
11 | -moz-transform: translateX(0);
12 | -ms-transform: translateX(0);
13 | -o-transform: translateX(0);
14 | transform: translateX(0);
15 | }
16 | }
17 | .wx-audio-content {
18 | user-select: none;
19 | width: 100%;
20 | display: flex;
21 | align-items: center;
22 | justify-content: center;
23 | min-height: auto;
24 | padding: 8px 12px;
25 | border: 1px solid #efefef;
26 | margin: 0 auto;
27 | font-size: 0;
28 | box-sizing: border-box;
29 | font-family: 'PingFangSC-Regular';
30 | -webkit-tap-highlight-color: transparent;
31 | background: #fdfdfd;
32 | }
33 | .wx-audio-content p {
34 | margin: 0;
35 | }
36 | .wx-audio-content .wx-audio-info {
37 | display: none;
38 | }
39 | .wx-audio-content .wx-audio-left {
40 | display: inline-block;
41 | width: 42px;
42 | height: 100%;
43 | }
44 | .wx-audio-content .wx-audio-left .wx-audio-state {
45 | width: 100%;
46 | height: 100%;
47 | }
48 | .wx-audio-content .wx-audio-right {
49 | display: inline-block;
50 | width: calc(100% - 42px);
51 | font-size: 16px;
52 | box-sizing: border-box;
53 | padding-left: 10px;
54 | }
55 | .wx-audio-content .wx-audio-right .wx-audio-title {
56 | padding-bottom: 6px;
57 | width: 100%;
58 | font-size: 16px;
59 | font-weight: 400;
60 | text-overflow: ellipsis;
61 | overflow: hidden;
62 | white-space: nowrap;
63 | }
64 | .wx-audio-content .wx-audio-right .wx-audio-disc {
65 | width: 100%;
66 | text-overflow: ellipsis;
67 | overflow: hidden;
68 | white-space: nowrap;
69 | padding-bottom: 10px;
70 | font-size: 12px;
71 | color: #8c8c8c;
72 | }
73 | .wx-audio-content .wx-audio-right .wx-audio-progrees {
74 | height: 2px;
75 | width: calc(100% - 4px);
76 | position: relative;
77 | }
78 | .wx-audio-content .wx-audio-right .wx-audio-progrees .wx-progrees-detail {
79 | height: 100%;
80 | width: 100%;
81 | background: #ebebeb;
82 | position: relative;
83 | cursor: pointer;
84 | }
85 | .wx-audio-content .wx-audio-right .wx-audio-progrees .wx-progrees-detail .wx-voice-p {
86 | width: 0%;
87 | position: absolute;
88 | top: 0;
89 | bottom: 0;
90 | left: 0;
91 | right: 0;
92 | overflow: hidden;
93 | background: #09bb07;
94 | z-index: 2;
95 | }
96 | .wx-audio-content .wx-audio-right .wx-audio-progrees .wx-progrees-detail .wx-buffer-p {
97 | width: 0%;
98 | position: absolute;
99 | top: 0;
100 | bottom: 0;
101 | left: 0;
102 | right: 0;
103 | overflow: hidden;
104 | background: #d9d9d9;
105 | z-index: 1;
106 | }
107 | .wx-audio-content .wx-audio-right .wx-audio-progrees .wx-progrees-detail .wx-loading {
108 | display: none;
109 | position: absolute;
110 | top: 0;
111 | bottom: 0;
112 | left: 0;
113 | right: 0;
114 | overflow: hidden;
115 | }
116 | .wx-audio-content .wx-audio-right .wx-audio-progrees .wx-progrees-detail .wx-loading .wx-loading-wrapper {
117 | position: absolute;
118 | top: 0;
119 | bottom: 0;
120 | left: 0;
121 | animation: slidein 6s linear infinite normal;
122 | -webkit-animation: slidein 6s linear infinite normal;
123 | -moz-animation: slidein 6s linear infinite normal;
124 | width: 200%;
125 | max-width: none!important;
126 | background-image: -owg-repeating-linear-gradient(-15deg, #d9d9d9, #d9d9d9 2px, #ebebeb 2px, #ebebeb 4px);
127 | background-image: -webkit-repeating-linear-gradient(-15deg, #d9d9d9, #d9d9d9 2px, #ebebeb 2px, #ebebeb 4px);
128 | background-image: -moz-repeating-linear-gradient(-15deg, #d9d9d9, #d9d9d9 2px, #ebebeb 2px, #ebebeb 4px);
129 | background-image: -o-repeating-linear-gradient(-15deg, #d9d9d9, #d9d9d9 2px, #ebebeb 2px, #ebebeb 4px);
130 | background-image: repeating-linear-gradient(-15deg, #d9d9d9, #d9d9d9 2px, #ebebeb 2px, #ebebeb 4px);
131 | }
132 | .wx-audio-content .wx-audio-right .wx-audio-progrees .wx-audio-origin {
133 | width: 6px;
134 | height: 6px;
135 | margin-top: -3px;
136 | margin-left: 0;
137 | border-radius: 50%;
138 | -moz-border-radius: 50%;
139 | -webkit-border-radius: 50%;
140 | background-color: #09bb07;
141 | position: absolute;
142 | left: 0;
143 | top: 50%;
144 | z-index: 2;
145 | }
146 | .wx-audio-content .wx-audio-right .wx-audio-progrees .wx-audio-origin:before {
147 | content: " ";
148 | display: block;
149 | position: absolute;
150 | width: 24px;
151 | height: 24px;
152 | border-radius: 50%;
153 | -moz-border-radius: 50%;
154 | -webkit-border-radius: 50%;
155 | background-image: radial-gradient(rgba(9, 187, 7, 0.3) 20%, transparent 40%);
156 | top: 50%;
157 | margin-top: -12px;
158 | margin-left: -9px;
159 | cursor: pointer;
160 | outline: 0;
161 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
162 | }
163 | .wx-audio-content .wx-audio-right .wx-audio-time {
164 | width: 100%;
165 | padding-top: 6px;
166 | height: auto;
167 | display: flex;
168 | align-items: center;
169 | justify-content: space-between;
170 | overflow: hidden;
171 | }
172 | .wx-audio-content .wx-audio-right .wx-audio-time span {
173 | font-size: 12px;
174 | color: #8c8c8c;
175 | }
176 |
--------------------------------------------------------------------------------
/lib/wx-audio.js:
--------------------------------------------------------------------------------
1 | var WxAudio=function(i){var t={};function e(A){if(t[A])return t[A].exports;var o=t[A]={i:A,l:!1,exports:{}};return i[A].call(o.exports,o,o.exports,e),o.l=!0,o.exports}return e.m=i,e.c=t,e.d=function(i,t,A){e.o(i,t)||Object.defineProperty(i,t,{enumerable:!0,get:A})},e.r=function(i){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(i,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(i,"__esModule",{value:!0})},e.t=function(i,t){if(1&t&&(i=e(i)),8&t)return i;if(4&t&&"object"==typeof i&&i&&i.__esModule)return i;var A=Object.create(null);if(e.r(A),Object.defineProperty(A,"default",{enumerable:!0,value:i}),2&t&&"string"!=typeof i)for(var o in i)e.d(A,o,function(t){return i[t]}.bind(null,o));return A},e.n=function(i){var t=i&&i.__esModule?function(){return i.default}:function(){return i};return e.d(t,"a",t),t},e.o=function(i,t){return Object.prototype.hasOwnProperty.call(i,t)},e.p="",e(e.s=0)}([function(i,t,e){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var A=function(){function i(i,t){for(var e=0;e0){for(var t=0,e=0;ei.durationT&&(t=i.durationT,i.showLoading(!1),console.log("缓冲完成"));var A=Math.floor(t/i.durationT*100);i.wxBufferP.style.width=A+"%"}var o=new Date;i.wxAudio.paused||(i.reduceTAfter=Date.parse(o)-Math.floor(1e3*i.currentT),i.reduceTAfter-i.reduceTBefore>1e3?i.showLoading(!0):i.showLoading(!1))},i.wxAudio.onended=function(){i.opt.ended()},i.wxAudio.ontimeupdate=function(){var t=new Date;i.isDrag||(i.currentT=i.wxAudio.currentTime,i.currentP=Number(i.wxAudio.currentTime/i.durationT*100),i.reduceTBefore=Date.parse(t)-Math.floor(1e3*i.currentT),i.currentP=i.currentP>100?100:i.currentP,i.wxVoiceP.style.width=i.currentP+"%",i.wxAudioOrigin.style.left=i.currentP+"%",i.wxAudioCurrent.innerText=i.formartTime(i.wxAudio.currentTime),i.showLoading(!1))},i.wxAudioStateImg.onclick=function(){i.audioPlayPause()},i.wxAudioOrigin.onmousedown=function(t){i.isDrag=!0;var e=(t||window.event).clientX,A=t.target.offsetLeft;i.maxProgressWidth=i.wxAudioDetail.offsetWidth,i.wxAudioC.onmousemove=function(t){if(i.isDrag){var o=(t||window.event).clientX;i.dragProgressTo=Math.min(i.maxProgressWidth,Math.max(0,A+(o-e))),i.updatePorgress()}},i.wxAudioC.onmouseup=function(){i.isDrag&&(i.isDrag=!1,i.wxAudio.currentTime=Math.floor(i.dragProgressTo/i.maxProgressWidth*i.durationT))},i.wxAudioC.onmouseleave=function(){i.isDrag&&(i.isDrag=!1,i.wxAudio.currentTime=Math.floor(i.dragProgressTo/i.maxProgressWidth*i.durationT))}},i.wxAudioOrigin.ontouchstart=function(t){i.isDrag=!0;var e=t||window.event,A=e.touches[0].clientX,o=e.target.offsetLeft;i.maxProgressWidth=i.wxAudioDetail.offsetWidth,i.wxAudioC.ontouchmove=function(t){if(i.isDrag){var e=(t||window.event).touches[0].clientX;i.dragProgressTo=Math.min(i.maxProgressWidth,Math.max(0,o+(e-A))),i.updatePorgress()}},i.wxAudioC.ontouchend=function(){i.isDrag&&(i.isDrag=!1,i.wxAudio.currentTime=Math.floor(i.dragProgressTo/i.maxProgressWidth*i.durationT))}},i.wxAudioDetail.onclick=function(t){var e=(t||window.event).layerX,A=i.wxAudioDetail.offsetWidth;i.wxAudio.currentTime=Math.floor(e/A*i.durationT)}}},{key:"isWeiXin",value:function(){var i=window.navigator.userAgent.toLowerCase();return"micromessenger"===String(i.match(/MicroMessenger/i))}},{key:"updatePorgress",value:function(){this.wxAudioOrigin.style.left=this.dragProgressTo+"px",this.wxVoiceP.style.width=this.dragProgressTo+"px";var i=Math.floor(this.dragProgressTo/this.maxProgressWidth*this.durationT);this.wxAudioCurrent.innerText=this.formartTime(i)}},{key:"formartTime",value:function(i){var t=function(i){return(i=i.toString())[1]?i:"0"+i},e=Math.floor(i/60),A=Math.floor(i%60);return t(e)+":"+t(A)}}]),i}();t.default=r},function(i,t){i.exports="data:image/gif;base64,R0lGODlhVABUAPfJAButGiKwIe747m7Kbe/47/r8+vj7+J3bnB+vHqDcny20LByuG+j16Pz9/HvPeiOwIk/ATuT05FLBUTa3Np7bnTm4OCqzKdXv1ff79ySwI8Lowi+1Lj66Pb3mvdvx23nPeaTepMjqyLXktVzEW63hrTW2NEu+So7WjdLu0j66PrzmvKrgqn7QfeL04p/cnkm+SCiyJ7/nvmTHYyGwIPn8+fX69d7y3vb69iWxJE2/TPL58iuzKqzgrHjOeEW8RPT69PH58ZXYlNDtz4bThSyzK+337eb15mLGYdbv1mnJaW/Lb8bqxja3NeX15V3FXPD48GHGYfP689fw11HAUHzQe3fOd0q+STi4N8rrytPu01/FXz25PGzKa17FXez37CCvH6ngqaDcoOn26ODz3x6vHZLXkiaxJef150y/S+Hz4NDt0E/AT77nvrTjtJfZlnrPeje3N0K7QWvKaoXThLvmu8fqxmXHZIPSg5bZlavgq8/tz9zx3JzbnI/WjtHu0Ue9RkS8Q93y3ZTYk6LdovH58FfDV2DGYInUiX3QfIfThmfIZtnw2Dq4OZDXkLrlulDAUIzVi43VjG/LbsPpw/n7+XTNc1TBUx6uHcDnv3DLcDG1MN/y31/FXsjqx2jJaFPBUi60LS60LljDWHXNdGbIZTS2M6/hrnfOdke9R9Tv1FbCVWPHYkC6P1rEWbDir0a8RVXCVMnryYvVi4jUiMHowVnDWMvry+v36zO2Mqjfpx2uHGfIZyeyJsDowLHisZHXkZPYk7nluXbNddnw2fv8+4fUhzC1LxqtGf39/QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/wtYTVAgRGF0YVhNUDw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDY3IDc5LjE1Nzc0NywgMjAxNS8wMy8zMC0yMzo0MDo0MiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo4NzEyYzBkMi03NGJlLTQ5MTEtYmQyMi1lNmI4ZTlhZmQ5ZGIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QkUzMTAyRkEyMjg0MTFFN0JDNzBCMEY5NjNCMDhDQjQiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QkUzMTAyRjkyMjg0MTFFN0JDNzBCMEY5NjNCMDhDQjQiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4NzEyYzBkMi03NGJlLTQ5MTEtYmQyMi1lNmI4ZTlhZmQ5ZGIiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6ODcxMmMwZDItNzRiZS00OTExLWJkMjItZTZiOGU5YWZkOWRiIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+Af/+/fz7+vn49/b19PPy8fDv7u3s6+rp6Ofm5eTj4uHg397d3Nva2djX1tXU09LR0M/OzczLysnIx8bFxMPCwcC/vr28u7q5uLe2tbSzsrGwr66trKuqqainpqWko6KhoJ+enZybmpmYl5aVlJOSkZCPjo2Mi4qJ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"},function(i,t){i.exports="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAABUCAMAAAArteDzAAAAaVBMVEUAAAAarRkarRkarRkarRkarRkarRkarRkarRkarRkarRkarRkarRkarRkarRkarRkarRkarRkarRkarRkarRkarRkarRkarRkarRkarRkarRkarRkarRkarRkarRkarRkarRkarRkarRlIa6J1AAAAInRSTlMA9wYa38QR7ZJnMK1IIqBsO3fXDbSGQudZz5fKpV0rfbpRlHIjYQAAA35JREFUWMPFWduyqjAMDS0tgtwEFBGv/P9Hntmh3cWDTYsMs/Oio3SRy0qapuCU7PXIRdUGQxCFncgfrwzWCb/l4TCTML/xbxFlIQariEJ+AZnkwUBKkCdLIZvBQ5olsPw61Uhc4vTOa4Ca39P4IqYWXH2dyw5mWXUs2ez/8liZVx6YD2bW6wXRzmpesov0U70HxW5azTBmpD1xqJW9uUzfaS0Lp1ms0Nru6Nfv9WPSi8lahT2BKoWyvARPKZUPhLRiduq9ckHaKds6y5pa6XmARXJQutaEP4MzLJTzyJfmk193I2YKiyUdUXcf+OnCdKPO+JqNvxO2kx4YNcr+c2jvjpE7Wv27W4uRS/C1jFEu3mpdhJyX34PWISY3ByNj/SxhhZRjfZ0UMkUJt3Bxx08rJU2xbFB16YEZDiG3JSy6sHlXNPbCHIbOVpHiN1VzjBLzKOCkmxjGKld6B4oNbjkiqi3rkJeBNN8jBj7SUEaxyGgnjE1OkS0mHkUAgd5X/qWF80mWR7PaOY0410GrnHHXVHpSqlZII521RzeXqtpkTkgEEitIiwF1YeLDJgQnIldbgAx5wMBj5z4br+aWB5GdGbxUxGjUp6ESLmxhJsaMFzx+Pi5+VIpN6bTUlcvPfw/InXlvjO5MjsdE/ucg6DjxRlEJY4Wb0J1IlnR0ZoXGEHF/6l1I68d+vj3ho9xH0mO+cjumNiMxvg/tTOWYcIAkqCl+XjRbtH7CHv4aCQrIQIui3TCxNPyN1BMXfhQFFxCgJ/yzmYAaTpGgEZpPoOq60GJctfkRaX5IBApRVTNTm/TvnYHqCEoh6kMzUCuNxnUUpVzkB/2+/Pc5iTpT5PdNUx78FrMT6kymqbugmEpxNZU4JXaph7v0GbOGxJQ3SZU+ryINSWT8iAt6skg7txPD1wCJN/rrQG0nZuNzo54nHQOnNj6zRTtRj5Pe5klu0d7NBGTThvFENhNE20NQS5BtD9GgUdQqyQZtaSuZ4bIr1fUGcmHTCz1SRpJNL9GeE3xNHe35/CDhRj04DhLzI48b9eI48mxxONvyGLn+wGtsLTY5mm87RFg/7jhNxh3bD2aANWtHSFsOu7Yfy60fIG4/6lw/lN14fOwedJdWXxKD7m1H8u7LAwZMZsn88mCDa46/v5DZ6OoIhcf7dg7Y7mPalb7XcVEwDEFU+V3H/QOplcP+ctPpgwAAAABJRU5ErkJggg=="},function(i,t){}]).default;
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@dw/wx-audio",
3 | "version": "1.0.7",
4 | "description": "wx-audio",
5 | "main": "src/lib/wx-audio.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "build": "webpack --mode production",
9 | "build:publish": "webpack --mode production && npm version patch && npm publish",
10 | "dev": "webpack-dev-server --mode development --progress --colors",
11 | "watch": "webpack --progress --colors --watch",
12 | "publish": "npm publish --access=public"
13 | },
14 | "repository": {
15 | "type": "git",
16 | "url": "https://www.github.com/ifmiss/wx-audio.js"
17 | },
18 | "files": [
19 | "lib/",
20 | "src/lib",
21 | "src/assets",
22 | "README.md"
23 | ],
24 | "keywords": [
25 | "audio",
26 | "wx",
27 | "we-audio",
28 | "wx-audio",
29 | "music"
30 | ],
31 | "author": "daiwei",
32 | "license": "ISC",
33 | "devDependencies": {
34 | "@dw/webpack-prompt-plugin": "^1.0.7",
35 | "axios": "^0.18.0",
36 | "babel-core": "^6.26.0",
37 | "babel-loader": "^7.1.4",
38 | "babel-polyfill": "^6.26.0",
39 | "babel-preset-env": "^1.6.1",
40 | "babel-preset-latest": "^6.24.1",
41 | "css-loader": "^0.28.10",
42 | "extract-text-webpack-plugin": "^4.0.0-beta.0",
43 | "html-webpack-plugin": "^3.0.6",
44 | "less": "^3.9.0",
45 | "less-loader": "^4.1.0",
46 | "style-loader": "^0.20.3",
47 | "url-loader": "^1.0.1",
48 | "url-parse": "^1.4.3",
49 | "webpack": "^4.1.1",
50 | "webpack-cli": "^3.3.1",
51 | "webpack-dev-server": "^3.1.1"
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/assets/pause.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IFmiss/wx-audio/8d99e43cbd2ab039983564045b0e3542518fac1d/src/assets/pause.png
--------------------------------------------------------------------------------
/src/assets/playing.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IFmiss/wx-audio/8d99e43cbd2ab039983564045b0e3542518fac1d/src/assets/playing.gif
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import './style.less'
2 | import WxAudio from './lib/wx-audio.js';
3 |
4 | import axios from 'axios'
5 | let index = 0
6 | let wx, music
7 |
8 | // axios.get('http://www.daiwei.org/vue/server/music.php?inAjax=1&do=playlist&id=2179377798').then((res) => {
9 | // music = res.data.playlist.tracks
10 | // index = Math.floor(Math.random() * music.length)
11 | // axios.get('http://www.daiwei.org/vue/server/music.php?inAjax=1&do=musicInfo&id=' + music[index].id).then((res) => {
12 | // wx = new WxAudio ({
13 | // ele: '.wx-audio',
14 | // title: music[index].name,
15 | // disc: music[index].ar[0].name,
16 | // src: res.data.data[0].url,
17 | // width: '320px',
18 | // ended: function () {
19 | // index = Math.floor(Math.random() * music.length)
20 | // axios.get('http://www.daiwei.org/vue/server/music.php?inAjax=1&do=musicInfo&id=' + music[index].id).then((res) => {
21 | // console.log(music[index].ar[0].name)
22 | // var src = res.data.data[0].url
23 | // var title = music[index].name
24 | // var disc = music[index].ar[0].name
25 | // wx.audioCut(src, title, disc)
26 | // }, (err) => {
27 | // console.log(err)
28 | // })
29 | // }
30 | // })
31 | // })
32 | // }, (err) => {
33 | // console.log(err)
34 | // })
35 | wx = new WxAudio ({
36 | ele: '.wx-audio',
37 | title: '111111',
38 | disc: '2222',
39 | src: 'http://m10.music.126.net/20190426110819/bdb6a025449d78de141a2c31a2330484/ymusic/cd1c/7825/d746/0dc64d2be36bfe20f55a401318b6080a.mp3',
40 | width: '320px',
41 | autoplay: true
42 | })
43 |
44 | document.getElementById('play').onclick = function () {
45 | wx.audioPlay()
46 | }
47 |
48 | document.getElementById('pause').onclick = function () {
49 | wx.audioPause()
50 | }
51 |
52 | document.getElementById('cut').onclick = function () {
53 | index = Math.floor(Math.random() * music.length)
54 | axios.get('http://www.daiwei.org/vue/server/music.php?inAjax=1&do=musicInfo&id=' + music[index].id).then((res) => {
55 | console.log(music[index].ar[0].name)
56 | var src = res.data.data[0].url
57 | var title = music[index].name
58 | var disc = music[index].ar[0].name
59 | wx.audioCut(src, title, disc)
60 | }, (err) => {
61 | console.log(err)
62 | })
63 | }
64 |
--------------------------------------------------------------------------------
/src/lib/wx-audio.js:
--------------------------------------------------------------------------------
1 | import './wx-audio.less'
2 | const playImg = require('./../assets/playing.gif')
3 | const pauseImg = require('./../assets/pause.png')
4 | export default class WxAudio {
5 | constructor (tpl) {
6 | let defaultOptions = {
7 | ele: null,
8 | width: '320px',
9 | title: '这是一个测试title',
10 | src: '',
11 | disc: '这是一个测试disc',
12 | autoplay: false,
13 | // loop为true的时候不执行ended事件
14 | loop: true,
15 | ended: function () {}
16 | }
17 | this.opt = Object.assign({}, defaultOptions, tpl)
18 | // 判断传进来的是DOM还是字符串
19 | if (typeof this.opt.ele === 'string') {
20 | this.opt.ele = document.querySelector(this.opt.ele)
21 | }
22 | if (!this.opt.ele) return
23 |
24 | this.loading = false
25 | this.isDrag = false
26 | this.isplaying = false
27 | this.durationT = 0
28 | this.currentT = 0
29 | this.currentP = 0
30 | this.maxProgressWidth = 0
31 | this.dragProgressTo = 0
32 |
33 | // 通过时间戳与当前时间的差值来判断是否需要加载
34 | this.reduceTBefore = 0 // 时间戳与当前时间的差值 (初始化)
35 | this.reduceTAfter = 0 // 时间戳与当前时间的差值 (执行中)
36 |
37 | this.initDom();
38 | }
39 |
40 | // 初始化元素
41 | initDom () {
42 | // content
43 | this.wxAudioC = document.createElement('div')
44 | this.wxAudioC.className = 'wx-audio-content'
45 | this.wxAudioC.style.width = this.opt.width
46 | this.opt.ele.appendChild(this.wxAudioC)
47 |
48 | // audio
49 | this.wxAudio = document.createElement('audio')
50 | this.wxAudio.className = 'wx-audio-content'
51 | this.wxAudio.src = this.opt.src
52 | if (this.opt.loop) this.wxAudio.setAttribute('loop', this.opt.loop)
53 | this.wxAudioC.appendChild(this.wxAudio)
54 |
55 | // left
56 | this.wxAudioL = document.createElement('div')
57 | this.wxAudioL.className = 'wx-audio-left'
58 | this.wxAudioC.appendChild(this.wxAudioL)
59 |
60 | // left image
61 | this.wxAudioStateImg = document.createElement('img')
62 | this.wxAudioStateImg.className = 'wx-audio-state'
63 | this.wxAudioStateImg.src = pauseImg
64 | this.wxAudioL.appendChild(this.wxAudioStateImg)
65 |
66 | // right
67 | this.wxAudioR = document.createElement('div')
68 | this.wxAudioR.className = 'wx-audio-right'
69 | this.wxAudioC.appendChild(this.wxAudioR)
70 |
71 | // right title
72 | this.wxAudioT = document.createElement('p')
73 | this.wxAudioT.className = 'wx-audio-title'
74 | this.wxAudioT.innerText = this.opt.title
75 | this.wxAudioR.appendChild(this.wxAudioT)
76 |
77 | // right disc
78 | this.wxAudioD = document.createElement('p')
79 | this.wxAudioD.className = 'wx-audio-disc'
80 | this.wxAudioD.innerText = this.opt.disc
81 | this.wxAudioR.appendChild(this.wxAudioD)
82 |
83 | // right progrees
84 | this.wxAudioP = document.createElement('div')
85 | this.wxAudioP.className = 'wx-audio-progrees'
86 | this.wxAudioR.appendChild(this.wxAudioP)
87 |
88 | // right progress detail
89 | this.wxAudioDetail = document.createElement('div')
90 | this.wxAudioDetail.className = 'wx-progrees-detail'
91 | this.wxAudioP.appendChild(this.wxAudioDetail)
92 |
93 | // voice p
94 | this.wxVoiceP = document.createElement('span')
95 | this.wxVoiceP.className = 'wx-voice-p'
96 | this.wxAudioDetail.appendChild(this.wxVoiceP)
97 |
98 | // buffer p
99 | this.wxBufferP = document.createElement('span')
100 | this.wxBufferP.className = 'wx-buffer-p'
101 | this.wxAudioDetail.appendChild(this.wxBufferP)
102 |
103 | // loading p
104 | this.wxLoading = document.createElement('span')
105 | this.wxLoading.className = 'wx-loading'
106 | this.wxAudioDetail.appendChild(this.wxLoading)
107 |
108 | // laoding wrapper
109 | this.wxLoadingWrapper = document.createElement('span')
110 | this.wxLoadingWrapper.className = 'wx-loading-wrapper'
111 | this.wxLoading.appendChild(this.wxLoadingWrapper)
112 |
113 | // origin
114 | this.wxAudioOrigin = document.createElement('div')
115 | this.wxAudioOrigin.className = 'wx-audio-origin'
116 | this.wxAudioP.appendChild(this.wxAudioOrigin)
117 |
118 | // 音乐时间信息
119 | this.wxAudioTime = document.createElement('div')
120 | this.wxAudioTime.className = 'wx-audio-time'
121 | this.wxAudioR.appendChild(this.wxAudioTime)
122 |
123 | // currentT
124 | this.wxAudioCurrent = document.createElement('span')
125 | this.wxAudioCurrent.className = 'current-t'
126 | this.wxAudioCurrent.innerText = '00:00'
127 | this.wxAudioTime.appendChild(this.wxAudioCurrent)
128 |
129 | // durationT
130 | this.wxAudioDuration = document.createElement('span')
131 | this.wxAudioDuration.className = 'duration-t'
132 | this.wxAudioDuration.innerText = '00:00'
133 | this.wxAudioTime.appendChild(this.wxAudioDuration)
134 |
135 | this.initAudioEvent();
136 |
137 | if (this.opt.autoplay) {
138 | document.addEventListener('WeixinJSBridgeReady', () => {
139 | this.audioPlay()
140 | })
141 | }
142 | }
143 |
144 | // 播放
145 | audioPlay () {
146 | this.wxAudio.play()
147 | this.isPlaying = true
148 | }
149 |
150 | //
151 | audioPause () {
152 | this.wxAudio.pause();
153 | this.isPlaying = false
154 | }
155 |
156 | audioPlayPause () {
157 | if (this.isPlaying) {
158 | this.audioPause();
159 | } else {
160 | this.audioPlay();
161 | }
162 | }
163 |
164 | audioCut (src, title, disc) {
165 | this.wxAudio.src = src
166 | this.wxAudioT.innerText = title
167 | this.wxAudioD.innerText = disc
168 | this.durationT = 0
169 | this.currentT = 0
170 | this.currentP = 0
171 | this.dragProgressTo = 0
172 | // 初始化 wxAudioCurrent 的文案
173 | this.wxAudioCurrent.innerText = '00:00'
174 | this.wxAudioOrigin.style.left = '0px'
175 | this.wxVoiceP.style.width = '0px'
176 | this.audioPlay()
177 | }
178 |
179 | showLoading (bool) {
180 | this.loading = bool || false
181 | if (this.loading) {
182 | this.wxLoading.style.display = 'block'
183 | } else {
184 | this.wxLoading.style.display = 'none'
185 | }
186 | }
187 |
188 | initAudioEvent () {
189 | var _this = this
190 | // 音频事件
191 | _this.wxAudio.onplaying = function () {
192 | var date = new Date ()
193 | _this.isPlaying = true
194 | _this.reduceTBefore = Date.parse(date) - Math.floor(_this.wxAudio.currentTime * 1000)
195 | _this.wxAudioStateImg.src = playImg
196 | },
197 | _this.wxAudio.onpause = function () {
198 | _this.isPlaying = false
199 | _this.showLoading(false)
200 | _this.wxAudioStateImg.src = pauseImg
201 | },
202 | _this.wxAudio.onloadedmetadata = function () {
203 | _this.durationT = _this.wxAudio.duration
204 | // 初始化视频时间
205 | _this.wxAudioDuration.innerText = _this.formartTime(_this.wxAudio.duration)
206 | },
207 | _this.wxAudio.onwaiting = function () {
208 | if(!_this.wxAudio.paused) {
209 | _this.showLoading(true)
210 | }
211 | },
212 | _this.wxAudio.onprogress = function () {
213 | if(_this.wxAudio.buffered.length > 0) {
214 | var bufferedT = 0
215 | for (var i = 0; i < _this.wxAudio.buffered.length; i++) {
216 | bufferedT += _this.wxAudio.buffered.end(i) - _this.wxAudio.buffered.start(i)
217 | if(bufferedT > _this.durationT) {
218 | bufferedT = _this.durationT
219 | _this.showLoading(false)
220 | console.log('缓冲完成')
221 | }
222 | }
223 | var bufferedP = Math.floor((bufferedT / _this.durationT) * 100)
224 | _this.wxBufferP.style.width = bufferedP + '%'
225 | }
226 |
227 | // ===========================
228 | var date = new Date ()
229 | if(!_this.wxAudio.paused) {
230 | _this.reduceTAfter = Date.parse(date) - Math.floor(_this.currentT * 1000)
231 | if(_this.reduceTAfter - _this.reduceTBefore > 1000) {
232 | _this.showLoading(true)
233 | } else {
234 | _this.showLoading(false)
235 | }
236 | } else {
237 | return
238 | }
239 | },
240 | // 播放结束事件
241 | _this.wxAudio.onended = function () {
242 | _this.opt.ended()
243 | }
244 | // 绑定进度条
245 | _this.wxAudio.ontimeupdate = function () {
246 | var date = new Date ()
247 | if (!_this.isDrag) {
248 | _this.currentT = _this.wxAudio.currentTime
249 | _this.currentP = Number((_this.wxAudio.currentTime / _this.durationT) * 100)
250 | _this.reduceTBefore = Date.parse(date) - Math.floor(_this.currentT * 1000)
251 | _this.currentP = _this.currentP > 100 ? 100 : _this.currentP
252 | _this.wxVoiceP.style.width = _this.currentP + '%'
253 | _this.wxAudioOrigin.style.left = _this.currentP + '%'
254 | // 更改时间进度
255 | _this.wxAudioCurrent.innerText = _this.formartTime(_this.wxAudio.currentTime)
256 | _this.showLoading(false)
257 | }
258 | },
259 | // 页面点击事件
260 | _this.wxAudioStateImg.onclick = function () {
261 | _this.audioPlayPause()
262 | }
263 |
264 | _this.wxAudioOrigin.onmousedown = function (event) {
265 | _this.isDrag = true
266 | var e = event || window.event
267 | var x = e.clientX
268 | var l = event.target.offsetLeft
269 | _this.maxProgressWidth = _this.wxAudioDetail.offsetWidth
270 | _this.wxAudioC.onmousemove = function (event) {
271 | if (_this.isDrag) {
272 | var e = event || window.event
273 | var thisX = e.clientX
274 | _this.dragProgressTo = Math.min(_this.maxProgressWidth, Math.max(0, l + (thisX - x)))
275 | // update Time
276 | _this.updatePorgress()
277 | }
278 | }
279 | _this.wxAudioC.onmouseup = function () {
280 | if (_this.isDrag) {
281 | _this.isDrag = false
282 | _this.wxAudio.currentTime = Math.floor(_this.dragProgressTo / _this.maxProgressWidth * _this.durationT)
283 | } else {
284 | return
285 | }
286 | }
287 |
288 | _this.wxAudioC.onmouseleave = function () {
289 | if (_this.isDrag) {
290 | _this.isDrag = false
291 | _this.wxAudio.currentTime = Math.floor(_this.dragProgressTo / _this.maxProgressWidth * _this.durationT)
292 | } else {
293 | return
294 | }
295 | }
296 | }
297 |
298 | _this.wxAudioOrigin.ontouchstart = function (event) {
299 | _this.isDrag = true
300 | var e = event || window.event
301 | var x = e.touches[0].clientX
302 | var l = e.target.offsetLeft
303 |
304 | _this.maxProgressWidth = _this.wxAudioDetail.offsetWidth
305 |
306 | _this.wxAudioC.ontouchmove = function (event) {
307 | if (_this.isDrag) {
308 | var e = event || window.event
309 | var thisX = e.touches[0].clientX
310 | _this.dragProgressTo = Math.min(_this.maxProgressWidth, Math.max(0, l + (thisX - x)))
311 | _this.updatePorgress()
312 | }
313 | },
314 | _this.wxAudioC.ontouchend = function () {
315 | if (_this.isDrag) {
316 | _this.isDrag = false
317 | _this.wxAudio.currentTime = Math.floor(_this.dragProgressTo / _this.maxProgressWidth * _this.durationT)
318 | } else {
319 | return
320 | }
321 | }
322 | }
323 |
324 | _this.wxAudioDetail.onclick = function (event) {
325 | var e = event || window.event
326 | var l = e.layerX
327 | var w = _this.wxAudioDetail.offsetWidth
328 | _this.wxAudio.currentTime = Math.floor(l / w * _this.durationT)
329 | }
330 | }
331 |
332 | isWeiXin () {
333 | const uaLower = window.navigator.userAgent.toLowerCase()
334 | return String(uaLower.match(/MicroMessenger/i)) === 'micromessenger'
335 | }
336 |
337 | updatePorgress () {
338 | this.wxAudioOrigin.style.left = this.dragProgressTo + 'px'
339 | this.wxVoiceP.style.width = this.dragProgressTo + 'px'
340 | var currentTime = Math.floor(this.dragProgressTo / this.maxProgressWidth * this.durationT)
341 | // this.wxAudio.currentTime = currentTime
342 | this.wxAudioCurrent.innerText = this.formartTime(currentTime)
343 | // this.wxAudio.currentTime = Math.floor(this.dragProgressTo / this.maxProgressWidth * this.durationT)
344 | }
345 |
346 | formartTime (seconds) {
347 | var formatNumber = function (n) {
348 | n = n.toString()
349 | return n[1] ? n : '0' + n
350 | }
351 | var m = Math.floor(seconds / 60);
352 | var s = Math.floor(seconds % 60);
353 | return formatNumber(m) + ":" + formatNumber(s);
354 | }
355 | }
356 |
--------------------------------------------------------------------------------
/src/lib/wx-audio.less:
--------------------------------------------------------------------------------
1 | @keyframes slidein {
2 | 0% {
3 | -webkit-transform: translateX(-50%);
4 | -moz-transform: translateX(-50%);
5 | -ms-transform: translateX(-50%);
6 | -o-transform: translateX(-50%);
7 | transform: translateX(-50%);
8 | -webkit-transform: translateX(-50%);
9 | -moz-transform: translateX(-50%);
10 | -ms-transform: translateX(-50%);
11 | -o-transform: translateX(-50%);
12 | transform: translateX(-50%); }
13 | 100% {
14 | -webkit-transform: translateX(0);
15 | -moz-transform: translateX(0);
16 | -ms-transform: translateX(0);
17 | -o-transform: translateX(0);
18 | transform: translateX(0);
19 | -webkit-transform: translateX(0);
20 | -moz-transform: translateX(0);
21 | -ms-transform: translateX(0);
22 | -o-transform: translateX(0);
23 | transform: translateX(0); } }
24 | .wx-audio-content{
25 | user-select: none;
26 | width: 100%;
27 | display: flex;
28 | align-items: center;
29 | justify-content: center;
30 | min-height: auto;
31 | padding: 8px 12px;
32 | border: 1px solid #efefef;
33 | margin: 0 auto;
34 | font-size: 0;
35 | box-sizing: border-box;
36 | font-family: 'PingFangSC-Regular';
37 | -webkit-tap-highlight-color:transparent;
38 | background:#fdfdfd;
39 | p{
40 | margin: 0;
41 | }
42 | .wx-audio-info{
43 | display: none;
44 | }
45 | .wx-audio-left{
46 | display: inline-block;
47 | width:42px;
48 | height: 100%;
49 | .wx-audio-state{
50 | width: 100%;
51 | height: 100%;
52 | }
53 | }
54 | .wx-audio-right{
55 | display: inline-block;
56 | width: calc(100% - 42px);
57 | font-size: 16px;
58 | box-sizing: border-box;
59 | padding-left:10px;
60 | .wx-audio-title{
61 | padding-bottom: 6px;
62 | width: 100%;
63 | font-size: 16px;
64 | font-weight: 400;
65 | text-overflow: ellipsis;
66 | overflow: hidden;
67 | white-space: nowrap;
68 | }
69 | .wx-audio-disc{
70 | width: 100%;
71 | text-overflow: ellipsis;
72 | overflow: hidden;
73 | white-space: nowrap;
74 | padding-bottom: 10px;
75 | font-size: 12px;
76 | color: #8c8c8c;
77 | }
78 | .wx-audio-progrees{
79 | height: 2px;
80 | width: calc(100% - 4px);
81 | position:relative;
82 | .wx-progrees-detail{
83 | height: 100%;
84 | width: 100%;
85 | background:#ebebeb;
86 | position:relative;
87 | cursor: pointer;
88 | .wx-voice-p{
89 | width: 0%;
90 | position: absolute;
91 | top: 0;
92 | bottom: 0;
93 | left: 0;
94 | right: 0;
95 | overflow: hidden;
96 | background:#09bb07;
97 | z-index: 2;
98 | }
99 | .wx-buffer-p{
100 | width: 0%;
101 | position: absolute;
102 | top: 0;
103 | bottom: 0;
104 | left: 0;
105 | right: 0;
106 | overflow: hidden;
107 | background:#d9d9d9;
108 | z-index: 1;
109 | }
110 | .wx-loading{
111 | display: none;
112 | position: absolute;
113 | top: 0;
114 | bottom: 0;
115 | left: 0;
116 | right: 0;
117 | overflow: hidden;
118 | .wx-loading-wrapper{
119 | position: absolute;
120 | top: 0;
121 | bottom: 0;
122 | left: 0;
123 | animation: slidein 6s linear infinite normal;
124 | -webkit-animation: slidein 6s linear infinite normal;
125 | -moz-animation: slidein 6s linear infinite normal;
126 | width: 200%;
127 | max-width: none!important;
128 | background-image: -owg-repeating-linear-gradient(-15deg, #d9d9d9, #d9d9d9 2px, #ebebeb 2px, #ebebeb 4px);
129 | background-image: -webkit-repeating-linear-gradient(-15deg, #d9d9d9, #d9d9d9 2px, #ebebeb 2px, #ebebeb 4px);
130 | background-image: -moz-repeating-linear-gradient(-15deg, #d9d9d9, #d9d9d9 2px, #ebebeb 2px, #ebebeb 4px);
131 | background-image: -o-repeating-linear-gradient(-15deg, #d9d9d9, #d9d9d9 2px, #ebebeb 2px, #ebebeb 4px);
132 | background-image: repeating-linear-gradient(-15deg, #d9d9d9, #d9d9d9 2px, #ebebeb 2px, #ebebeb 4px);
133 | }
134 | }
135 | }
136 | .wx-audio-origin{
137 | width: 6px;
138 | height: 6px;
139 | margin-top: -3px;
140 | margin-left: 0;
141 | border-radius: 50%;
142 | -moz-border-radius: 50%;
143 | -webkit-border-radius: 50%;
144 | background-color: #09bb07;
145 | position: absolute;
146 | left: 0;
147 | top: 50%;
148 | z-index: 2;
149 | &:before{
150 | content: " ";
151 | display: block;
152 | // z-index: 2;
153 | position: absolute;
154 | width: 24px;
155 | height: 24px;
156 | border-radius: 50%;
157 | -moz-border-radius: 50%;
158 | -webkit-border-radius: 50%;
159 | // background-color: rgba(9,187,7,0.3);
160 | background-image: radial-gradient(rgba(9,187,7,0.3) 20%, transparent 40%);
161 | top: 50%;
162 | margin-top: -12px;
163 | margin-left: -9px;
164 | cursor: pointer;
165 | outline: 0;
166 | -webkit-tap-highlight-color: rgba(0,0,0,0);
167 | }
168 | }
169 | }
170 | .wx-audio-time{
171 | width: 100%;
172 | padding-top: 6px;
173 | height: auto;
174 | display: flex;
175 | align-items: center;
176 | justify-content: space-between;
177 | overflow: hidden;
178 | span{
179 | font-size: 12px;
180 | color: #8c8c8c;
181 | }
182 | }
183 | }
184 | }
185 |
--------------------------------------------------------------------------------
/src/style.less:
--------------------------------------------------------------------------------
1 | body,html{
2 | margin: 0;
3 | padding: 0;
4 | height:100%;
5 | background: #fff;
6 | }
7 |
8 | .colortext-lt (@color1, @color2) {
9 | position: relative;
10 | background: -webkit-linear-gradient(left top, @color1 , @color2); /* Safari 5.1 - 6.0 */
11 | background: -o-linear-gradient(bottom right, @color1, @color2); /* Opera 11.1 - 12.0 */
12 | background: -moz-linear-gradient(bottom right, @color1, @color2); /* Firefox 3.6 - 15 */
13 | background: linear-gradient(to bottom right, @color1 , @color2); /* 标准的语法 */
14 | -webkit-background-clip: text;
15 | -webkit-text-fill-color: transparent;
16 | }
17 |
18 | body{
19 | // background: red;
20 | display: flex;
21 | width: 100%;
22 | height: 100%;
23 | align-items: center;
24 | flex-direction: column;
25 | justify-content: center;
26 | .title{
27 | font-size: 42px;
28 | display: inline-block;
29 | .colortext-lt(rgba(50, 219, 154, 0.856), rgba(209, 163, 47, 0.808));
30 | margin-top: 0;
31 | }
32 | .disc{
33 | font-size: 14px;
34 | color: #f1f1f1;
35 | }
36 | .github-info{
37 | margin-top: 40px;
38 | text-align: center;
39 | display: flex;
40 | justify-content: center;
41 | span{
42 | color: #ffffff;
43 | font: Arial,"Helvetica Neue",Helvetica,"Microsoft Yahei","Hiragino Sans GB","Heiti SC","WenQuanYi Micro Hei",sans-serif;
44 | font-size:14px;
45 | }
46 | }
47 | .btn{
48 | width: 320px;
49 | line-height: 40px;
50 | background: #999;
51 | cursor: pointer;
52 | color: #fff;
53 | text-align: center;
54 | margin-top: 30px;
55 | }
56 | }
--------------------------------------------------------------------------------
/tea.yaml:
--------------------------------------------------------------------------------
1 | # https://tea.xyz/what-is-this-file
2 | ---
3 | version: 1.0.0
4 | codeOwners:
5 | - '0x18fb62c5c736405ece7E8e7a2F01D084fFa77B6c'
6 | quorum: 1
7 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack'); // 用于访问内置插件
2 | const path = require('path');
3 |
4 | const HtmlWebpackPlugin = require('html-webpack-plugin');
5 | const ExtractTextPlugin = require("extract-text-webpack-plugin");
6 | const WebpackPromptPlugin = require("@dw/webpack-prompt-plugin")
7 |
8 | const extractSass = new ExtractTextPlugin({
9 | filename: "wx-audio.css",
10 | disable: process.env.NODE_ENV === "development"
11 | });
12 |
13 | const resolve = function (dir) {
14 | return path.resolve(__dirname, dir);
15 | }
16 |
17 | module.exports = {
18 | entry: {
19 | index: 'src/lib/wx-audio.js'
20 | // index: './src/index.js'
21 | },
22 | output: {
23 | path: path.resolve(__dirname, 'lib'),
24 | filename: 'wx-audio.js',
25 | libraryTarget: 'var',
26 | library: 'WxAudio',
27 | libraryExport: 'default'
28 | },
29 | module: {
30 | rules: [
31 | {
32 | test: /\.css$/,
33 | use: ExtractTextPlugin.extract({
34 | fallback:"style-loader",
35 | use:["css-loader"]
36 | })
37 | },
38 | {
39 | test: /\.less$/,
40 | use: ExtractTextPlugin.extract({
41 | fallback:"style-loader",
42 | use:[
43 | {
44 | loader: 'css-loader'
45 | },
46 | {
47 | loader: 'less-loader'
48 | }
49 | ]
50 | })
51 | },
52 | {
53 | test: /\.(ttf|eot|svg|woff|woff2)$/,
54 | use: [
55 | {
56 | loader: 'url-loader'
57 | }
58 | ]
59 | },
60 | {
61 | test: /\.js$/,
62 | exclude: /(node_modules)/,
63 | use: {
64 | loader: 'babel-loader',
65 | options: {
66 | presets: ["env"]
67 | }
68 | }
69 | },
70 | {
71 | test: /\.(png|jpg|gif)$/,
72 | use: [
73 | {
74 | loader: 'url-loader',
75 | options: {
76 | limit: 8192
77 | }
78 | }
79 | ]
80 | },
81 | ]
82 | },
83 | plugins: [
84 | // new HtmlWebpackPlugin ({
85 | // filename: 'index.html',
86 | // template: 'index.html',
87 | // inject: true
88 | // }),
89 | extractSass,
90 | new WebpackPromptPlugin()
91 | ],
92 | devServer: {
93 | // 当使用 HTML5 History API 时,任意的 404 响应都可能需要被替代为 index.html。通过传入以下启用:
94 | contentBase: "./",
95 | host: '0.0.0.0',
96 | // 端口号
97 | port: 1997,
98 | //当有编译器错误或警告时,在浏览器中显示全屏覆盖。默认禁用。如果您只想显示编译器错误:
99 | noInfo: true,
100 | // 配置端口号
101 | overlay: true,
102 | },
103 | resolve: {
104 | alias: {
105 | 'src': resolve('src'),
106 | 'commonjs': resolve('src/commonjs'),
107 | 'scss': resolve('src/scss'),
108 | 'stylus': resolve('src/stylus'),
109 | 'script': resolve('src/script'),
110 | 'static': resolve('static'),
111 | }
112 | },
113 | optimization: {
114 | splitChunks: {
115 | chunks: "all",
116 | minSize: 30000,
117 | minChunks: 3,
118 | maxAsyncRequests: 5,
119 | maxInitialRequests: 3,
120 | name: true,
121 | cacheGroups: {
122 | default: {
123 | minChunks: 2,
124 | priority: -20,
125 | reuseExistingChunk: true,
126 | },
127 | vendors: {
128 | test: /[\\/]node_modules[\\/]/,
129 | priority: -10
130 | }
131 | }
132 | }
133 | }
134 | }
135 |
--------------------------------------------------------------------------------