196 lines
4.5 KiB
Vue
196 lines
4.5 KiB
Vue
|
|
<template>
|
|||
|
|
<div ref="windowListItem" class="windowListItem" :class="{active: active}" @click="onClick">
|
|||
|
|
<span class="order">{{ index + 1 }}</span>
|
|||
|
|
<canvas ref="canvas" class="windowListItemCanvas" />
|
|||
|
|
</div>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script>
|
|||
|
|
export default {
|
|||
|
|
name: 'WindowListItem',
|
|||
|
|
props: {
|
|||
|
|
index: {
|
|||
|
|
type: Number
|
|||
|
|
},
|
|||
|
|
data: {
|
|||
|
|
type: Object,
|
|||
|
|
default() {
|
|||
|
|
return {}
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
totalMS: {
|
|||
|
|
type: Number
|
|||
|
|
},
|
|||
|
|
startTimestamp: {
|
|||
|
|
type: Number
|
|||
|
|
},
|
|||
|
|
width: {
|
|||
|
|
type: Number
|
|||
|
|
},
|
|||
|
|
active: {
|
|||
|
|
type: Boolean,
|
|||
|
|
default: false
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
data() {
|
|||
|
|
return {
|
|||
|
|
height: 0,
|
|||
|
|
ctx: null
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
mounted() {
|
|||
|
|
this.init()
|
|||
|
|
this.drawTimeSegments()
|
|||
|
|
},
|
|||
|
|
methods: {
|
|||
|
|
/**
|
|||
|
|
* @Author: 王林25
|
|||
|
|
* @Date: 2020-04-14 09:20:22
|
|||
|
|
* @Desc: 初始化
|
|||
|
|
*/
|
|||
|
|
init() {
|
|||
|
|
const { height } = this.$refs.windowListItem.getBoundingClientRect()
|
|||
|
|
this.height = height - 1
|
|||
|
|
this.$refs.canvas.width = this.width
|
|||
|
|
this.$refs.canvas.height = this.height
|
|||
|
|
this.ctx = this.$refs.canvas.getContext('2d')
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @Author: 王林25
|
|||
|
|
* @Date: 2020-04-14 15:42:49
|
|||
|
|
* @Desc: 绘制时间段
|
|||
|
|
*/
|
|||
|
|
drawTimeSegments(callback, path) {
|
|||
|
|
if (!this.data.timeSegments || this.data.timeSegments.length <= 0) {
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
const PX_PER_MS = this.width / this.totalMS // px/ms,每毫秒占的像素
|
|||
|
|
this.data.timeSegments.forEach((item) => {
|
|||
|
|
if (
|
|||
|
|
item.beginTime <= this.startTimestamp + this.totalMS &&
|
|||
|
|
item.endTime >= this.startTimestamp
|
|||
|
|
) {
|
|||
|
|
this.ctx.beginPath()
|
|||
|
|
let x = (item.beginTime - this.startTimestamp) * PX_PER_MS
|
|||
|
|
let w
|
|||
|
|
if (x < 0) {
|
|||
|
|
x = 0
|
|||
|
|
w = (item.endTime - this.startTimestamp) * PX_PER_MS
|
|||
|
|
} else {
|
|||
|
|
w = (item.endTime - item.beginTime) * PX_PER_MS
|
|||
|
|
}
|
|||
|
|
const heightStartRatio = item.startRatio === undefined ? 0.6 : item.startRatio
|
|||
|
|
const heightEndRatio = item.endRatio === undefined ? 0.9 : item.endRatio
|
|||
|
|
if (path) {
|
|||
|
|
this.ctx.rect(
|
|||
|
|
x,
|
|||
|
|
this.height * heightStartRatio,
|
|||
|
|
w,
|
|||
|
|
this.height * (heightEndRatio - heightStartRatio)
|
|||
|
|
)
|
|||
|
|
} else {
|
|||
|
|
this.ctx.fillStyle = item.color
|
|||
|
|
this.ctx.fillRect(
|
|||
|
|
x,
|
|||
|
|
this.height * heightStartRatio,
|
|||
|
|
w,
|
|||
|
|
this.height * (heightEndRatio - heightStartRatio)
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
callback && callback(item)
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @Author: 王林25
|
|||
|
|
* @Date: 2020-04-14 14:25:43
|
|||
|
|
* @Desc: 清除画布
|
|||
|
|
*/
|
|||
|
|
clearCanvas() {
|
|||
|
|
this.ctx.clearRect(0, 0, this.width, this.height)
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @Author: 王林25
|
|||
|
|
* @Date: 2021-01-20 19:07:31
|
|||
|
|
* @Desc: 绘制
|
|||
|
|
*/
|
|||
|
|
draw() {
|
|||
|
|
this.$nextTick(() => {
|
|||
|
|
this.clearCanvas()
|
|||
|
|
this.drawTimeSegments()
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @Author: 王林25
|
|||
|
|
* @Date: 2021-01-20 19:26:46
|
|||
|
|
* @Desc: 点击事件
|
|||
|
|
*/
|
|||
|
|
onClick(e) {
|
|||
|
|
this.$emit('click', e)
|
|||
|
|
const { left, top } = this.$refs.windowListItem.getBoundingClientRect()
|
|||
|
|
const x = e.clientX - left
|
|||
|
|
const y = e.clientY - top
|
|||
|
|
const timeSegments = this.getClickTimeSegments(x, y)
|
|||
|
|
if (timeSegments.length > 0) {
|
|||
|
|
this.$emit('click_window_timeSegments', timeSegments, this.index, this.data)
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @Author: 王林25
|
|||
|
|
* @Date: 2021-01-20 16:24:54
|
|||
|
|
* @Desc: 检测当前是否点击了某个时间段
|
|||
|
|
*/
|
|||
|
|
getClickTimeSegments(x, y) {
|
|||
|
|
if (!this.data.timeSegments || this.data.timeSegments.length <= 0) {
|
|||
|
|
return []
|
|||
|
|
}
|
|||
|
|
const inItems = []
|
|||
|
|
this.drawTimeSegments((item) => {
|
|||
|
|
if (this.ctx.isPointInPath(x, y)) {
|
|||
|
|
inItems.push(item)
|
|||
|
|
}
|
|||
|
|
}, true)
|
|||
|
|
return inItems
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @Author: 王林25
|
|||
|
|
* @Date: 2021-01-21 11:25:26
|
|||
|
|
* @Desc: 获取位置信息
|
|||
|
|
*/
|
|||
|
|
getRect() {
|
|||
|
|
return this.$refs.windowListItem ? this.$refs.windowListItem.getBoundingClientRect() : null
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<style scoped>
|
|||
|
|
.windowListItem {
|
|||
|
|
width: 100%;
|
|||
|
|
height: 30px;
|
|||
|
|
position: relative;
|
|||
|
|
border-bottom: 1px solid #999999;
|
|||
|
|
user-select: none;
|
|||
|
|
}
|
|||
|
|
.windowListItem.active {
|
|||
|
|
background-color: #000;
|
|||
|
|
}
|
|||
|
|
.windowListItem .order {
|
|||
|
|
position: absolute;
|
|||
|
|
width: 30px;
|
|||
|
|
height: 30px;
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: center;
|
|||
|
|
align-items: center;
|
|||
|
|
color: #fff;
|
|||
|
|
border-right: 1px solid #999999;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
</style>
|