Skip to content

Commit

Permalink
feat: add rect property
Browse files Browse the repository at this point in the history
  • Loading branch information
daybrush committed Jun 23, 2020
1 parent 0e04c1d commit 8d5fe6e
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 31 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "selecto",
"version": "1.2.0",
"version": "1.3.0",
"description": "Selecto.js is a component that allows you to select elements in the drag area using the mouse or touch.",
"main": "./dist/selecto.cjs.js",
"module": "./dist/selecto.esm.js",
Expand Down
62 changes: 34 additions & 28 deletions src/Selecto.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { isObject, camelize, IObject, addEvent, removeEvent } from "@daybrush/ut
import ChildrenDiffer, { diff, ChildrenDiffResult } from "@egjs/children-differ";
import DragScroll from "@scena/dragscroll";
import KeyController, { getCombi } from "keycon";
import { createElement, h, getClient, diffValue } from "./utils";
import { createElement, h, getClient, diffValue, getRect } from "./utils";
import { SelectoOptions, Rect, SelectoProperties, OnDragEvent, SelectoEvents } from "./types";
import { PROPERTIES, injector, CLASS_NAME } from "./consts";
/**
Expand Down Expand Up @@ -299,7 +299,8 @@ class Selecto extends Component {

return added.map(index => list[index]).concat(removed.map(index => prevList[index]));
}
private select(selectedTargets: Array<HTMLElement | SVGElement>, inputEvent: any, isStart?: boolean) {
private select(
selectedTargets: Array<HTMLElement | SVGElement>, rect: Rect, inputEvent: any, isStart?: boolean) {
const {
added,
removed,
Expand Down Expand Up @@ -342,6 +343,7 @@ class Selecto extends Component {
selected: selectedTargets,
added: added.map(index => list[index]),
removed: removed.map(index => prevList[index]),
rect,
inputEvent,
});
}
Expand Down Expand Up @@ -373,13 +375,15 @@ class Selecto extends Component {
selected: selectedTargets,
added: added.map(index => list[index]),
removed: removed.map(index => prevList[index]),
rect,
inputEvent,
});
}
}
private selectEnd(
startSelectedTargets: Array<HTMLElement | SVGElement>,
selectedTargets: Array<HTMLElement | SVGElement>,
rect: Rect,
e: OnDragEvent,
) {
const { inputEvent, isDouble } = e;
Expand Down Expand Up @@ -436,6 +440,7 @@ class Selecto extends Component {
afterRemoved: afterRemoved.map(index => afterPrevList[index]),
isDragStart,
isDouble: !!isDouble,
rect,
inputEvent,
});
}
Expand All @@ -452,21 +457,27 @@ class Selecto extends Component {
top,
right: left + width,
bottom: top + height,
width,
height,
};
});
datas.selectableTargets = selectableTargets;
datas.selectableRects = selectableRects;
datas.startSelectedTargets = this.selectedTargets;

const pointTarget = clickedTarget || document.elementFromPoint(clientX, clientY);
let firstPassedTargets = this.hitTest({
const hitRect = {
left: clientX,
top: clientY,
right: clientX,
bottom: clientY,
}, clientX, clientY, selectableTargets, selectableRects).filter(
target => target === pointTarget || target.contains(pointTarget),
);
width: 0,
height: 0,
};
let firstPassedTargets = this.hitTest(
hitRect, clientX, clientY, selectableTargets, selectableRects).filter(
target => target === pointTarget || target.contains(pointTarget),
);

const hasInsideTargets = firstPassedTargets.length > 0;
const isPreventSelect = !selectFromInside && hasInsideTargets;
Expand Down Expand Up @@ -514,11 +525,12 @@ class Selecto extends Component {
if (!result) {
return false;
}
this.select(firstPassedTargets, inputEvent, true);
this.select(firstPassedTargets, hitRect, inputEvent, true);
datas.startX = clientX;
datas.startY = clientY;
datas.selectedTargets = firstPassedTargets;
this.target.style.cssText += `left:${clientX}px;top:${clientY}px`;
this.target.style.cssText
+= `left:0px;top:0px;transform: translate(${clientX}px, ${clientY}px)`;

if (isPreventSelect && selectByClick) {
this.onDragEnd(e);
Expand All @@ -537,34 +549,27 @@ class Selecto extends Component {
}
private check(e: any) {
const {
distX,
distY,
datas,
inputEvent,
} = e;
const { startX, startY } = datas;
const tx = Math.min(0, distX);
const ty = Math.min(0, distY);
const width = Math.abs(distX);
const height = Math.abs(distY);

const rect = getRect(e);
const {
top,
left,
width,
height,
} = rect;
this.target.style.cssText
+= `display: block;`
+ `left:${startX}px;top:${startY}px;`
+ `transform: translate(${tx}px, ${ty}px);`
+ `left:0px;top:0px;`
+ `transform: translate(${left}px, ${top}px);`
+ `width:${width}px;height:${height}px;`;

const left = startX + tx;
const top = startY + ty;
const passedTargets = this.hitTest({
left,
top,
right: left + width,
bottom: top + height,
}, datas.startX, datas.startY, datas.selectableTargets, datas.selectableRects);
const passedTargets = this.hitTest(
rect, datas.startX, datas.startY, datas.selectableTargets, datas.selectableRects);
const selectedTargets = this.getSelectedTargets(passedTargets);

this.select(selectedTargets, inputEvent);
this.select(selectedTargets, rect, inputEvent);
datas.selectedTargets = selectedTargets;
}
private onDrag = (e: OnDrag) => {
Expand All @@ -580,7 +585,8 @@ class Selecto extends Component {
const { datas } = e;
this.dragScroll.dragEnd();
this.target.style.cssText += "display: none;";
this.selectEnd(datas.startSelectedTargets, datas.selectedTargets, e);
this.selectEnd(
datas.startSelectedTargets, datas.selectedTargets, getRect(e), e);
this.selectedTargets = datas.selectedTargets;
}
private sameCombiKey(e: any) {
Expand Down
6 changes: 6 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ export interface Rect {
left: number;
bottom: number;
right: number;
width: number;
height: number;
}

/**
Expand All @@ -58,12 +60,14 @@ export interface Rect {
* @property - Selection Element to apply for framework (private)
* @property - added
* @property - removed
* @property - Rect of Selection Element
* @property - inputEvent
*/
export interface OnSelect {
selected: Array<HTMLElement | SVGElement>;
added: Array<HTMLElement | SVGElement>;
removed: Array<HTMLElement | SVGElement>;
rect: Rect;
inputEvent: any;
}
/**
Expand All @@ -84,6 +88,8 @@ export interface OnDragEvent {
datas: IObject<any>;
clientX: number;
clientY: number;
distX?: number;
distY?: number;
isDouble?: boolean;
inputEvent: any;
}
Expand Down
26 changes: 25 additions & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Hypertext } from "./types";
import { Hypertext, Rect } from "./types";
import { IObject, addClass, hasClass } from "@daybrush/utils";

export function getClient(e: MouseEvent | TouchEvent) {
Expand Down Expand Up @@ -74,3 +74,27 @@ export function diffValue<T>(prev: T, cur: T, func: (prev: T, cur: T) => void) {
func(prev, cur);
}
}

export function getRect(e: any): Rect {
const {
distX = 0,
distY = 0,
datas,
} = e;
const { startX, startY } = datas;
const tx = Math.min(0, distX);
const ty = Math.min(0, distY);
const width = Math.abs(distX);
const height = Math.abs(distY);
const left = startX + tx;
const top = startY + ty;

return {
left,
top,
right: left + width,
bottom: top + height,
width,
height,
};
}

0 comments on commit 8d5fe6e

Please sign in to comment.