File size: 8,997 Bytes
89ce340 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
import { storeToRefs } from 'pinia'
import { useSlidesStore } from '@/store'
import type { PPTElement } from '@/types/slides'
import { ElementOrderCommands } from '@/types/edit'
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
export default () => {
const slidesStore = useSlidesStore()
const { currentSlide } = storeToRefs(slidesStore)
const { addHistorySnapshot } = useHistorySnapshot()
/**
* 获取组合元素层级范围
* @param elementList 本页所有元素列表
* @param combineElementList 组合元素列表
*/
const getCombineElementLevelRange = (elementList: PPTElement[], combineElementList: PPTElement[]) => {
return {
minLevel: elementList.findIndex(_element => _element.id === combineElementList[0].id),
maxLevel: elementList.findIndex(_element => _element.id === combineElementList[combineElementList.length - 1].id),
}
}
/**
* 上移一层
* @param elementList 本页所有元素列表
* @param element 当前操作的元素
*/
const moveUpElement = (elementList: PPTElement[], element: PPTElement) => {
const copyOfElementList: PPTElement[] = JSON.parse(JSON.stringify(elementList))
// 如果被操作的元素是组合元素成员,需要将该组合全部成员一起进行移动
if (element.groupId) {
// 获取到该组合全部成员,以及所有成员的层级范围
const combineElementList = copyOfElementList.filter(_element => _element.groupId === element.groupId)
const { minLevel, maxLevel } = getCombineElementLevelRange(elementList, combineElementList)
// 已经处在顶层,无法继续移动
if (maxLevel === elementList.length - 1) return
// 通过组合成员范围的最大值,获取到该组合上一层的元素,然后将该组合元素从元素列表中移除(并缓存被移除的元素列表)
// 若上层元素处在另一个组合中,则将上述被移除的组合元素插入到该上层组合上方
// 若上层元素不处于任何分组中,则将上述被移除的组合元素插入到该上层元素上方
const nextElement = copyOfElementList[maxLevel + 1]
const movedElementList = copyOfElementList.splice(minLevel, combineElementList.length)
if (nextElement.groupId) {
const nextCombineElementList = copyOfElementList.filter(_element => _element.groupId === nextElement.groupId)
copyOfElementList.splice(minLevel + nextCombineElementList.length, 0, ...movedElementList)
}
else copyOfElementList.splice(minLevel + 1, 0, ...movedElementList)
}
// 如果被操作的元素不是组合元素成员
else {
// 获取该元素在列表中的层级
const level = elementList.findIndex(item => item.id === element.id)
// 已经处在顶层,无法继续移动
if (level === elementList.length - 1) return
// 获取到该组合上一层的元素,然后将该组合元素从元素列表中移除(并缓存被移除的元素列表)
const nextElement = copyOfElementList[level + 1]
const movedElement = copyOfElementList.splice(level, 1)[0]
// 通过组合成员范围的最大值,获取到该组合上一层的元素,然后将该组合元素从元素列表中移除(并缓存被移除的元素列表)
// 若上层元素处在另一个组合中,则将上述被移除的组合元素插入到该上层组合上方
// 若上层元素不处于任何分组中,则将上述被移除的组合元素插入到该上层元素上方
if (nextElement.groupId) {
const combineElementList = copyOfElementList.filter(_element => _element.groupId === nextElement.groupId)
copyOfElementList.splice(level + combineElementList.length, 0, movedElement)
}
else copyOfElementList.splice(level + 1, 0, movedElement)
}
return copyOfElementList
}
/**
* 下移一层,操作方式同上移
* @param elementList 本页所有元素列表
* @param element 当前操作的元素
*/
const moveDownElement = (elementList: PPTElement[], element: PPTElement) => {
const copyOfElementList: PPTElement[] = JSON.parse(JSON.stringify(elementList))
if (element.groupId) {
const combineElementList = copyOfElementList.filter(_element => _element.groupId === element.groupId)
const { minLevel } = getCombineElementLevelRange(elementList, combineElementList)
if (minLevel === 0) return
const prevElement = copyOfElementList[minLevel - 1]
const movedElementList = copyOfElementList.splice(minLevel, combineElementList.length)
if (prevElement.groupId) {
const prevCombineElementList = copyOfElementList.filter(_element => _element.groupId === prevElement.groupId)
copyOfElementList.splice(minLevel - prevCombineElementList.length, 0, ...movedElementList)
}
else copyOfElementList.splice(minLevel - 1, 0, ...movedElementList)
}
else {
const level = elementList.findIndex(item => item.id === element.id)
if (level === 0) return
const prevElement = copyOfElementList[level - 1]
const movedElement = copyOfElementList.splice(level, 1)[0]
if (prevElement.groupId) {
const combineElementList = copyOfElementList.filter(_element => _element.groupId === prevElement.groupId)
copyOfElementList.splice(level - combineElementList.length, 0, movedElement)
}
else copyOfElementList.splice(level - 1, 0, movedElement)
}
return copyOfElementList
}
/**
* 置顶层
* @param elementList 本页所有元素列表
* @param element 当前操作的元素
*/
const moveTopElement = (elementList: PPTElement[], element: PPTElement) => {
const copyOfElementList: PPTElement[] = JSON.parse(JSON.stringify(elementList))
// 如果被操作的元素是组合元素成员,需要将该组合全部成员一起进行移动
if (element.groupId) {
// 获取到该组合全部成员,以及所有成员的层级范围
const combineElementList = copyOfElementList.filter(_element => _element.groupId === element.groupId)
const { minLevel, maxLevel } = getCombineElementLevelRange(elementList, combineElementList)
// 已经处在顶层,无法继续移动
if (maxLevel === elementList.length - 1) return null
// 将该组合元素从元素列表中移除,然后将被移除的元素添加到元素列表顶部
const movedElementList = copyOfElementList.splice(minLevel, combineElementList.length)
copyOfElementList.push(...movedElementList)
}
// 如果被操作的元素不是组合元素成员
else {
// 获取该元素在列表中的层级
const level = elementList.findIndex(item => item.id === element.id)
// 已经处在顶层,无法继续移动
if (level === elementList.length - 1) return null
// 将该组合元素从元素列表中移除,然后将被移除的元素添加到元素列表底部
copyOfElementList.splice(level, 1)
copyOfElementList.push(element)
}
return copyOfElementList
}
/**
* 置底层,操作方式同置顶
* @param elementList 本页所有元素列表
* @param element 当前操作的元素
*/
const moveBottomElement = (elementList: PPTElement[], element: PPTElement) => {
const copyOfElementList: PPTElement[] = JSON.parse(JSON.stringify(elementList))
if (element.groupId) {
const combineElementList = copyOfElementList.filter(_element => _element.groupId === element.groupId)
const { minLevel } = getCombineElementLevelRange(elementList, combineElementList)
if (minLevel === 0) return
const movedElementList = copyOfElementList.splice(minLevel, combineElementList.length)
copyOfElementList.unshift(...movedElementList)
}
else {
const level = elementList.findIndex(item => item.id === element.id)
if (level === 0) return
copyOfElementList.splice(level, 1)
copyOfElementList.unshift(element)
}
return copyOfElementList
}
/**
* 调整元素层级
* @param element 需要调整层级的元素
* @param command 调整命令:上移、下移、置顶、置底
*/
const orderElement = (element: PPTElement, command: ElementOrderCommands) => {
let newElementList
if (command === ElementOrderCommands.UP) newElementList = moveUpElement(currentSlide.value.elements, element)
else if (command === ElementOrderCommands.DOWN) newElementList = moveDownElement(currentSlide.value.elements, element)
else if (command === ElementOrderCommands.TOP) newElementList = moveTopElement(currentSlide.value.elements, element)
else if (command === ElementOrderCommands.BOTTOM) newElementList = moveBottomElement(currentSlide.value.elements, element)
if (!newElementList) return
slidesStore.updateSlide({ elements: newElementList })
addHistorySnapshot()
}
return {
orderElement,
}
} |