feat:add checkbox interactive
This commit is contained in:
@@ -569,10 +569,10 @@ export class Draw {
|
||||
metrics.height = this.options.defaultSize
|
||||
} else if (element.type === ElementType.CHECKBOX) {
|
||||
const { width, height, gap } = this.options.checkbox
|
||||
const elementWidth = width + gap * 2
|
||||
const elementWidth = (width + gap * 2) * scale
|
||||
element.width = elementWidth
|
||||
metrics.width = elementWidth
|
||||
metrics.height = height
|
||||
metrics.height = height * scale
|
||||
} else {
|
||||
// 设置上下标真实字体尺寸
|
||||
const size = element.size || this.options.defaultSize
|
||||
|
||||
@@ -12,24 +12,39 @@ export class CheckboxParticle {
|
||||
}
|
||||
|
||||
public render(ctx: CanvasRenderingContext2D, element: IRowElement, x: number, y: number) {
|
||||
const { checkbox: { gap, lineWidth } } = this.options
|
||||
const { checkbox: { gap, lineWidth, fillStyle, fontStyle }, scale } = this.options
|
||||
const { metrics, checkbox } = element
|
||||
// left top 四舍五入避免1像素问题
|
||||
const left = Math.round(x + gap)
|
||||
const top = Math.round(y - metrics.height + lineWidth)
|
||||
const width = metrics.width - gap * 2
|
||||
const width = metrics.width - gap * 2 * scale
|
||||
const height = metrics.height
|
||||
ctx.save()
|
||||
ctx.beginPath()
|
||||
ctx.translate(0.5, 0.5)
|
||||
ctx.lineWidth = lineWidth
|
||||
ctx.rect(left, top, width, height)
|
||||
ctx.stroke()
|
||||
// 绘制勾选状态
|
||||
if (checkbox?.value) {
|
||||
ctx.moveTo(left + 2, top + 7)
|
||||
ctx.lineTo(left + 6, top + 12)
|
||||
ctx.lineTo(left + 12, top + 3)
|
||||
// 边框
|
||||
ctx.lineWidth = lineWidth
|
||||
ctx.strokeStyle = fillStyle
|
||||
ctx.rect(left, top, width, height)
|
||||
ctx.stroke()
|
||||
// 背景色
|
||||
ctx.beginPath()
|
||||
ctx.fillStyle = fillStyle
|
||||
ctx.fillRect(left, top, width, height)
|
||||
// 勾选对号
|
||||
ctx.beginPath()
|
||||
ctx.strokeStyle = fontStyle
|
||||
ctx.lineWidth = lineWidth * 2
|
||||
ctx.moveTo(left + 2 * scale, top + 7 * scale)
|
||||
ctx.lineTo(left + 7 * scale, top + 11 * scale)
|
||||
ctx.moveTo(left + 6.5 * scale, top + 11 * scale)
|
||||
ctx.lineTo(left + 12 * scale, top + 3 * scale)
|
||||
ctx.stroke()
|
||||
} else {
|
||||
ctx.lineWidth = lineWidth
|
||||
ctx.rect(left, top, width, height)
|
||||
ctx.stroke()
|
||||
}
|
||||
ctx.closePath()
|
||||
|
||||
@@ -188,6 +188,7 @@ export class CanvasEvent {
|
||||
const {
|
||||
index,
|
||||
isDirectHit,
|
||||
isCheckbox,
|
||||
isControl,
|
||||
isImage,
|
||||
isTable,
|
||||
@@ -214,27 +215,34 @@ export class CanvasEvent {
|
||||
...positionResult,
|
||||
index: isTable ? tdValueIndex! : index
|
||||
}
|
||||
// 绘制
|
||||
const isDirectHitImage = isDirectHit && isImage
|
||||
if (~index) {
|
||||
let curIndex = index
|
||||
if (isTable) {
|
||||
this.range.setRange(tdValueIndex!, tdValueIndex!)
|
||||
curIndex = tdValueIndex!
|
||||
} else {
|
||||
this.range.setRange(index, index)
|
||||
}
|
||||
this.draw.render({
|
||||
curIndex,
|
||||
isSubmitHistory: false,
|
||||
isSetCursor: !isDirectHitImage,
|
||||
isComputeRowList: false
|
||||
})
|
||||
}
|
||||
const elementList = this.draw.getElementList()
|
||||
const positionList = this.position.getPositionList()
|
||||
const curIndex = isTable ? tdValueIndex! : index
|
||||
const curElement = elementList[curIndex]
|
||||
// 绘制
|
||||
const isDirectHitImage = !!(isDirectHit && isImage)
|
||||
const isDirectHitCheckbox = !!(isDirectHit && isCheckbox)
|
||||
if (~index) {
|
||||
this.range.setRange(index, index)
|
||||
// 复选框
|
||||
const isSetCheckbox = isDirectHitCheckbox && !isReadonly
|
||||
if (isSetCheckbox) {
|
||||
const { checkbox } = curElement
|
||||
if (checkbox) {
|
||||
checkbox.value = !checkbox.value
|
||||
} else {
|
||||
curElement.checkbox = {
|
||||
value: true
|
||||
}
|
||||
}
|
||||
}
|
||||
this.draw.render({
|
||||
curIndex,
|
||||
isSubmitHistory: isSetCheckbox,
|
||||
isSetCursor: !isDirectHitImage && !isDirectHitCheckbox,
|
||||
isComputeRowList: false
|
||||
})
|
||||
}
|
||||
// 图片尺寸拖拽组件
|
||||
this.imageParticle.clearResizer()
|
||||
if (isDirectHitImage && !isReadonly) {
|
||||
|
||||
@@ -119,6 +119,13 @@ export class Position {
|
||||
isImage: true
|
||||
}
|
||||
}
|
||||
if (element.type === ElementType.CHECKBOX) {
|
||||
return {
|
||||
index: curPositionIndex,
|
||||
isDirectHit: true,
|
||||
isCheckbox: true
|
||||
}
|
||||
}
|
||||
// 判断是否在文字中间前后
|
||||
if (elementList[index].value !== ZERO) {
|
||||
const valueWidth = rightTop[0] - leftTop[0]
|
||||
|
||||
@@ -4,5 +4,7 @@ export const defaultCheckboxOption: Readonly<Required<ICheckboxOption>> = {
|
||||
width: 14,
|
||||
height: 14,
|
||||
gap: 5,
|
||||
lineWidth: 1
|
||||
lineWidth: 1,
|
||||
fillStyle: '#5175f4',
|
||||
fontStyle: '#ffffff'
|
||||
}
|
||||
@@ -8,4 +8,6 @@ export interface ICheckboxOption {
|
||||
height?: number;
|
||||
gap?: number;
|
||||
lineWidth?: number;
|
||||
fillStyle?: string;
|
||||
fontStyle?: string;
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import { ITd } from './table/Td'
|
||||
|
||||
export interface ICurrentPosition {
|
||||
index: number;
|
||||
isCheckbox?: boolean;
|
||||
isControl?: boolean;
|
||||
isImage?: boolean;
|
||||
isTable?: boolean;
|
||||
|
||||
Reference in New Issue
Block a user