aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStanley Yip <stanley_yip@brown.edu>2020-04-20 20:06:53 -0700
committerStanley Yip <stanley_yip@brown.edu>2020-04-20 20:06:53 -0700
commit4bdffbc63bcfac5db15e5bb58fb3a41be617b2a1 (patch)
treefa57eaa4818a72c5e8fd4b71158f6c28d62f1cae /src
parent587a97e9f5fc49952d7520829d719614477e2717 (diff)
better snapping, scaling is off still
Diffstat (limited to 'src')
-rw-r--r--src/client/util/DragManager.ts67
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx55
2 files changed, 96 insertions, 26 deletions
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 21306c339..b0cabfaad 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -74,7 +74,8 @@ export function SetupDrag(
export namespace DragManager {
let dragDiv: HTMLDivElement;
- let snapLines: [PointData, PointData][];
+ let horizSnapLines: number[];
+ let vertSnapLines: number[];
export function Root() {
const root = document.getElementById("root");
@@ -283,8 +284,9 @@ export namespace DragManager {
StartDrag([ele], {}, downX, downY);
}
- export function SetSnapLines() {
- snapLines = [];
+ export function SetSnapLines(horizLines: number[], vertLines: number[]) {
+ horizSnapLines = horizLines;
+ vertSnapLines = vertLines;
}
function StartDrag(eles: HTMLElement[], dragData: { [id: string]: any }, downX: number, downY: number, options?: DragOptions, finishDrag?: (dropData: DragCompleteEvent) => void) {
@@ -302,12 +304,22 @@ export namespace DragManager {
const ys: number[] = [];
const docs = dragData instanceof DocumentDragData ? dragData.draggedDocuments : dragData instanceof PdfAnnoDragData ? [dragData.dragDocument] : [];
+ const elesCont = {
+ left: Number.MAX_SAFE_INTEGER,
+ top: Number.MAX_SAFE_INTEGER,
+ right: Number.MIN_SAFE_INTEGER,
+ bottom: Number.MIN_SAFE_INTEGER
+ };
const dragElements = eles.map(ele => {
if (!ele.parentNode) dragDiv.appendChild(ele);
const dragElement = ele.parentNode === dragDiv ? ele : ele.cloneNode(true) as HTMLElement;
const rect = ele.getBoundingClientRect();
const scaleX = rect.width / ele.offsetWidth,
scaleY = rect.height / ele.offsetHeight;
+ elesCont.left = Math.min(rect.left, elesCont.left);
+ elesCont.top = Math.min(rect.top, elesCont.top);
+ elesCont.right = Math.max(rect.right, elesCont.right);
+ elesCont.bottom = Math.max(rect.bottom, elesCont.bottom);
xs.push(rect.left);
ys.push(rect.top);
scaleXs.push(scaleX);
@@ -357,6 +369,12 @@ export namespace DragManager {
let lastX = downX;
let lastY = downY;
+ const xFromLeft = downX - elesCont.left;
+ const yFromTop = downY - elesCont.top;
+ const xFromRight = elesCont.right - downX;
+ const yFromBottom = elesCont.bottom - downY;
+ console.log(elesCont);
+ console.log(xFromLeft, yFromTop);
const moveHandler = (e: PointerEvent) => {
e.preventDefault(); // required or dragging text menu link item ends up dragging the link button as native drag/drop
if (dragData instanceof DocumentDragData) {
@@ -373,10 +391,45 @@ export namespace DragManager {
}, dragData.droppedDocuments);
}
//TODO: Why can't we use e.movementX and e.movementY?
- const moveX = e.pageX - lastX;
- const moveY = e.pageY - lastY;
- lastX = e.pageX;
- lastY = e.pageY;
+ 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 closestHoriz = horizSnapLines.reduce((prev, curr) => Math.abs(prev - thisY) > Math.abs(curr - thisY) ? curr : prev);
+ // const closestVert = vertSnapLines.reduce((prev, curr) => Math.abs(prev - thisX) > Math.abs(curr - thisX) ? curr : prev);
+ // if (Math.abs(thisY - closestHoriz) < 10) {
+ // thisY = closestHoriz;
+ // }
+ // if (Math.abs(thisX - closestVert) < 10) {
+ // thisX = closestVert;
+ // }
+ const moveX = thisX - lastX;
+ const moveY = thisY - lastY;
+ lastX = thisX;
+ lastY = thisY;
dragElements.map((dragElement, i) => (dragElement.style.transform =
`translate(${(xs[i] += moveX) + (options?.offsetX || 0)}px, ${(ys[i] += moveY) + (options?.offsetY || 0)}px) scale(${scaleXs[i]}, ${scaleYs[i]})`)
);
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 36ec4c72e..c4c37141b 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1094,6 +1094,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument, u
return !(r2.left > r1.left + r1.width || r2.left + r2.width < r1.left || r2.top > r1.top + r1.height || r2.top + r2.height < r1.top);
}
+ @action
onPointerOver = (e: React.PointerEvent) => {
if (SelectionManager.GetIsDragging()) {
const size = this.props.ScreenToLocalTransform().transformDirection(this.props.PanelWidth(), this.props.PanelHeight());
@@ -1123,11 +1124,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument, u
});
}
if (!selection.length) {
- const left = this._downX < this._lastX ? this._downX : this._lastX;
- const top = this._downY < this._lastY ? this._downY : this._lastY;
- const topLeft = this.getContainerTransform().transformPoint(left, top);
- const size = this.getContainerTransform().transformDirection(this._lastX - this._downX, this._lastY - this._downY);
- const otherBounds = { left: topLeft[0], top: topLeft[1], width: Math.abs(size[0]), height: Math.abs(size[1]) };
+ 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);
@@ -1139,23 +1136,38 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument, u
}
});
}
- const lines: [PointData, PointData][] = [];
+ const horizLines: number[] = [];
+ const vertLines: number[] = [];
selection.forEach(doc => {
- const x = NumCast(doc.x);
- const y = NumCast(doc.y);
- const w = doc[WidthSym]();
- const h = doc[HeightSym]();
- lines.push([{ X: x, Y: y }, { X: x + w, Y: y }]); // top line
- lines.push([{ X: x, Y: y }, { X: x, Y: y + h }]); // left line
- lines.push([{ X: x + w, Y: y }, { X: x + w, Y: y + h }]); // right line
- lines.push([{ X: x, Y: y + h }, { X: x + w, Y: y + h }]); // bottom line
- lines.push([{ X: x + w / 2, Y: y }, { X: x + w / 2, Y: y + h }]); // horizontal center line
- lines.push([{ X: x, Y: y + h / 2 }, { X: x + w, Y: y + h / 2 }]); // vertical center line
- })
- DragManager.SetSnapLines(lines);
+ const layoutDoc = Doc.Layout(doc);
+ const x = NumCast(doc.x) - selRect.left;
+ const y = NumCast(doc.y) - selRect.top;
+ const w = NumCast(layoutDoc._width);
+ const h = NumCast(layoutDoc._height);
+ // const s = this._mainCont!.getBoundingClientRect().width / selRect.width;
+ // const tLFromCorner = [s * x, s * y];
+ const topLeft = this.getLocalTransform().inverse().transformDirection(x, y);
+ console.log(topLeft);
+ const topLeftInScreen = [this._mainCont!.getBoundingClientRect().left + topLeft[0], this._mainCont!.getBoundingClientRect().top + topLeft[1]];
+ const docSize = this.getLocalTransform().inverse().transformDirection(w, h);
+ console.log(topLeftInScreen);
+ horizLines.push(topLeftInScreen[1]); // top line
+ horizLines.push(topLeftInScreen[1] + docSize[1]); // bottom line
+ horizLines.push(topLeftInScreen[1] + docSize[1] / 2); // horiz center line
+ vertLines.push(topLeftInScreen[0]);//left line
+ vertLines.push(topLeftInScreen[0] + docSize[0]);// right line
+ vertLines.push(topLeftInScreen[0] + docSize[0] / 2);// vert center line
+ });
+ // console.log(horizLines, vertLines);
+ // this._hLines = horizLines;
+ // this._vLines = vertLines;
+ DragManager.SetSnapLines(horizLines, vertLines);
}
}
+ @observable private _hLines: number[] | undefined;
+ @observable private _vLines: number[] | undefined;
+
private childViews = () => {
const children = typeof this.props.children === "function" ? (this.props.children as any)() as JSX.Element[] : [];
return [
@@ -1242,7 +1254,12 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument, u
}}>
</div>
-
+ <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 >;
}
}