in src/app/views/canvas/snapping/session.ts [80:224]
public handleDrag(e: HandlesDragEvent) {
const EPSILON = 1e-5;
switch (this.handle.type) {
case "line":
{
let minGuide: SnappableGuide<ElementType> = null;
let minDistance: number = null;
let minXGuide: SnappableGuide<ElementType> = null;
let minXDistance: number = null;
let minYGuide: SnappableGuide<ElementType> = null;
let minYDistance: number = null;
for (const g of this.candidates.sort(this.giveProrityToPoint)) {
const guide = g.guide as Prototypes.SnappingGuides.Axis;
if (this.findClosestSnappingGuide) {
if (guide.type == "y") {
const dY = Math.abs(guide.value - (e.value as number));
if (dY < minYDistance || minYDistance == null) {
minYDistance = dY;
minYGuide = g;
}
} else if (guide.type == "x") {
const dX = Math.abs(guide.value - (e.value as number));
if (dX < minXDistance || minXDistance == null) {
minXDistance = dX;
minXGuide = g;
}
} else {
const guide = g.guide as Prototypes.SnappingGuides.Axis;
const d = Math.abs(guide.value - (e.value as number));
if (
d < this.threshold &&
(minDistance == null || d < minDistance - EPSILON)
) {
minDistance = d;
minGuide = g;
}
}
}
}
if (this.findClosestSnappingGuide) {
if ((this.handle as Handles.Line)?.axis === "y") {
if (minYGuide) {
this.currentCandidates = [minYGuide];
}
}
if ((this.handle as Handles.Line)?.axis === "x") {
if (minXGuide) {
this.currentCandidates = [minXGuide];
}
}
} else {
if (minGuide) {
this.currentCandidates = [minGuide];
} else {
this.currentCandidates = null;
}
}
}
break;
case "point":
{
let minXGuide: SnappableGuide<ElementType> = null;
let minXDistance: number = null;
let minYGuide: SnappableGuide<ElementType> = null;
let minYDistance: number = null;
for (const g of this.candidates.sort(this.giveProrityToPoint)) {
const guide = g.guide as Prototypes.SnappingGuides.Axis;
if (this.findClosestSnappingGuide) {
// Find closest point
if (g.guide.type == "point") {
const polarGuide = g.guide as Prototypes.SnappingGuides.PolarAxis;
const dX = Math.abs(polarGuide.angle - (e.x as number));
const dY = Math.abs(polarGuide.radius - (e.y as number));
if (dX < minXDistance || minXDistance == null) {
minXDistance = dX;
minXGuide = g;
}
if (dY < minYDistance || minYDistance == null) {
minYDistance = dY;
minYGuide = g;
}
} else if (guide.type == "y") {
const dY = Math.abs(guide.value - (e.y as number));
if (dY < minYDistance || minYDistance == null) {
minYDistance = dY;
minYGuide = g;
}
} else if (guide.type == "x") {
const dX = Math.abs(guide.value - (e.x as number));
if (dX < minXDistance || minXDistance == null) {
minXDistance = dX;
minXGuide = g;
}
}
} else {
// Filter guides by threshold
if (g.guide.type == "point") {
const polarGuide = g.guide as Prototypes.SnappingGuides.PolarAxis;
const d = Math.sqrt(
(polarGuide.angle - (e.x as number)) *
(polarGuide.angle - (e.x as number)) +
(polarGuide.radius - (e.y as number)) *
(polarGuide.radius - (e.y as number))
);
if (
d < this.threshold &&
(minYDistance == null || d < minYDistance - EPSILON)
) {
minYDistance = d;
minYGuide = g;
minXDistance = d;
minXGuide = g;
}
} else if (guide.type == "x") {
const d = Math.abs(guide.value - (e.x as number));
if (
d < this.threshold &&
(minXDistance == null || d < minXDistance - EPSILON)
) {
minXDistance = d;
minXGuide = g;
}
} else if (guide.type == "y") {
const d = Math.abs(guide.value - (e.y as number));
if (
d < this.threshold &&
(minYDistance == null || d < minYDistance - EPSILON)
) {
minYDistance = d;
minYGuide = g;
}
}
}
}
this.currentCandidates = [];
if (minXGuide) {
this.currentCandidates.push(minXGuide);
}
if (minYGuide) {
this.currentCandidates.push(minYGuide);
}
}
break;
}
}