Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

JavaScript

Babel is required to process package imports. If you need a different preprocessor remove all packages first.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <div id='banner-page'></div>
              
            
!

CSS

              
                .voice-read{
	border-top: 1px solid #dbdbdb;
	margin-top: 15px;
	
	height: 65px;
	
	width: 100px;
}

audio{
	width: 270px;
}


.flex-start{
	justify-content: flex-start !important;
}


.fake-control{
	position: relative;
	top: 4px;
	width: 100%;
}

.fake-control-timeline{
	float: left;
}

.play-icon{
  font-size:14px;
}

.voice-title{
	margin-right: 15px;
	float: left;
	font-size: 13px;
}

.voice-container{
	float: left;
	width: 250px;
  margin:20px;
}

.timeline{
	height: 4px;
  width: 100px;
  background-color: #D8D8D8;
  
  margin-right: 15px;
  position: relative;
  top: -3px;
}

.play-time{
	// margin-right: 33px;
	font-size: 12px;
}

.playhead{
	background-color: #49a9ee;
	width: 13px;
	height: 13px;
	border-radius: 50px;
	position: relative;
	top: -4px;
}

.voice-control{
	position: relative;
	top: -2px;
	
	float: right;
}

.voice-read-outside{
	width: 100%;
}


.clearfix:before,
.clearfix:after{ 
    content:""; 
    display:table; 
} 
.clearfix:after{clear:both;} 
.clearfix{
    clear: both;
}

.inline-block{
	display: inline-block;
}

.float-right{
	float: right;
}
.float-left{
	float: left;
}

.height-0{
	height: 0;
}

/**
 * 居中
 */




.center-father-style{
	display: flex;
	justify-content: center;
	align-items: center;
	
	
}

.center-father-style-align{
	display: flex;
	align-items: center;
}

.center-father-style-justify{
	display: flex;
	justify-content: center;
}

.direction-row-reverse{
	flex-direction :row-reverse;
}


.font-style{
  font-size:13px;
  padding:10px 10px 0  10px;
  
}
              
            
!

JS

              
                // React H5音频<audio/>样式修改,拖拽、点击改变进度操作,总时长 during 加载

// react中SVG的使用(改变大小颜色) 
// 原文地址:
// http://blog.csdn.net/candy_home/article/details/76167345

const voice = "http://aita-access-logo.oss-cn-hangzhou-zmf.aliyuncs.com/logo__wwyxhqc.mp3";

class VoiceRead extends React.Component {
  constructor(props) {
    super(props);
    
    this.state = {
      voice: voice,

      // 是否播放
      isPlay: false,
      // 当前播放时间
      timeCurrent: "00:00",
      // audio currentTime
      currentTime: 0,
      // 播放总时间
      voiceDuration: "00:00",
    }
  }
  
  
  play() {
    let self = this;
    let audio = this.refs.audioTag;

    let timeline = this.refs.timeline;
    let playhead = this.refs.playhead;
    let timelineWidth = timeline.offsetWidth - playhead.offsetWidth;
    let playPercent = timelineWidth * (this.state.currentTime / audio.duration);
    audio.currentTime = this.state.currentTime;

    this.setState({
      isPlay: !this.state.isPlay
    })

    if (!this.state.isPlay) {
      audio.play();
      //如果没有加载出时间
      // alert("play");
      if (this.state.voiceDuration == "00:00") {
        window.setTimeout(() => {
          self.loadVideo();
        }, 300);
      }
    } else { // pause music
      audio.pause();
    }
  }

  // audio的timeupdate事件,用于更新播放进度
  timeUpdate() {
    let audio = this.refs.audioTag;
    // let value = Math.round((Math.floor(audio.currentTime) / Math.floor(audio.duration)) * 100, 0);
    // console.log("timeUpdate " + value);

    let timeline = this.refs.timeline;
    let playhead = this.refs.playhead;
    let timelineWidth = timeline.offsetWidth - playhead.offsetWidth;
    let playPercent = timelineWidth * (audio.currentTime / audio.duration);
    playhead.style.webkitTransform = "translateX(" + playPercent + "px)";
    playhead.style.transform = "translateX(" + playPercent + "px)";

    let timeCurrent = this.transTime(audio.currentTime);
    this.setState({
      timeCurrent: timeCurrent,
      currentTime: audio.currentTime,
    });
  }



