| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- import type { PPTElement } from '@/lib/types/slides';
- export function useOrderElement() {
- /**
- * Get the z-order range of grouped elements
- * @param elementList All elements on the page
- * @param combineElementList Grouped elements list
- */
- 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,
- ),
- };
- };
- /**
- * Move up one layer
- * @param elementList All elements on the page
- * @param element The element being operated on
- */
- const moveUpElement = (elementList: PPTElement[], element: PPTElement) => {
- const copyOfElementList: PPTElement[] = JSON.parse(JSON.stringify(elementList));
- // If the element is a group member, all group members must be moved together
- if (element.groupId) {
- // Get all group members and their z-order range
- const combineElementList = copyOfElementList.filter(
- (_element) => _element.groupId === element.groupId,
- );
- const { minLevel, maxLevel } = getCombineElementLevelRange(elementList, combineElementList);
- // Already at the top level, cannot move further
- 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);
- }
- // If the element is not a group member
- else {
- // Get the element's z-level in the list
- const level = elementList.findIndex((item) => item.id === element.id);
- // Already at the top level, cannot move further
- if (level === elementList.length - 1) return;
- // Get the element above, remove this element from the list (cache removed element).
- // If the above element is in a group, insert above that group.
- // If the above element is not in any group, insert above that element.
- const nextElement = copyOfElementList[level + 1];
- const [movedElement] = copyOfElementList.splice(level, 1);
- 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;
- };
- /**
- * Move down one layer, same approach as move up
- * @param elementList All elements on the page
- * @param element The element being operated on
- */
- 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;
- };
- /**
- * Bring to front
- * @param elementList All elements on the page
- * @param element The element being operated on
- */
- const moveTopElement = (elementList: PPTElement[], element: PPTElement) => {
- const copyOfElementList: PPTElement[] = JSON.parse(JSON.stringify(elementList));
- // If the element is a group member, all group members must be moved together
- if (element.groupId) {
- // Get all group members and their z-order range
- const combineElementList = copyOfElementList.filter(
- (_element) => _element.groupId === element.groupId,
- );
- const { minLevel, maxLevel } = getCombineElementLevelRange(elementList, combineElementList);
- // Already at the top level, cannot move further
- if (maxLevel === elementList.length - 1) return null;
- // Remove the group from the list, then append removed elements to the top
- const movedElementList = copyOfElementList.splice(minLevel, combineElementList.length);
- copyOfElementList.push(...movedElementList);
- }
- // If the element is not a group member
- else {
- // Get the element's z-level in the list
- const level = elementList.findIndex((item) => item.id === element.id);
- // Already at the top level, cannot move further
- if (level === elementList.length - 1) return null;
- // Remove the element from the list, then append it to the top
- copyOfElementList.splice(level, 1);
- copyOfElementList.push(element);
- }
- return copyOfElementList;
- };
- /**
- * Send to back, same approach as bring to front
- * @param elementList All elements on the page
- * @param element The element being operated on
- */
- 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;
- };
- return {
- moveUpElement,
- moveDownElement,
- moveTopElement,
- moveBottomElement,
- };
- }
|