From db5ddcbe874a425775b4bd507bb3a3da3bb112ef Mon Sep 17 00:00:00 2001 From: DD Date: Fri, 22 Dec 2017 11:32:06 -0500 Subject: [PATCH] Change handle ratio to make squares circles --- src/containers/mode-tools.jsx | 15 ++++++++------- src/helper/math.js | 4 ++++ src/helper/selection-tools/point-tool.js | 14 ++++++++------ 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/containers/mode-tools.jsx b/src/containers/mode-tools.jsx index e260245c..8450c258 100644 --- a/src/containers/mode-tools.jsx +++ b/src/containers/mode-tools.jsx @@ -8,6 +8,7 @@ import ModeToolsComponent from '../components/mode-tools/mode-tools.jsx'; import {clearSelectedItems, setSelectedItems} from '../reducers/selected-items'; import {incrementPasteOffset, setClipboardItems} from '../reducers/clipboard'; import {clearSelection, getSelectedLeafItems, getSelectedRootItems} from '../helper/selection'; +import {HANDLE_RATIO} from '../helper/math'; class ModeTools extends React.Component { constructor (props) { @@ -78,29 +79,29 @@ class ModeTools extends React.Component { // Handles are parallel to the line from prev to next point.handleIn = prev.point.subtract(next.point) .normalize() - .multiply(prev.getCurve().length / 2); + .multiply(prev.getCurve().length * HANDLE_RATIO); } else if (prev && !next && point.handleIn.length === 0) { // Point is end point // Direction is average of normal at the point and direction to prev point, using the // normal that points out from the convex side - // Lenth is curve length / 2 - const convexity = prev.getCurve().getCurvatureAt(.1) < 0 ? -1 : 1; + // Lenth is curve length * HANDLE_RATIO + const convexity = prev.getCurve().getCurvatureAtTime(.1) < 0 ? -1 : 1; point.handleIn = (prev.getCurve().getNormalAtTime(1) .multiply(convexity) .add(prev.point.subtract(point.point).normalize())) .normalize() - .multiply(prev.getCurve().length / 2); + .multiply(prev.getCurve().length * HANDLE_RATIO); } else if (next && !prev && point.handleOut.length === 0) { // Point is start point // Direction is average of normal at the point and direction to prev point, using the // normal that points out from the convex side - // Lenth is curve length / 2 - const convexity = point.getCurve().getCurvatureAt(.1) < 0 ? -1 : 1; + // Lenth is curve length * HANDLE_RATIO + const convexity = point.getCurve().getCurvatureAtTime(.1) < 0 ? -1 : 1; point.handleOut = (point.getCurve().getNormalAtTime(0) .multiply(convexity) .add(next.point.subtract(point.point).normalize())) .normalize() - .multiply(point.getCurve().length / 2); + .multiply(point.getCurve().length * HANDLE_RATIO); } // Point guaranteed to have a handle now. Make the second handle match the length and direction of first. diff --git a/src/helper/math.js b/src/helper/math.js index 5c74c740..cab99242 100644 --- a/src/helper/math.js +++ b/src/helper/math.js @@ -1,5 +1,8 @@ import paper from '@scratch/paper'; +/** The ratio of the curve length to use for the handle length to convert squares into approximately circles. */ +const HANDLE_RATIO = 0.3902628565; + const checkPointsClose = function (startPos, eventPoint, threshold) { const xOff = Math.abs(startPos.x - eventPoint.x); const yOff = Math.abs(startPos.y - eventPoint.y); @@ -95,6 +98,7 @@ const expandByOne = function (path) { }; export { + HANDLE_RATIO, checkPointsClose, expandByOne, getRandomInt, diff --git a/src/helper/selection-tools/point-tool.js b/src/helper/selection-tools/point-tool.js index 0c88d2f9..9a9ddd4b 100644 --- a/src/helper/selection-tools/point-tool.js +++ b/src/helper/selection-tools/point-tool.js @@ -1,6 +1,7 @@ import paper from '@scratch/paper'; import {snapDeltaToAngle} from '../math'; import {clearSelection, getSelectedLeafItems} from '../selection'; +import {HANDLE_RATIO} from '../math'; /** Subtool of ReshapeTool for moving control points. */ class PointTool { @@ -72,8 +73,8 @@ class PointTool { hitProperties.hitResult.location.curve.length - hitProperties.hitResult.location.curveOffset; // Handle length based on curve length until next point - let handleIn = hitProperties.hitResult.location.tangent.multiply(-beforeCurveLength / 2); - let handleOut = hitProperties.hitResult.location.tangent.multiply(afterCurveLength / 2); + let handleIn = hitProperties.hitResult.location.tangent.multiply(-beforeCurveLength * HANDLE_RATIO); + let handleOut = hitProperties.hitResult.location.tangent.multiply(afterCurveLength * HANDLE_RATIO); // Don't let one handle overwhelm the other (results in path doubling back on itself weirdly) if (handleIn.length > 3 * handleOut.length) { handleIn = handleIn.multiply(3 * handleOut.length / handleIn.length); @@ -98,7 +99,7 @@ class PointTool { if (beforeSegment && beforeSegment.handleOut) { if (afterSegment) { beforeSegment.handleOut = - beforeSegment.handleOut.multiply(beforeCurveLength / 2 / beforeSegment.handleOut.length); + beforeSegment.handleOut.multiply(beforeCurveLength * HANDLE_RATIO / beforeSegment.handleOut.length); } else { beforeSegment.handleOut = null; } @@ -106,7 +107,7 @@ class PointTool { if (afterSegment && afterSegment.handleIn) { if (beforeSegment) { afterSegment.handleIn = - afterSegment.handleIn.multiply(afterCurveLength / 2 / afterSegment.handleIn.length); + afterSegment.handleIn.multiply(afterCurveLength * HANDLE_RATIO / afterSegment.handleIn.length); } else { afterSegment.handleIn = null; } @@ -123,14 +124,15 @@ class PointTool { if (beforeSegment && beforeSegment.handleOut) { if (afterSegment) { beforeSegment.handleOut = - beforeSegment.handleOut.multiply(curveLength / 2 / beforeSegment.handleOut.length); + beforeSegment.handleOut.multiply(curveLength * HANDLE_RATIO / beforeSegment.handleOut.length); } else { beforeSegment.handleOut = null; } } if (afterSegment && afterSegment.handleIn) { if (beforeSegment) { - afterSegment.handleIn = afterSegment.handleIn.multiply(curveLength / 2 / afterSegment.handleIn.length); + afterSegment.handleIn = + afterSegment.handleIn.multiply(curveLength * HANDLE_RATIO / afterSegment.handleIn.length); } else { afterSegment.handleIn = null; }