aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBob Zeleznik <zzzman@gmail.com>2020-04-29 22:27:59 -0400
committerBob Zeleznik <zzzman@gmail.com>2020-04-29 22:27:59 -0400
commit37b5878ac3a8f0bd5168431b71e58eee27a3ec99 (patch)
tree65b920cd12b387aebb8af56571c4b703ffffde4d /src
parent0cff51fbe53deea53ffa4d1f1cbb80a3c74a918f (diff)
fixed problems with snapping so that it snaps on finishDrag. cleaned up code a bit.
Diffstat (limited to 'src')
-rw-r--r--src/client/util/DragManager.ts81
-rw-r--r--src/client/views/MainView.tsx14
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx60
3 files changed, 68 insertions, 87 deletions
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index a905dff0a..36c26fe2c 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -75,8 +75,8 @@ export function SetupDrag(
export namespace DragManager {
let dragDiv: HTMLDivElement;
- export let horizSnapLines: number[];
- export let vertSnapLines: number[];
+ export let horizSnapLines: number[] = [];
+ export let vertSnapLines: number[] = [];
export function Root() {
const root = document.getElementById("root");
@@ -296,7 +296,6 @@ export namespace DragManager {
StartDrag([ele], {}, downX, downY);
}
- @action
export function SetSnapLines(horizLines: number[], vertLines: number[]) {
horizSnapLines = horizLines;
vertSnapLines = vertLines;
@@ -304,6 +303,36 @@ export namespace DragManager {
MainView.Instance._vLines = vertLines;
}
+ function snapDrag(e: PointerEvent, xFromLeft: number, yFromTop: number, xFromRight: number, yFromBottom: number) {
+ let thisX = e.pageX;
+ let thisY = e.pageY;
+ const currLeft = e.pageX - xFromLeft;
+ const currTop = e.pageY - yFromTop;
+ const currRight = e.pageX + xFromRight;
+ const currBottom = e.pageY + yFromBottom;
+ const closestLeft = vertSnapLines.reduce((prev, curr) => Math.abs(prev - currLeft) > Math.abs(curr - currLeft) ? curr : prev);
+ const closestTop = horizSnapLines.reduce((prev, curr) => Math.abs(prev - currTop) > Math.abs(curr - currTop) ? curr : prev);
+ const closestRight = vertSnapLines.reduce((prev, curr) => Math.abs(prev - currRight) > Math.abs(curr - currRight) ? curr : prev);
+ const closestBottom = horizSnapLines.reduce((prev, curr) => Math.abs(prev - currBottom) > Math.abs(curr - currBottom) ? curr : prev);
+ const distFromClosestLeft = Math.abs(e.pageX - xFromLeft - closestLeft);
+ const distFromClosestTop = Math.abs(e.pageY - yFromTop - closestTop);
+ const distFromClosestRight = Math.abs(e.pageX + xFromRight - closestRight);
+ const distFromClosestBottom = Math.abs(e.pageY + yFromBottom - closestBottom);
+ if (distFromClosestLeft < 10 && distFromClosestLeft < distFromClosestRight) {
+ thisX = closestLeft + xFromLeft;
+ }
+ else if (distFromClosestRight < 10) {
+ thisX = closestRight - xFromRight;
+ }
+ if (distFromClosestTop < 10 && distFromClosestTop < distFromClosestRight) {
+ thisY = closestTop + yFromTop;
+ }
+ else if (distFromClosestBottom < 10) {
+ thisY = closestBottom - yFromBottom;
+ }
+ return { thisX, thisY };
+ }
+ export let docsBeingDragged: Doc[] = [];
function StartDrag(eles: HTMLElement[], dragData: { [id: string]: any }, downX: number, downY: number, options?: DragOptions, finishDrag?: (dropData: DragCompleteEvent) => void) {
eles = eles.filter(e => e);
if (!dragDiv) {
@@ -318,7 +347,7 @@ export namespace DragManager {
const xs: number[] = [];
const ys: number[] = [];
- const docs = dragData instanceof DocumentDragData ? dragData.draggedDocuments : dragData instanceof PdfAnnoDragData ? [dragData.dragDocument] : [];
+ docsBeingDragged = dragData instanceof DocumentDragData ? dragData.draggedDocuments : dragData instanceof PdfAnnoDragData ? [dragData.dragDocument] : [];
const elesCont = {
left: Number.MAX_SAFE_INTEGER,
top: Number.MAX_SAFE_INTEGER,
@@ -354,7 +383,7 @@ export namespace DragManager {
dragElement.style.width = `${rect.width / scaleX}px`;
dragElement.style.height = `${rect.height / scaleY}px`;
- if (docs.length) {
+ if (docsBeingDragged.length) {
const pdfBox = dragElement.getElementsByTagName("canvas");
const pdfBoxSrc = ele.getElementsByTagName("canvas");
Array.from(pdfBox).map((pb, i) => pb.getContext('2d')!.drawImage(pdfBoxSrc[i], 0, 0));
@@ -408,32 +437,8 @@ export namespace DragManager {
button: 0
}, dragData.droppedDocuments);
}
- let thisX = e.pageX;
- let thisY = e.pageY;
- const currLeft = e.pageX - xFromLeft;
- const currTop = e.pageY - yFromTop;
- const currRight = e.pageX + xFromRight;
- const currBottom = e.pageY + yFromBottom;
- const closestLeft = vertSnapLines.reduce((prev, curr) => Math.abs(prev - currLeft) > Math.abs(curr - currLeft) ? curr : prev);
- const closestTop = horizSnapLines.reduce((prev, curr) => Math.abs(prev - currTop) > Math.abs(curr - currTop) ? curr : prev);
- const closestRight = vertSnapLines.reduce((prev, curr) => Math.abs(prev - currRight) > Math.abs(curr - currRight) ? curr : prev);
- const closestBottom = horizSnapLines.reduce((prev, curr) => Math.abs(prev - currBottom) > Math.abs(curr - currBottom) ? curr : prev);
- const distFromClosestLeft = Math.abs(e.pageX - xFromLeft - closestLeft);
- const distFromClosestTop = Math.abs(e.pageY - yFromTop - closestTop);
- const distFromClosestRight = Math.abs(e.pageX + xFromRight - closestRight);
- const distFromClosestBottom = Math.abs(e.pageY + yFromBottom - closestBottom);
- if (distFromClosestLeft < 10 && distFromClosestLeft < distFromClosestRight) {
- thisX = closestLeft + xFromLeft;
- }
- else if (distFromClosestRight < 10) {
- thisX = closestRight - xFromRight;
- }
- if (distFromClosestTop < 10 && distFromClosestTop < distFromClosestRight) {
- thisY = closestTop + yFromTop;
- }
- else if (distFromClosestBottom < 10) {
- thisY = closestBottom - yFromBottom;
- }
+
+ const { thisX, thisY } = snapDrag(e, xFromLeft, yFromTop, xFromRight, yFromBottom);
alias = "move";
const moveX = thisX - lastX;
@@ -462,7 +467,7 @@ export namespace DragManager {
};
const upHandler = (e: PointerEvent) => {
hideDragShowOriginalElements();
- dispatchDrag(eles, e, dragData, options, finishDrag);
+ dispatchDrag(eles, e, dragData, xFromLeft, yFromTop, xFromRight, yFromBottom, options, finishDrag);
SelectionManager.SetIsDragging(false);
endDrag();
options?.dragComplete?.(new DragCompleteEvent(false, dragData));
@@ -471,7 +476,8 @@ export namespace DragManager {
document.addEventListener("pointerup", upHandler);
}
- function dispatchDrag(dragEles: HTMLElement[], e: PointerEvent, dragData: { [index: string]: any }, options?: DragOptions, finishDrag?: (e: DragCompleteEvent) => void) {
+ function dispatchDrag(dragEles: HTMLElement[], e: PointerEvent, dragData: { [index: string]: any },
+ xFromLeft: number, yFromTop: number, xFromRight: number, yFromBottom: number, options?: DragOptions, finishDrag?: (e: DragCompleteEvent) => void) {
const removed = dragData.dontHideOnDrop ? [] : dragEles.map(dragEle => {
const ret = { ele: dragEle, w: dragEle.style.width, h: dragEle.style.height, o: dragEle.style.overflow };
dragEle.style.width = "0";
@@ -485,14 +491,15 @@ export namespace DragManager {
r.ele.style.height = r.h;
r.ele.style.overflow = r.o;
});
+ const { thisX, thisY } = snapDrag(e, xFromLeft, yFromTop, xFromRight, yFromBottom);
if (target) {
const complete = new DragCompleteEvent(false, dragData);
target.dispatchEvent(
new CustomEvent<DropEvent>("dashPreDrop", {
bubbles: true,
detail: {
- x: e.x,
- y: e.y,
+ x: thisX,
+ y: thisY,
complete: complete,
shiftKey: e.shiftKey,
altKey: e.altKey,
@@ -506,8 +513,8 @@ export namespace DragManager {
new CustomEvent<DropEvent>("dashOnDrop", {
bubbles: true,
detail: {
- x: e.x,
- y: e.y,
+ x: thisX,
+ y: thisY,
complete: complete,
shiftKey: e.shiftKey,
altKey: e.altKey,
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 0102d1327..62b2d1d18 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -588,13 +588,13 @@ export class MainView extends React.Component {
<MarqueeOptionsMenu />
<RichTextMenu />
<OverlayView />
- {/* TO VIEW SNAP LINES
- <div className="snapLines" style={{ position: "absolute", top: 0, left: 0, width: "100%", height: "100%", pointerEvents: "none" }}>
- <svg style={{ width: "100%", height: "100%" }}>
- {this._hLines?.map(l => <line x1="0" y1={l} x2="2000" y2={l} stroke="black" />)}
- {this._vLines?.map(l => <line y1="0" x1={l} y2="2000" x2={l} stroke="black" />)}
- </svg>
- </div> */}
+ {// TO VIEW SNAP LINES
+ /* <div className="snapLines" style={{ position: "absolute", top: 0, left: 0, width: "100%", height: "100%", pointerEvents: "none" }}>
+ <svg style={{ width: "100%", height: "100%" }}>
+ {this._hLines?.map(l => <line x1="0" y1={l} x2="2000" y2={l} stroke="black" />)}
+ {this._vLines?.map(l => <line y1="0" x1={l} y2="2000" x2={l} stroke="black" />)}
+ </svg>
+ </div>*/}
<TimelineMenu />
</div >);
}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index d291cad21..0c9403429 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1129,7 +1129,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
input.click();
}
});
- ContextMenu.Instance.addItem({ description: "Options ...", subitems: optionItems, icon: "eye" });
+ ContextMenu.Instance.addItem({ description: "Options...", subitems: optionItems, icon: "eye" });
this._timelineRef.current!.timelineContextMenu(e);
}
@@ -1144,51 +1144,24 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
const size = this.props.ScreenToLocalTransform().transformDirection(this.props.PanelWidth(), this.props.PanelHeight());
const selRect = { left: this.panX() - size[0] / 2, top: this.panY() - size[1] / 2, width: size[0], height: size[1] };
const selection: Doc[] = [];
- this.getActiveDocuments().filter(doc => !doc.isBackground && doc.z === undefined).map(doc => {
- const layoutDoc = Doc.Layout(doc);
- const x = NumCast(doc.x);
- const y = NumCast(doc.y);
- const w = NumCast(layoutDoc._width);
- const h = NumCast(layoutDoc._height);
- if (this.intersectRect({ left: x, top: y, width: w, height: h }, selRect)) {
+ const docDims = (doc: Doc, layoutDoc: Doc) => ({ left: NumCast(doc.x), top: NumCast(doc.y), width: NumCast(layoutDoc._width), height: NumCast(layoutDoc._height) });
+ const compareDoc = (doc: Doc, rect: { left: number, top: number, width: number, height: number }) => {
+ if (this.intersectRect(docDims(doc, Doc.Layout(doc)), rect)) {
selection.push(doc);
}
- });
- if (!selection.length) {
- this.getActiveDocuments().filter(doc => doc.z === undefined).map(doc => {
- const layoutDoc = Doc.Layout(doc);
- const x = NumCast(doc.x);
- const y = NumCast(doc.y);
- const w = NumCast(layoutDoc._width);
- const h = NumCast(layoutDoc._height);
- if (this.intersectRect({ left: x, top: y, width: w, height: h }, selRect)) {
- selection.push(doc);
- }
- });
- }
- if (!selection.length) {
- const otherBounds = { left: this.panX(), top: this.panY(), width: Math.abs(size[0]), height: Math.abs(size[1]) };
- this.getActiveDocuments().filter(doc => doc.z !== undefined).map(doc => {
- const layoutDoc = Doc.Layout(doc);
- const x = NumCast(doc.x);
- const y = NumCast(doc.y);
- const w = NumCast(layoutDoc._width);
- const h = NumCast(layoutDoc._height);
- if (this.intersectRect({ left: x, top: y, width: w, height: h }, otherBounds)) {
- selection.push(doc);
- }
- });
}
+ const otherBounds = { left: this.panX(), top: this.panY(), width: Math.abs(size[0]), height: Math.abs(size[1]) };
+ this.getActiveDocuments().filter(doc => !doc.isBackground && doc.z === undefined).map(doc => compareDoc(doc, selRect)); // first try foreground docs
+ !selection.length && this.getActiveDocuments().filter(doc => doc.z === undefined).map(doc => compareDoc(doc, selRect)); // then background docs
+ !selection.length && this.getActiveDocuments().filter(doc => doc.z !== undefined).map(doc => compareDoc(doc, otherBounds)); // then floating docs
+
const horizLines: number[] = [];
const vertLines: number[] = [];
- selection.forEach(doc => {
- const layoutDoc = Doc.Layout(doc);
- const x = NumCast(doc.x);
- const y = NumCast(doc.y);
- const w = NumCast(layoutDoc._width);
- const h = NumCast(layoutDoc._height);
- const topLeftInScreen = this.getTransform().inverse().transformPoint(x, y);
- const docSize = this.getTransform().inverse().transformDirection(w, h);
+ selection.filter(doc => !DragManager.docsBeingDragged.includes(doc)).forEach(doc => {
+ const { left, top, width, height } = docDims(doc, Doc.Layout(doc));
+ const topLeftInScreen = this.getTransform().inverse().transformPoint(left, top);
+ const docSize = this.getTransform().inverse().transformDirection(width, height);
+
horizLines.push(topLeftInScreen[1]); // top line
horizLines.push(topLeftInScreen[1] + docSize[1]); // bottom line
horizLines.push(topLeftInScreen[1] + docSize[1] / 2); // horiz center line
@@ -1292,12 +1265,13 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
}}>
</div>
- {/* <div className="snapLines" style={{ position: "absolute", top: 0, left: 0, width: "100%", height: "100%", pointerEvents: "none" }}>
+ {// uncomment to show snap lines
+ /*<div className="snapLines" style={{ position: "absolute", top: 0, left: 0, width: "100%", height: "100%", pointerEvents: "none" }}>
<svg style={{ width: "100%", height: "100%" }}>
{this._hLines?.map(l => <line x1="0" y1={l} x2="1000" y2={l} stroke="black" />)}
{this._vLines?.map(l => <line y1="0" x1={l} y2="1000" x2={l} stroke="black" />)}
</svg>
- </div> */}
+ </div>*/}
</div >;
}
}