From 765e2e446e231f2e84ccf8b0877e4f3c4d47c54f Mon Sep 17 00:00:00 2001 From: stockiNail Date: Tue, 11 Jul 2023 17:20:08 +0200 Subject: [PATCH] code improving --- src/helpers/helpers.core.js | 15 ++++++++++----- src/types/box.js | 3 +-- src/types/ellipse.js | 15 ++++++--------- src/types/label.js | 3 +-- src/types/line.js | 13 ++++++------- src/types/point.js | 10 ++++------ src/types/polygon.js | 2 +- 7 files changed, 29 insertions(+), 32 deletions(-) diff --git a/src/helpers/helpers.core.js b/src/helpers/helpers.core.js index 9c3f465c..9b1bfbe8 100644 --- a/src/helpers/helpers.core.js +++ b/src/helpers/helpers.core.js @@ -9,6 +9,13 @@ const isOlderPart = (act, req) => req > act || (act.length > req.length && act.s export const EPSILON = 0.001; export const clamp = (x, from, to) => Math.min(to, Math.max(from, x)); +/** + * @param {{value: number, start: number, end: number}} limit + * @param {number} hitSize + * @returns {boolean} + */ +export const inLimit = (limit, hitSize) => limit.value >= limit.start - hitSize && limit.value <= limit.end + hitSize; + /** * @param {Object} obj * @param {number} from @@ -26,16 +33,14 @@ export function clampAll(obj, from, to) { * @param {Point} point * @param {Point} center * @param {number} radius - * @param {number} borderWidth + * @param {number} hitSize * @returns {boolean} */ -export function inPointRange(point, center, radius, {borderWidth, hitTolerance}) { +export function inPointRange(point, center, radius, hitSize) { if (!point || !center || radius <= 0) { return false; } - const hBorderWidth = borderWidth / 2; - const tolerance = hitTolerance / 2; - return (Math.pow(point.x - center.x, 2) + Math.pow(point.y - center.y, 2)) <= Math.pow(radius + hBorderWidth + tolerance, 2); + return (Math.pow(point.x - center.x, 2) + Math.pow(point.y - center.y, 2)) <= Math.pow(radius + hitSize, 2); } /** diff --git a/src/types/box.js b/src/types/box.js index be9b96d4..42ce4d54 100644 --- a/src/types/box.js +++ b/src/types/box.js @@ -6,8 +6,7 @@ export default class BoxAnnotation extends Element { inRange(mouseX, mouseY, axis, useFinalPosition) { const {x, y} = rotated({x: mouseX, y: mouseY}, this.getCenterPoint(useFinalPosition), toRadians(-this.options.rotation)); - const {borderWidth, hitTolerance} = this.options; - return inBoxRange({x, y}, this.getProps(['x', 'y', 'x2', 'y2'], useFinalPosition), axis, {borderWidth, hitTolerance}); + return inBoxRange({x, y}, this.getProps(['x', 'y', 'x2', 'y2'], useFinalPosition), axis, this.options); } getCenterPoint(useFinalPosition) { diff --git a/src/types/ellipse.js b/src/types/ellipse.js index 96e5519a..211d0e51 100644 --- a/src/types/ellipse.js +++ b/src/types/ellipse.js @@ -6,16 +6,15 @@ import BoxAnnotation from './box'; export default class EllipseAnnotation extends Element { inRange(mouseX, mouseY, axis, useFinalPosition) { - const {rotation, borderWidth, hitTolerance} = this.options; + const rotation = this.options.rotation; + const hitSize = (this.options.borderWidth + this.options.hitTolerance) / 2; if (axis !== 'x' && axis !== 'y') { - return pointInEllipse({x: mouseX, y: mouseY}, this.getProps(['width', 'height', 'centerX', 'centerY'], useFinalPosition), {rotation, borderWidth, hitTolerance}); + return pointInEllipse({x: mouseX, y: mouseY}, this.getProps(['width', 'height', 'centerX', 'centerY'], useFinalPosition), rotation, hitSize); } const {x, y, x2, y2} = this.getProps(['x', 'y', 'x2', 'y2'], useFinalPosition); - const hBorderWidth = borderWidth / 2; - const tolerance = hitTolerance / 2; const limit = axis === 'y' ? {start: y, end: y2} : {start: x, end: x2}; const rotatedPoint = rotated({x: mouseX, y: mouseY}, this.getCenterPoint(useFinalPosition), toRadians(-rotation)); - return rotatedPoint[axis] >= limit.start - hBorderWidth - tolerance - EPSILON && rotatedPoint[axis] <= limit.end + hBorderWidth + tolerance + EPSILON; + return rotatedPoint[axis] >= limit.start - hitSize - EPSILON && rotatedPoint[axis] <= limit.end + hitSize + EPSILON; } getCenterPoint(useFinalPosition) { @@ -86,7 +85,7 @@ EllipseAnnotation.descriptors = { } }; -function pointInEllipse(p, ellipse, {rotation, borderWidth, hitTolerance}) { +function pointInEllipse(p, ellipse, rotation, hitSize) { const {width, height, centerX, centerY} = ellipse; const xRadius = width / 2; const yRadius = height / 2; @@ -96,11 +95,9 @@ function pointInEllipse(p, ellipse, {rotation, borderWidth, hitTolerance}) { } // https://stackoverflow.com/questions/7946187/point-and-ellipse-rotated-position-test-algorithm const angle = toRadians(rotation || 0); - const hBorderWidth = borderWidth / 2 || 0; - const tolerance = hitTolerance / 2 || 0; const cosAngle = Math.cos(angle); const sinAngle = Math.sin(angle); const a = Math.pow(cosAngle * (p.x - centerX) + sinAngle * (p.y - centerY), 2); const b = Math.pow(sinAngle * (p.x - centerX) - cosAngle * (p.y - centerY), 2); - return (a / Math.pow(xRadius + hBorderWidth + tolerance, 2)) + (b / Math.pow(yRadius + hBorderWidth + tolerance, 2)) <= 1.0001; + return (a / Math.pow(xRadius + hitSize, 2)) + (b / Math.pow(yRadius + hitSize, 2)) <= 1.0001; } diff --git a/src/types/label.js b/src/types/label.js index 2df5ea01..881f1c4b 100644 --- a/src/types/label.js +++ b/src/types/label.js @@ -8,8 +8,7 @@ export default class LabelAnnotation extends Element { inRange(mouseX, mouseY, axis, useFinalPosition) { const {x, y} = rotated({x: mouseX, y: mouseY}, this.getCenterPoint(useFinalPosition), toRadians(-this.rotation)); - const {borderWidth, hitTolerance} = this.options; - return inBoxRange({x, y}, this.getProps(['x', 'y', 'x2', 'y2'], useFinalPosition), axis, {borderWidth, hitTolerance}); + return inBoxRange({x, y}, this.getProps(['x', 'y', 'x2', 'y2'], useFinalPosition), axis, this.options); } getCenterPoint(useFinalPosition) { diff --git a/src/types/line.js b/src/types/line.js index fd3df5a8..dcf5715d 100644 --- a/src/types/line.js +++ b/src/types/line.js @@ -1,6 +1,6 @@ import {Element} from 'chart.js'; import {PI, toRadians, toDegrees, toPadding, distanceBetweenPoints} from 'chart.js/helpers'; -import {EPSILON, clamp, rotated, measureLabelSize, getRelativePosition, setBorderStyle, setShadowStyle, getElementCenterPoint, toPosition, getSize, resolveLineProperties, initAnimationProperties} from '../helpers'; +import {EPSILON, clamp, rotated, measureLabelSize, getRelativePosition, setBorderStyle, setShadowStyle, getElementCenterPoint, toPosition, getSize, resolveLineProperties, initAnimationProperties, inLimit} from '../helpers'; import LabelAnnotation from './label'; const pointInLine = (p1, p2, t) => ({x: p1.x + t * (p2.x - p1.x), y: p1.y + t * (p2.y - p1.y)}); @@ -17,8 +17,7 @@ const angleInCurve = (start, cp, end, t) => -Math.atan2(coordAngleInCurve(start. export default class LineAnnotation extends Element { inRange(mouseX, mouseY, axis, useFinalPosition) { - const hBorderWidth = this.options.borderWidth / 2; - const tolerance = this.options.hitTolerance / 2; + const hitSize = (this.options.borderWidth + this.options.hitTolerance) / 2; if (axis !== 'x' && axis !== 'y') { const point = {mouseX, mouseY}; const {path, ctx} = this; @@ -32,10 +31,10 @@ export default class LineAnnotation extends Element { ctx.restore(); return result; } - const epsilon = sqr(hBorderWidth + tolerance); + const epsilon = sqr(hitSize); return intersects(this, point, epsilon, useFinalPosition) || isOnLabel(this, point, useFinalPosition); } - return inAxisRange(this, {mouseX, mouseY}, axis, {hBorderWidth, tolerance, useFinalPosition}); + return inAxisRange(this, {mouseX, mouseY}, axis, {hitSize, useFinalPosition}); } getCenterPoint(useFinalPosition) { @@ -215,9 +214,9 @@ LineAnnotation.defaultRoutes = { borderColor: 'color' }; -function inAxisRange(element, {mouseX, mouseY}, axis, {hBorderWidth, tolerance, useFinalPosition}) { +function inAxisRange(element, {mouseX, mouseY}, axis, {hitSize, useFinalPosition}) { const limit = rangeLimit(mouseX, mouseY, element.getProps(['x', 'y', 'x2', 'y2'], useFinalPosition), axis); - return (limit.value >= limit.start - hBorderWidth - tolerance && limit.value <= limit.end + hBorderWidth + tolerance) || isOnLabel(element, {mouseX, mouseY}, useFinalPosition, axis); + return inLimit(limit, hitSize) || isOnLabel(element, {mouseX, mouseY}, useFinalPosition, axis); } function isLineInArea({x, y, x2, y2}, {top, right, bottom, left}) { diff --git a/src/types/point.js b/src/types/point.js index af9bed07..615051be 100644 --- a/src/types/point.js +++ b/src/types/point.js @@ -1,18 +1,16 @@ import {Element} from 'chart.js'; -import {inPointRange, getElementCenterPoint, resolvePointProperties, setBorderStyle, setShadowStyle, isImageOrCanvas, initAnimationProperties, drawPoint} from '../helpers'; +import {inPointRange, getElementCenterPoint, resolvePointProperties, setBorderStyle, setShadowStyle, isImageOrCanvas, initAnimationProperties, drawPoint, inLimit} from '../helpers'; export default class PointAnnotation extends Element { inRange(mouseX, mouseY, axis, useFinalPosition) { const {x, y, x2, y2, width} = this.getProps(['x', 'y', 'x2', 'y2', 'width'], useFinalPosition); - const {hitTolerance, borderWidth} = this.options; + const hitSize = (this.options.borderWidth + this.options.hitTolerance) / 2; if (axis !== 'x' && axis !== 'y') { - return inPointRange({x: mouseX, y: mouseY}, this.getCenterPoint(useFinalPosition), width / 2, {borderWidth, hitTolerance}); + return inPointRange({x: mouseX, y: mouseY}, this.getCenterPoint(useFinalPosition), width / 2, hitSize); } - const hBorderWidth = borderWidth / 2; - const tolerance = hitTolerance / 2; const limit = axis === 'y' ? {start: y, end: y2, value: mouseY} : {start: x, end: x2, value: mouseX}; - return limit.value >= limit.start - hBorderWidth - tolerance && limit.value <= limit.end + hBorderWidth + tolerance; + return inLimit(limit, hitSize); } getCenterPoint(useFinalPosition) { diff --git a/src/types/polygon.js b/src/types/polygon.js index 42711211..577d22b1 100644 --- a/src/types/polygon.js +++ b/src/types/polygon.js @@ -103,7 +103,7 @@ PolygonAnnotation.defaultRoutes = { }; function buildPointElement({centerX, centerY}, {radius, borderWidth, hitTolerance}, rad) { - const hitSize = borderWidth / 2 + hitTolerance / 2; + const hitSize = (borderWidth + hitTolerance) / 2; const sin = Math.sin(rad); const cos = Math.cos(rad); const point = {x: centerX + sin * radius, y: centerY - cos * radius};