feat:drag and drop element
This commit is contained in:
@@ -122,8 +122,7 @@ export class CheckboxControl implements IControlInstance {
|
||||
}
|
||||
|
||||
public cut(): number {
|
||||
const { endIndex } = this.control.getRange()
|
||||
return endIndex
|
||||
return -1
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,36 +1,88 @@
|
||||
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 { deepClone, getUUID } from '../../../utils'
|
||||
import { formatElementList } from '../../../utils/element'
|
||||
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) {
|
||||
// 判断是否允许拖放
|
||||
if (host.isAllowDrop) {
|
||||
const draw = host.getDraw()
|
||||
const position = draw.getPosition()
|
||||
const positionList = position.getPositionList()
|
||||
const rangeManager = draw.getRange()
|
||||
const cacheRange = host.cacheRange!
|
||||
const cacheElementList = host.cacheElementList!
|
||||
const cachePositionList = host.cachePositionList!
|
||||
// 如果同一上下文拖拽位置向后移动,则重置光标位置
|
||||
const range = rangeManager.getRange()
|
||||
const elementList = draw.getElementList()
|
||||
const positionList = position.getPositionList()
|
||||
const startPosition = positionList[range.startIndex]
|
||||
const cacheStartElement = cacheElementList[cacheRange.startIndex]
|
||||
const startElement = elementList[range.startIndex]
|
||||
let curIndex = range.startIndex
|
||||
if (cacheStartElement.tdId === startElement.tdId && range.startIndex > cacheRange.endIndex) {
|
||||
curIndex -= (cacheRange.endIndex - cacheRange.startIndex)
|
||||
// 是否是不可拖拽的控件结构元素
|
||||
const dragElementList = cacheElementList.slice(cacheRange.startIndex + 1, cacheRange.endIndex + 1)
|
||||
const isContainControl = dragElementList.find(element =>
|
||||
element.type === ElementType.CONTROL ||
|
||||
element.type === ElementType.DATE
|
||||
)
|
||||
if (isContainControl) {
|
||||
// 仅允许 (最前/后元素不是控件 || 在控件前后 || 文本控件且是值) 拖拽
|
||||
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 = {}
|
||||
if (startElement.tableId) {
|
||||
const { tdId, trId, tableId } = startElement
|
||||
if (anchorElement.tableId) {
|
||||
const { tdId, trId, tableId } = anchorElement
|
||||
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 = {
|
||||
value: el.value,
|
||||
...restArg
|
||||
@@ -42,9 +94,57 @@ export function mouseup(evt: MouseEvent, host: CanvasEvent) {
|
||||
}
|
||||
})
|
||||
return newElement
|
||||
} else {
|
||||
const newElement = deepClone(el)
|
||||
formatElementList([newElement], {
|
||||
isHandleFirstElement: false,
|
||||
editorOptions,
|
||||
})
|
||||
elementList.splice(curIndex + 1, 0, ...replaceElementList)
|
||||
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
|
||||
})
|
||||
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 positionContext = position.getPositionContext()
|
||||
let positionContextIndex = positionContext.index
|
||||
@@ -52,12 +152,12 @@ export function mouseup(evt: MouseEvent, host: CanvasEvent) {
|
||||
if (startElement.tableId && !cacheStartElement.tableId) {
|
||||
// 表格外移动到表格内&&表格之前
|
||||
if (cacheStartPosition.index < positionContextIndex) {
|
||||
positionContextIndex -= deleteElementList.length
|
||||
positionContextIndex -= replaceLength
|
||||
}
|
||||
} else if (!startElement.tableId && cacheStartElement.tableId) {
|
||||
// 表格内移到表格外&&表格之前
|
||||
if (startPosition.index < positionContextIndex) {
|
||||
positionContextIndex += deleteElementList.length
|
||||
positionContextIndex += replaceLength
|
||||
}
|
||||
}
|
||||
position.setPositionContext({
|
||||
@@ -65,25 +165,24 @@ export function mouseup(evt: MouseEvent, host: CanvasEvent) {
|
||||
index: positionContextIndex
|
||||
})
|
||||
}
|
||||
// 设置选区
|
||||
// 重设选区
|
||||
const rangeStartIndex = getElementIndexByDragId(rangeStartId, elementList)
|
||||
const rangeEndIndex = getElementIndexByDragId(rangeEndId, elementList)
|
||||
rangeManager.setRange(
|
||||
curIndex,
|
||||
curIndex + deleteElementList.length,
|
||||
rangeStartIndex,
|
||||
rangeEndIndex,
|
||||
range.tableId,
|
||||
range.startTdIndex,
|
||||
range.endTdIndex,
|
||||
range.startTrIndex,
|
||||
range.endTrIndex
|
||||
)
|
||||
// 重新渲染&重设状态
|
||||
// 重新渲染
|
||||
draw.render({
|
||||
isSetCursor: false
|
||||
})
|
||||
host.isAllowDrag = false
|
||||
host.isAllowDrop = false
|
||||
} else if (host.isAllowDrag) {
|
||||
// 如果是允许拖拽不允许拖放则光标重置
|
||||
host.mousedown(evt)
|
||||
host.isAllowDrag = false
|
||||
}
|
||||
}
|
||||
@@ -103,6 +103,18 @@ export class RangeManager {
|
||||
control.destroyControl()
|
||||
}
|
||||
|
||||
public replaceRange(range: IRange) {
|
||||
this.setRange(
|
||||
range.startIndex,
|
||||
range.endIndex,
|
||||
range.tableId,
|
||||
range.startTdIndex,
|
||||
range.endTdIndex,
|
||||
range.startTrIndex,
|
||||
range.endTrIndex
|
||||
)
|
||||
}
|
||||
|
||||
public setRangeStyle() {
|
||||
if (!this.listener.rangeStyleChange) return
|
||||
let curElementList = this.getSelection()
|
||||
|
||||
Reference in New Issue
Block a user