feat:drag and drop element

pr675
Hufe921 3 years ago
parent 9f64a068b1
commit 9b9a0a09ae

@ -122,8 +122,7 @@ export class CheckboxControl implements IControlInstance {
} }
public cut(): number { public cut(): number {
const { endIndex } = this.control.getRange() return -1
return endIndex
} }
} }

@ -1,36 +1,88 @@
import { EDITOR_ELEMENT_STYLE_ATTR } from '../../../dataset/constant/Element' import { EDITOR_ELEMENT_STYLE_ATTR } from '../../../dataset/constant/Element'
import { ControlComponent, ControlType } from '../../../dataset/enum/Control'
import { ElementType } from '../../../dataset/enum/Element'
import { IElement } from '../../../interface/Element' import { IElement } from '../../../interface/Element'
import { deepClone, getUUID } from '../../../utils'
import { formatElementList } from '../../../utils/element'
import { CanvasEvent } from '../CanvasEvent' import { CanvasEvent } from '../CanvasEvent'
type IDragElement = IElement & { dragId: string }
function createDragId(element: IElement): string {
const dragId = getUUID()
Reflect.set(element, 'dragId', dragId)
return dragId
}
function getElementIndexByDragId(dragId: string, elementList: IElement[]) {
return (<IDragElement[]>elementList).findIndex((el) => el.dragId === dragId)
}
export function mouseup(evt: MouseEvent, host: CanvasEvent) { export function mouseup(evt: MouseEvent, host: CanvasEvent) {
// 判断是否允许拖放 // 判断是否允许拖放
if (host.isAllowDrop) { if (host.isAllowDrop) {
const draw = host.getDraw() const draw = host.getDraw()
const position = draw.getPosition() const position = draw.getPosition()
const positionList = position.getPositionList()
const rangeManager = draw.getRange() const rangeManager = draw.getRange()
const cacheRange = host.cacheRange! const cacheRange = host.cacheRange!
const cacheElementList = host.cacheElementList! const cacheElementList = host.cacheElementList!
const cachePositionList = host.cachePositionList! const cachePositionList = host.cachePositionList!
// 如果同一上下文拖拽位置向后移动,则重置光标位置
const range = rangeManager.getRange() const range = rangeManager.getRange()
const elementList = draw.getElementList() // 是否是不可拖拽的控件结构元素
const positionList = position.getPositionList() const dragElementList = cacheElementList.slice(cacheRange.startIndex + 1, cacheRange.endIndex + 1)
const startPosition = positionList[range.startIndex] const isContainControl = dragElementList.find(element =>
const cacheStartElement = cacheElementList[cacheRange.startIndex] element.type === ElementType.CONTROL ||
const startElement = elementList[range.startIndex] element.type === ElementType.DATE
let curIndex = range.startIndex )
if (cacheStartElement.tdId === startElement.tdId && range.startIndex > cacheRange.endIndex) { if (isContainControl) {
curIndex -= (cacheRange.endIndex - cacheRange.startIndex) // 仅允许 (最前/后元素不是控件 || 在控件前后 || 文本控件且是值) 拖拽
const cacheStartElement = cacheElementList[cacheRange.startIndex + 1]
const cacheEndElement = cacheElementList[cacheRange.endIndex]
const isAllowDragControl =
(
(
cacheStartElement.type !== ElementType.CONTROL ||
cacheStartElement.controlComponent === ControlComponent.PREFIX
) &&
(
cacheEndElement.type !== ElementType.CONTROL ||
cacheEndElement.controlComponent === ControlComponent.POSTFIX
) &&
cacheStartElement.type !== ElementType.DATE &&
cacheEndElement.type !== ElementType.DATE
) ||
(
cacheStartElement.controlId === cacheEndElement.controlId &&
cacheStartElement.controlComponent === ControlComponent.PREFIX &&
cacheEndElement.controlComponent === ControlComponent.POSTFIX
) ||
(
cacheStartElement.control?.type === ControlType.TEXT &&
cacheStartElement.controlComponent === ControlComponent.VALUE &&
cacheEndElement.control?.type === ControlType.TEXT &&
cacheEndElement.controlComponent === ControlComponent.VALUE
)
if (!isAllowDragControl) {
draw.render({
curIndex: range.startIndex,
isCompute: false,
isSubmitHistory: false
})
return
}
} }
// 删除原有拖拽元素
const deleteElementList = cacheElementList.splice(cacheRange.startIndex + 1, cacheRange.endIndex - cacheRange.startIndex)
// 格式化元素 // 格式化元素
const editorOptions = draw.getOptions()
const elementList = draw.getElementList()
const anchorElement = elementList[range.startIndex]
let restArg = {} let restArg = {}
if (startElement.tableId) { if (anchorElement.tableId) {
const { tdId, trId, tableId } = startElement const { tdId, trId, tableId } = anchorElement
restArg = { tdId, trId, tableId } restArg = { tdId, trId, tableId }
} }
const replaceElementList = deleteElementList.map(el => { const replaceElementList = dragElementList.map(el => {
if (!el.type || el.type === ElementType.TEXT || el.control?.type === ControlType.TEXT) {
const newElement: IElement = { const newElement: IElement = {
value: el.value, value: el.value,
...restArg ...restArg
@ -42,9 +94,57 @@ export function mouseup(evt: MouseEvent, host: CanvasEvent) {
} }
}) })
return newElement return newElement
} else {
const newElement = deepClone(el)
formatElementList([newElement], {
isHandleFirstElement: false,
editorOptions,
})
return newElement
}
})
// 缓存拖拽选区开始结束id
const cacheRangeStartId = createDragId(cacheElementList[cacheRange.startIndex])
const cacheRangeEndId = createDragId(cacheElementList[cacheRange.endIndex])
// 设置拖拽值
const replaceLength = replaceElementList.length
let rangeStart = range.startIndex
let rangeEnd = rangeStart + replaceLength
const control = draw.getControl()
const activeControl = control.getActiveControl()
if (activeControl && cacheElementList[rangeStart].controlComponent !== ControlComponent.POSTFIX) {
rangeEnd = activeControl.setValue(replaceElementList)
rangeStart = rangeEnd - replaceLength
} else {
elementList.splice(rangeStart + 1, 0, ...replaceElementList)
}
if (!~rangeEnd) {
draw.render({
isSetCursor: false
})
return
}
// 缓存当前开始结束id
const rangeStartId = createDragId(elementList[rangeStart])
const rangeEndId = createDragId(elementList[rangeEnd])
// 删除原有拖拽元素
const cacheRangeStartIndex = getElementIndexByDragId(cacheRangeStartId, cacheElementList)
const cacheRangeEndIndex = getElementIndexByDragId(cacheRangeEndId, cacheElementList)
const cacheEndElement = cacheElementList[cacheRangeEndIndex]
if (cacheEndElement.type === ElementType.CONTROL && cacheEndElement.controlComponent !== ControlComponent.POSTFIX) {
rangeManager.replaceRange({
...cacheRange,
startIndex: cacheRangeStartIndex,
endIndex: cacheRangeEndIndex
}) })
elementList.splice(curIndex + 1, 0, ...replaceElementList) control.getActiveControl()?.cut()
} else {
cacheElementList.splice(cacheRangeStartIndex + 1, cacheRangeEndIndex - cacheRangeStartIndex)
}
// 重设上下文 // 重设上下文
const startElement = elementList[range.startIndex]
const cacheStartElement = cacheElementList[cacheRange.startIndex]
const startPosition = positionList[range.startIndex]
const cacheStartPosition = cachePositionList[cacheRange.startIndex] const cacheStartPosition = cachePositionList[cacheRange.startIndex]
const positionContext = position.getPositionContext() const positionContext = position.getPositionContext()
let positionContextIndex = positionContext.index let positionContextIndex = positionContext.index
@ -52,12 +152,12 @@ export function mouseup(evt: MouseEvent, host: CanvasEvent) {
if (startElement.tableId && !cacheStartElement.tableId) { if (startElement.tableId && !cacheStartElement.tableId) {
// 表格外移动到表格内&&表格之前 // 表格外移动到表格内&&表格之前
if (cacheStartPosition.index < positionContextIndex) { if (cacheStartPosition.index < positionContextIndex) {
positionContextIndex -= deleteElementList.length positionContextIndex -= replaceLength
} }
} else if (!startElement.tableId && cacheStartElement.tableId) { } else if (!startElement.tableId && cacheStartElement.tableId) {
// 表格内移到表格外&&表格之前 // 表格内移到表格外&&表格之前
if (startPosition.index < positionContextIndex) { if (startPosition.index < positionContextIndex) {
positionContextIndex += deleteElementList.length positionContextIndex += replaceLength
} }
} }
position.setPositionContext({ position.setPositionContext({
@ -65,25 +165,24 @@ export function mouseup(evt: MouseEvent, host: CanvasEvent) {
index: positionContextIndex index: positionContextIndex
}) })
} }
// 设置选区 // 重设选区
const rangeStartIndex = getElementIndexByDragId(rangeStartId, elementList)
const rangeEndIndex = getElementIndexByDragId(rangeEndId, elementList)
rangeManager.setRange( rangeManager.setRange(
curIndex, rangeStartIndex,
curIndex + deleteElementList.length, rangeEndIndex,
range.tableId, range.tableId,
range.startTdIndex, range.startTdIndex,
range.endTdIndex, range.endTdIndex,
range.startTrIndex, range.startTrIndex,
range.endTrIndex range.endTrIndex
) )
// 重新渲染&重设状态 // 重新渲染
draw.render({ draw.render({
isSetCursor: false isSetCursor: false
}) })
host.isAllowDrag = false
host.isAllowDrop = false
} else if (host.isAllowDrag) { } else if (host.isAllowDrag) {
// 如果是允许拖拽不允许拖放则光标重置 // 如果是允许拖拽不允许拖放则光标重置
host.mousedown(evt) host.mousedown(evt)
host.isAllowDrag = false
} }
} }

@ -103,6 +103,18 @@ export class RangeManager {
control.destroyControl() control.destroyControl()
} }
public replaceRange(range: IRange) {
this.setRange(
range.startIndex,
range.endIndex,
range.tableId,
range.startTdIndex,
range.endTdIndex,
range.startTrIndex,
range.endTrIndex
)
}
public setRangeStyle() { public setRangeStyle() {
if (!this.listener.rangeStyleChange) return if (!this.listener.rangeStyleChange) return
let curElementList = this.getSelection() let curElementList = this.getSelection()

Loading…
Cancel
Save