-
Notifications
You must be signed in to change notification settings - Fork 48
Expand file tree
/
Copy pathTimeline.min.js
More file actions
1 lines (1 loc) · 6.16 KB
/
Copy pathTimeline.min.js
File metadata and controls
1 lines (1 loc) · 6.16 KB
1
let BMapLib=window.BMapLib||{};const prefix="BMapLib";class Timeline{constructor(t){this.options=t,this.listeners={},this._interval=t.interval||1e3,this._playTimeId=null,this._playStatus="pause",this._startX,this._progressMax=0,this._playIndex=0,this._progress=0,this._steps=[],this._times=t.times||[],this._ctx=document.createElement("canvas").getContext("2d"),this._startScrollIndex=-1,this._scrollIndex=1,this._container=null,this._playButton=t.playButton?t.playButton:document.createTextNode("播放"),this._pauseButton=t.pauseButton?t.pauseButton:document.createTextNode("暂停"),this._initDom(t),this._drawTime()}_initDom(){if(this.element=document.createElement("div"),this.element.className=`${prefix}-timeline`,this.options.className&&(this.element.className+=` ${this.options.className}`),this._startButton=document.createElement("div"),this._startButton.className=`${prefix}-timeline-play`,this._startButton.innerHTML="",this._startButton.appendChild(this._playButton),this.element.appendChild(this._startButton),this._scrollDiv=document.createElement("div"),this._scrollDiv.className=`${prefix}-timeline-main`,this.element.appendChild(this._scrollDiv),this._ul=document.createElement("ul"),this._scrollDiv.appendChild(this._ul),this._progressDiv=document.createElement("div"),this._progressDiv.className=`${prefix}-timeline-progress`,this.options.progressButtonStyle&&this._applyStyle(this._progressDiv,this.options.progressButtonStyle),this._scrollDiv.appendChild(this._progressDiv),this._onPlayChange=this._onPlayChange.bind(this),this._onProgressDragStart=this._onProgressDragStart.bind(this),this._onProgressDrag=this._onProgressDrag.bind(this),this._onProgressDragEnd=this._onProgressDragEnd.bind(this),this._startButton.addEventListener("click",this._onPlayChange),this._progressDiv.addEventListener("mousedown",this._onProgressDragStart),this.options.customContainer)this._container=this.options.customContainer,this.options.customContainer.appendChild(this.element);else{if(!this.options.map)throw new Error("options.map or options.customContainer is required");this._container=this.options.map.getContainer(),this.options.map.getContainer().appendChild(this.element)}this._startX=this._scrollDiv.getBoundingClientRect().left}on(t,s){this.listeners[t]||(this.listeners[t]=[]),this.listeners[t].push(s)}un(t,s){if(this.listeners[t]){let e=this.listeners[t].indexOf(s);e>-1&&this.listeners[t].splice(e,1)}}dispatchEvent(t){if(this.listeners[t.type])for(let s=0;s<this.listeners[t.type].length;s++)this.listeners[t.type][s](t)}pause(){"pause"!==this._playStatus&&this._onPlayChange()}play(){"play"!==this._playStatus&&this._onPlayChange()}_drawTime(){let t=0,s=0;for(let e=0;e<this._times.length;e++){const i=this._times[e],n=document.createElement("li"),r=document.createElement("div"),o=document.createElement("span");o.innerText=i,this.options.timeStyle&&this._applyStyle(o,this.options.timeStyle),n.appendChild(r),n.appendChild(o),r.className=`${prefix}-time-item`,0===e&&(r.className=`${prefix}-time-item ${prefix}-time-start`),e===this._times.length-1&&(r.className=`${prefix}-time-item ${prefix}-time-end`),this.options.scrollStyle&&this._applyStyle(r,this.options.scrollStyle);const l=document.createElement("div");l.className=`${prefix}-time-divider`,this.options.dividerStyle&&this._applyStyle(l,this.options.dividerStyle),n.appendChild(l),this._ul.appendChild(n),this._ctx.font=getComputedStyle(o).font;const h=this._ctx.measureText(i).width+16;r.style.width=h+"px";let a=h/2;s+=h;const p={time:i,start:t,end:s-a,index:e};t=s-a+1,this._steps.push(p)}this._progressMax=s,this._calcStartScrollIndex()}_calcStartScrollIndex(){const t=this._scrollDiv.clientWidth;let s=0;for(let e=0;e<this._steps.length-1;e++)if(this._steps[e].end>t){s=e;break}this._startScrollIndex=s}_onProgressDrag(t){const s=t.clientX-this._startX+this._scrollDiv.scrollLeft;s>=0&&s<=this._progressMax&&this._updateProgress(s)}_onProgressDragEnd(t){const s=t.clientX-this._startX,e=this._getStepByProgress(s);e?(this.dispatchEvent({type:"change",time:e.time}),this._playIndex=e.index):this._playIndex=this._steps.length,document.removeEventListener("mousemove",this._onProgressDrag),document.removeEventListener("mouseup",this._onProgressDragEnd)}_onProgressDragStart(t){clearTimeout(this._playTimeId),this._playStatus="pause",this._startButton.innerHTML="",this._startButton.appendChild(this._playButton),document.addEventListener("mousemove",this._onProgressDrag),document.addEventListener("mouseup",this._onProgressDragEnd)}_onPlayChange(){if(this._playTimeId&&clearTimeout(this._playTimeId),this._playIndex>=this._steps.length)this._playIndex=0,this._scrollIndex=1,this._scrollDiv.scrollLeft=0,this._progressDiv.style.left=0;else{let t=this._getStepByProgress(this._progress);this._playIndex=t?t.index:this._steps.length}if("pause"===this._playStatus){this.dispatchEvent({type:"playstart"});const t=()=>{this._playTimeId=setTimeout(t,this._interval);let s=this._steps[this._playIndex++];s&&this._updateProgressByStep(s),this._playIndex>=this._steps.length&&(clearTimeout(this._playTimeId),this._playStatus="pause",this._startButton.innerHTML="",this._startButton.appendChild(this._playButton),this.dispatchEvent({type:"playend"}))};this._playTimeId=setTimeout(t,this._interval),this._playStatus="play",this._startButton.innerHTML="",this._startButton.appendChild(this._pauseButton)}else this._playStatus="pause",this._startButton.innerHTML="",this._startButton.appendChild(this._playButton),this.dispatchEvent({type:"playend"}),clearTimeout(this._playTimeId)}_updateProgressByStep(t){this.dispatchEvent({type:"change",time:t.time}),this._progress=t.end,this._progressDiv.style.left=this._progress-5+"px",this._startScrollIndex>0&&t.end>=this._steps[this._startScrollIndex].end&&(this._scrollDiv.scrollLeft=this._steps[this._scrollIndex++].end)}_getStepByProgress(t){for(let s=0;s<this._steps.length;s++){const e=this._steps[s];if(e.start<=t&&e.end>=t)return e}}_updateProgress(t){this._progress=t,this._progressDiv.style.left=t+"px"}_applyStyle(t,s){for(let e in s)t.style[e]=s[e]}destroy(){this._startButton.removeEventListener("click",this._onPlayChange),this._progressDiv.removeEventListener("mousedown",this._onProgressDragStart),this._container.removeChild(this.element)}}BMapLib.Timeline=Timeline;