|
|
@@ -19,10 +19,12 @@ const canvasRef = ref<HTMLCanvasElement | null>(null)
|
|
|
const img = new window.Image()
|
|
|
img.src = props.cardData.img
|
|
|
|
|
|
+type Rect = { id: number, name: string, x: number, y: number, width: number, height: number, music_name: string, selected: boolean }
|
|
|
+
|
|
|
// 矩形参数
|
|
|
const rectWidth = 180
|
|
|
const rectHeight = 240
|
|
|
-const rects = [] as { id: number, name: string, x: number, y: number, width: number, height: number }[]
|
|
|
+const rects = [] as Rect[]
|
|
|
const rectGapX = 127 // 矩形间横向间隔
|
|
|
const rectGapY = 146 // 矩形间纵向间隔
|
|
|
const startX = 112 // 图片内第一个矩形的x偏移
|
|
|
@@ -31,25 +33,32 @@ const startY = -56 // 图片内第一个矩形的y偏移
|
|
|
// 未选择 选中了但是没有音频 选中了有音频 三种模式的矩形样式
|
|
|
const rectStyles = {
|
|
|
unselected: {
|
|
|
- fillStyle: 'rgba(255, 255, 255, 0.5)',
|
|
|
+ fillStyle: '007bff22',
|
|
|
strokeStyle: '#007bff',
|
|
|
lineWidth: 2,
|
|
|
lineDash: []
|
|
|
},
|
|
|
selectedNoAudio: {
|
|
|
- fillStyle: 'rgba(255, 0, 0, 0.5)',
|
|
|
+ fillStyle: '007bff22',
|
|
|
strokeStyle: '#ff0000',
|
|
|
lineWidth: 2,
|
|
|
lineDash: [4, 6]
|
|
|
},
|
|
|
selectedWithAudio: {
|
|
|
- fillStyle: 'rgba(0, 255, 0, 0.5)',
|
|
|
+ fillStyle: 'ff660033',
|
|
|
strokeStyle: '#ff6600',
|
|
|
lineWidth: 2,
|
|
|
lineDash: []
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+const generateRectStyle = (rect: Rect) => {
|
|
|
+ if (rect.selected) {
|
|
|
+ return rect.music_name ? rectStyles.selectedWithAudio : rectStyles.selectedNoAudio
|
|
|
+ }
|
|
|
+ return rectStyles.unselected
|
|
|
+}
|
|
|
+
|
|
|
// 生成矩形数据
|
|
|
function generateRects () {
|
|
|
rects.length = 0
|
|
|
@@ -63,7 +72,9 @@ function generateRects () {
|
|
|
x: startX + item.id * (rectWidth - 40 + firstRowGapX) + 1166,
|
|
|
y: startY + 116,
|
|
|
width: rectWidth - 40,
|
|
|
- height: rectHeight - 100
|
|
|
+ height: rectHeight - 100,
|
|
|
+ music_name: item.music_name || '',
|
|
|
+ selected: item.selected
|
|
|
})
|
|
|
}
|
|
|
} else {
|
|
|
@@ -73,7 +84,9 @@ function generateRects () {
|
|
|
x: startX + item.col * (rectWidth + rectGapX),
|
|
|
y: startY + item.row * (rectHeight + rectGapY),
|
|
|
width: rectWidth,
|
|
|
- height: rectHeight
|
|
|
+ height: rectHeight,
|
|
|
+ music_name: item.music_name || '',
|
|
|
+ selected: item.selected
|
|
|
})
|
|
|
}
|
|
|
})
|
|
|
@@ -168,12 +181,13 @@ function draw () {
|
|
|
const rh = rect.height * state.scale
|
|
|
ctx.save()
|
|
|
ctx.lineWidth = 2
|
|
|
- const isSelected = rect.id === state.selectedRectId || props.config.touch_key.find(item => item.id === rect.id)?.selected
|
|
|
+ const isSelected = rect.selected
|
|
|
ctx.strokeStyle = isSelected ? '#ff6600' : '#007bff'
|
|
|
ctx.globalAlpha = 0.5
|
|
|
ctx.fillStyle = isSelected ? '#ff660033' : '#007bff22'
|
|
|
ctx.fillRect(rx, ry, rw, rh)
|
|
|
ctx.globalAlpha = 1
|
|
|
+ ctx.setLineDash([]) // 确保边框为实线
|
|
|
ctx.strokeRect(rx, ry, rw, rh)
|
|
|
// 绘制序号
|
|
|
ctx.font = `bold ${Math.floor(rh / 1.7)}px sans-serif`
|
|
|
@@ -181,25 +195,11 @@ function draw () {
|
|
|
ctx.lineWidth = 1
|
|
|
ctx.textAlign = 'center'
|
|
|
ctx.textBaseline = 'middle'
|
|
|
- ctx.setLineDash([]) // 设置为实线
|
|
|
+ // 根据选中状态设置线条样式
|
|
|
+ ctx.setLineDash(isSelected ? [] : []) // 选中时使用虚线,否则实线
|
|
|
ctx.strokeText(rect.name, rx + rw / 2, ry + rh / 2)
|
|
|
ctx.restore()
|
|
|
})
|
|
|
-
|
|
|
- // 画选择框
|
|
|
- // if (selection.selecting) {
|
|
|
- // ctx.save()
|
|
|
- // ctx.strokeStyle = '#1890ff'
|
|
|
- // ctx.setLineDash([6, 4])
|
|
|
- // ctx.lineWidth = 2
|
|
|
- // ctx.globalAlpha = 0.7
|
|
|
- // const x = Math.min(selection.startX, selection.endX)
|
|
|
- // const y = Math.min(selection.startY, selection.endY)
|
|
|
- // const w = Math.abs(selection.endX - selection.startX)
|
|
|
- // const h = Math.abs(selection.endY - selection.startY)
|
|
|
- // ctx.strokeRect(x, y, w, h)
|
|
|
- // ctx.restore()
|
|
|
- // }
|
|
|
}
|
|
|
}
|
|
|
|