Change handle ratio to make squares circles

This commit is contained in:
DD 2017-12-22 11:32:06 -05:00
parent 396e73e640
commit db5ddcbe87
3 changed files with 20 additions and 13 deletions

View file

@ -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.

View file

@ -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,

View file

@ -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;
}