  /** 获取视频总长 */
  loadVideo() {
    let self = this;
    let audio = this.refs.audioTag;
    let duration = this.transTime(audio.duration);
    let time = duration == "NaN:NaN" ? "00:00" : duration;
    // alert(audio.duration);

    if (time == "00:00" && duration != "NaN:NaN" && !!initAudio) {
      // alert("initAudio play");
      audio.play();
      // alert("initAudio pause");
      audio.pause();
      initAudio = false;

      window.setTimeout(() => {
        self.loadVideo();
      }, 300);
    }

    this.setState({
      voiceDuration: time,
    });
  }

  /**
   * 工具类
   */
  //转换音频时长显示
  transTime(time) {
    let duration = parseInt(time);
    let minute = parseInt(duration / 60);
    let sec = duration % 60 + '';
    let isM0 = ':';
    if (minute == 0) {
      minute = '00';
    } else if (minute < 10) {
      minute = '0' + minute;
    }
    if (sec.length == 1) {
      sec = '0' + sec;
    }
    return minute + isM0 + sec
  }



  /**
   * 进度条操作
   * @param  {[type]} e [description]
   * @return {[type]}   [description]
   */
  timelineClick(e) {
    let timeline = this.refs.timeline;
    let playhead = this.refs.playhead;
    let audio = this.refs.audioTag;
    let timelineWidth = timeline.offsetWidth - playhead.offsetWidth;

    // 更新坐标位置
    // e.pageX 鼠标点击位置
    // offsetLeft  元素 相对于它的直接父元素 的 偏移量
    let newLeft = e.pageX - timeline.offsetParent.offsetLeft;
    let currentTime = audio.duration * (e.pageX - timeline.offsetParent.offsetLeft) / timelineWidth;

    if (newLeft >= 0 && newLeft <= timelineWidth) {
      playhead.style.transform = "translateX(" + newLeft + "px)";
    }
    if (newLeft < 0) {
      playhead.style.transform = "translateX(0)";
      currentTime = 0;
    }
    if (newLeft > timelineWidth) {
      playhead.style.transform = "translateX(" + timelineWidth + "px)";
      currentTime = audio.duration;
    }
    // 更新时间
    let timeCurrent = this.transTime(currentTime);
    this.setState({
      timeCurrent: timeCurrent,
      currentTime: currentTime,
    });

    // 如果在播放
    if (this.state.isPlay) {
      audio.currentTime = currentTime;
      audio.play();
    } else { // pause music
      audio.pause();
    }

  }

  // 进度条点击
  touchStart(e) {
    let events = e.touches[0] || e;
    this.timelineClick(events);
  }

  touchMove(e) {
    // if (this.state.touching !== true) {
    //   return;
    // }
    let events = e.touches[0] || e;
    this.timelineClick(events);
  }

  touchEnd(e) {
    this.setState({
      touching: false,
    })
  }
  
  render() {
    return (
      <div> 
        <div className="font-style">点击下方“点击播放”,开始播放和暂停音乐</div>
        <div className="font-style">拖拽 蓝色小球,或者直接点击灰色条 来修改播放时间</div>
         <div className="voice-container">
            <audio  ref="audioTag" src={this.state.voice} onTimeUpdate={()=>this.timeUpdate()} onLoadedMetadata={()=>this.loadVideo()}/>
            <div className="controls">
              <div className="fake-control">
                <div  className="inline-block fake-control-timeline" >
                  <div ref="timeline" className="timeline inline-block" onClick={(e)=> this.timelineClick(e)} > 
                      <div ref="playhead" className="playhead" onTouchStart={(e)=>this.touchStart(e)} onTouchMove={(e)=>this.touchMove(e)} onTouchEnd={(e)=>this.touchEnd(e)}></div>
                  </div>
                  
                  <div className="inline-block play-time">
                    <div className="inline-block played-time">{this.state.timeCurrent}</div>
                    <div className="inline-block">/</div>
                    <div className="inline-block audio-time" id="audioTime">{this.state.voiceDuration}</div>
                  </div> 
                </div>
                <div className="inline-block voice-control">
                  <a className="play-pause" id="playPause" onClick={()=>this.play()}>
                    <div className="play-icon">{ this.state.isPlay ? "点击暂停" : "点击播放" }</div>
                  </a>
                </div>
              </div>
            </div>
            
          </div>
      </div>
    );
  }
}

ReactDOM.render(<VoiceRead />, document.getElementById("banner-page"));

              
            
!
999px

Console