class StartConnection { constructor(state, start) { this.state = state; this.deltaX = 0; this.deltaY = 0; this.text = ''; if(start) { this.setAnchorPoint(start.x, start.y); } } setAnchorPoint(x, y) { this.deltaX = x - this.state.x; this.deltaY = y - this.state.y; if(Math.abs(this.deltaX) < settings.snapToPadding) { this.deltaX = 0; } if(Math.abs(this.deltaY) < settings.snapToPadding) { this.deltaY = 0; } } getEndPoints() { const startX = this.state.x + this.deltaX; const startY = this.state.y + this.deltaY; const end = this.state.closestPointOnCircle(startX, startY); return { start: {x: startX, y: startY}, end, }; } draw() { const points = this.getEndPoints(); ctx.strokeStyle = ctx.fillStyle = settings.colors.getColor(this); ctx.beginPath(); ctx.moveTo(points.start.x, points.start.y); ctx.lineTo(points.end.x, points.end.y); ctx.stroke(); ctx.closePath(); const textAngle = Math.atan2(points.start.y - points.end.y, points.start.x - points.end.x); ctx.drawText(this.text, points.start.x, points.start.y, textAngle, selectedObject === this); ctx.drawArrow(points.end.x, points.end.y, Math.atan2(-this.deltaY, -this.deltaX)) } containsPoint(x, y) { const points = this.getEndPoints(); const dx = points.end.x - points.start.x, dy = points.end.y - points.start.y, length = Math.sqrt(dx ** 2 + dy ** 2), percent = (dx * (x - points.start.x) + dy * (y - points.start.y)) / (length ** 2), distance = (dx * (y - points.start.y) - dy * (x - points.start.x)) / length; return (percent > 0 && percent < 1 && Math.abs(distance) < settings.hitTargetPadding); } }