From 6a27e18c0b8021bd6982486198063a1667d1307f Mon Sep 17 00:00:00 2001 From: Eugen Ciur <eugen@papermerge.com> Date: Sat, 12 Mar 2022 07:34:29 +0100 Subject: [PATCH] add dom utils to comput element position while dragging pages --- app/components/viewer/thumbnail/index.js | 11 +++- app/components/viewer/thumbnails/index.js | 13 +++- app/utils/dom.js | 76 +++++++++++++++++++++++ 3 files changed, 96 insertions(+), 4 deletions(-) create mode 100644 app/utils/dom.js diff --git a/app/components/viewer/thumbnail/index.js b/app/components/viewer/thumbnail/index.js index 6bea713..ea8cb89 100644 --- a/app/components/viewer/thumbnail/index.js +++ b/app/components/viewer/thumbnail/index.js @@ -1,6 +1,8 @@ import Component from '@glimmer/component'; import { action } from '@ember/object'; +import { get_pos_within_siblings } from 'papermerge/utils/dom'; + export default class ViewerThumbnailComponent extends Component { @@ -21,11 +23,15 @@ export default class ViewerThumbnailComponent extends Component { @action onDragStart({event, model, items, canvas, element}) { - let data; + let data, original_pos; + + original_pos = get_pos_within_siblings(element); + console.log(`OnDragStart: original_pos = ${original_pos}`); data = { pages: items, - page: model + page: model, + original_pos: original_pos }; event.dataTransfer.setData( @@ -34,7 +40,6 @@ export default class ViewerThumbnailComponent extends Component { ); event.dataTransfer.setDragImage(canvas, 0, -15); - console.log(`Thumbnails onDragStart elment=${element}`); } get is_selected() { diff --git a/app/components/viewer/thumbnails/index.js b/app/components/viewer/thumbnails/index.js index 3268148..c936928 100644 --- a/app/components/viewer/thumbnails/index.js +++ b/app/components/viewer/thumbnails/index.js @@ -1,5 +1,7 @@ import Component from '@glimmer/component'; import { action } from '@ember/object'; +import Point from 'papermerge/utils/point'; +import { get_cursor_pos_within_element } from 'papermerge/utils/dom'; export default class ViewerThumbnailsComponent extends Component { @@ -13,13 +15,22 @@ export default class ViewerThumbnailsComponent extends Component { @action onDrop({event, element}) { - let data, json_data, page_ids; + let data, json_data, page_ids, original_pos, drop_pos; + console.log(`posX=${event.clientX} posY=${event.clientY}`); event.preventDefault(); data = event.dataTransfer.getData('application/x.page'); json_data = JSON.parse(data); + original_pos = json_data['original_pos'] page_ids = json_data['pages'].map(page => page.id); + + drop_pos = get_cursor_pos_within_element( + element, + new Point(event.clientX, event.clientY) + ) console.log(`Thumbnails received: dropped page_ids=${page_ids}`); + console.log(`original position=${original_pos}`); + console.log(`drop position=${drop_pos}`); } @action diff --git a/app/utils/dom.js b/app/utils/dom.js new file mode 100644 index 0000000..ebf87ac --- /dev/null +++ b/app/utils/dom.js @@ -0,0 +1,76 @@ + +function get_pos_within_siblings(element) { + /* + Input element is an HTMLElement instance. + Returns position order (0, 1, 2, ...) of the ``element`` + within his siblings. Position order starts with zero. + + Example: + <div> + <div class='sib'></div> <- pos 0 + <div class='sib'></div> <- pos 1 + <div id="x" class='sib'></div> <-- element + <div class='sib'></div> + </div> + + For element with ID='x' as input, will return position 2. + + On error returns -1. + */ + let el, pos = 0; + + if (!element) { + return -1; + } + + if (element.previousElementSibling) { + el = element.previousElementSibling; + pos += 1; + } else { + // element has no previous siblings i.e. it is + // very first one. + return 0; + } + + do { + el = el.previousElementSibling; + if (el) { + pos += 1; + } + } while( el ); + + return pos; +} + + +function get_cursor_pos_within_element(element, cursor_coord) { + /** + */ + let rect, + pos, + children, + cursor_before_child = 0; + + if (!element) { + return; + } + + children = Array.from(element.children); + + children.forEach(child => { + rect = child.getBoundingClientRect(); + + if (cursor_coord.y <= rect.y) { + cursor_before_child += 1; + } + }); + + pos = children.length - cursor_before_child + + return pos; +} + +export { + get_pos_within_siblings, + get_cursor_pos_within_element +} \ No newline at end of file -- GitLab