129 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			129 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <template>
 | |
|   <div :class="wrapper" class="canvas" v-if="isInit">
 | |
|     <canvas
 | |
|       :id="id"
 | |
|       :style="{height: '10px'}"
 | |
|       v-if="canvasWidth"
 | |
|       :width="canvasWidth"
 | |
|       height="10">
 | |
|     </canvas>
 | |
|   </div>
 | |
| </template>
 | |
| 
 | |
| <script>
 | |
|   export default {
 | |
|     props: ['times', 'deviceId'],
 | |
| 
 | |
|     data () {
 | |
|       return {
 | |
|         ctx: null,
 | |
|         canvasWidth: '',
 | |
|         canvasHeight: '',
 | |
|         isInit: false,
 | |
|         wrapper: `canvas-${new Date().getTime()}`,
 | |
|         id: `timeline-${new Date().getTime()}-${this.deviceId}`,
 | |
|         timer: null
 | |
|       }
 | |
|     },
 | |
| 
 | |
|     watch: {
 | |
|       times: {
 | |
|         deep: true,
 | |
|         handler (v) {
 | |
|           if (v.length && this.ctx) {
 | |
|             this.init()
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     },
 | |
| 
 | |
|     mounted () {
 | |
|       this.$nextTick(() => {
 | |
|         this.init()
 | |
|       })
 | |
|     },
 | |
| 
 | |
|     destroyed () {
 | |
|       clearInterval(this.timer)
 | |
|     },
 | |
| 
 | |
|     methods: {
 | |
|       init () {
 | |
|         if (this.ctx) {
 | |
|           this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight)
 | |
|         }
 | |
|         this.isInit = false
 | |
|         this.$nextTick(() => {
 | |
|           this.isInit = true
 | |
|           this.$nextTick(() => {
 | |
|             this.canvasWidth = document.querySelector(`.${this.wrapper}`).offsetWidth
 | |
|             this.canvasHeight = document.querySelector(`.${this.wrapper}`).offsetHeight
 | |
| 
 | |
|             this.$nextTick(() => {
 | |
|               const el = document.querySelector(`#${this.id}`)
 | |
|               this.ctx = el.getContext('2d')
 | |
|               this.ctx.width  = document.querySelector('.canvas').offsetWidth
 | |
|               this.ctx.height  = document.querySelector('.canvas').offsetHeight
 | |
|               this.renderPlayback()
 | |
|             })
 | |
|           })
 | |
|         })
 | |
|       },
 | |
| 
 | |
|       countdown () {
 | |
|         this.timer = setInterval(() => {
 | |
|           if (this.isLiveing) {
 | |
|             this.initNowTime()
 | |
|           } else {
 | |
|             this.x = this.x + this.canvasWidth / (24 * 60 * 60)
 | |
|           }
 | |
|         }, 1000)
 | |
|       },
 | |
| 
 | |
|       initNowTime () {
 | |
|         const date = new Date()
 | |
|         const seconds = date.getHours() * 3600 + date.getMinutes() * 60 + date.getSeconds()
 | |
| 
 | |
|         this.x = this.canvasWidth / (24 * 60 * 60) * seconds
 | |
|       },
 | |
| 
 | |
|       drawLine(ctx, options) {
 | |
|         const { beginX, beginY, endX, endY, lineColor, lineWidth } = options
 | |
|         ctx.beginPath()
 | |
|         ctx.lineWidth = lineWidth
 | |
|         ctx.moveTo(beginX, beginY)
 | |
|         ctx.lineTo(endX, endY)
 | |
|         ctx.strokeStyle = lineColor
 | |
|         ctx.stroke()
 | |
|       },
 | |
| 
 | |
|       renderPlayback () {
 | |
|         const ctx = this.ctx
 | |
|         const unit = this.canvasWidth / (24 * 60 * 60)
 | |
|         this.times.forEach(item => {
 | |
|           this.drawLine(ctx, {
 | |
|             beginX: item.startTime * unit,
 | |
|             beginY: 28,
 | |
|             endX: item.startTime * unit,
 | |
|             endY: 0,
 | |
|             lineColor: 'rgba(0, 156, 255, 1)',
 | |
|             lineWidth: item.endTime * unit - item.startTime * unit
 | |
|           })
 | |
|         })
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| </script>
 | |
| 
 | |
| <style lang="scss" scoped>
 | |
|   .canvas {
 | |
|     position: relative;
 | |
|     width: 100%;
 | |
|     height: 10px;
 | |
| 
 | |
|     canvas {
 | |
|       width: 100%;
 | |
|       height: 10px;
 | |
|     }
 | |
|   }
 | |
| </style> |