From c4070bb1bc332524e5094ed71cf9d6f96d69b275 Mon Sep 17 00:00:00 2001 From: Martin Veillette Date: Fri, 3 Feb 2023 15:34:50 -0600 Subject: [PATCH] set penultimatePosition to null at start od drag (see #218) Signed-off-by: Martin Veillette --- js/common/model/TransformedCurve.ts | 78 +++++++++++++++-------------- js/common/view/OriginalGraphNode.ts | 9 ++-- 2 files changed, 46 insertions(+), 41 deletions(-) diff --git a/js/common/model/TransformedCurve.ts b/js/common/model/TransformedCurve.ts index 1f5cce06..cf400ad4 100644 --- a/js/common/model/TransformedCurve.ts +++ b/js/common/model/TransformedCurve.ts @@ -277,6 +277,37 @@ export default class TransformedCurve extends Curve { ); } + public manipulateCurve( mode: CurveManipulationMode, + width: number, + position: Vector2, + penultimatePosition: Vector2 | null, + antepenultimatePosition: Vector2 | null ): void { + + this.wasManipulatedProperty.value = true; + + if ( mode === CurveManipulationMode.HILL || + mode === CurveManipulationMode.PARABOLA || + mode === CurveManipulationMode.PEDESTAL || + mode === CurveManipulationMode.TRIANGLE || + mode === CurveManipulationMode.SINE + ) { + this.widthManipulatedCurve( mode, width, position.x, position.y ); + } + else if ( mode === CurveManipulationMode.TILT || + mode === CurveManipulationMode.SHIFT ) { + this.positionManipulatedCurve( mode, position.x, position.y ); + } + else if ( mode === CurveManipulationMode.FREEFORM ) { + this.drawFreeformToPosition( position, penultimatePosition, antepenultimatePosition ); + } + else { + throw new Error( 'Unsupported Curve Manipulation Mode' ); + } + + // Signals that this Curve has changed. + this.curveChangedEmitter.emit(); + } + /** * Allows the user to drag Points in the Curve to any desired position to create custom but smooth shapes. * This method will update the curve with the new position value. It attempts to create a smooth curve @@ -290,7 +321,7 @@ export default class TransformedCurve extends Curve { * @param antepenultimatePosition - in model coordinates */ private drawFreeformToPosition( position: Vector2, - penultimatePosition: Vector2, + penultimatePosition: Vector2 | null, antepenultimatePosition: Vector2 | null ): void { // Closest point associated with the position @@ -300,13 +331,17 @@ export default class TransformedCurve extends Curve { closestPoint.y = position.y; // Point associated with the last drag event - const lastPoint = this.getClosestPointAt( penultimatePosition.x ); + if ( penultimatePosition ) { + const lastPoint = this.getClosestPointAt( penultimatePosition.x ); + - // We want to create a straight line between this point and the last drag event point - const closestVector = closestPoint.getVector(); - this.interpolate( closestVector.x, closestVector.y, lastPoint.x, penultimatePosition.y ); + // We want to create a straight line between this point and the last drag event point + const closestVector = closestPoint.getVector(); + this.interpolate( closestVector.x, closestVector.y, lastPoint.x, penultimatePosition.y ); + } + if ( penultimatePosition && antepenultimatePosition ) { - if ( antepenultimatePosition ) { + const lastPoint = this.getClosestPointAt( penultimatePosition.x ); // Point associated with the last drag event const nextToLastPoint = this.getClosestPointAt( antepenultimatePosition.x ); @@ -367,37 +402,6 @@ export default class TransformedCurve extends Curve { } } - public manipulateCurve( mode: CurveManipulationMode, - width: number, - position: Vector2, - penultimatePosition: Vector2, - antepenultimatePosition: Vector2 | null ): void { - - this.wasManipulatedProperty.value = true; - - if ( mode === CurveManipulationMode.HILL || - mode === CurveManipulationMode.PARABOLA || - mode === CurveManipulationMode.PEDESTAL || - mode === CurveManipulationMode.TRIANGLE || - mode === CurveManipulationMode.SINE - ) { - this.widthManipulatedCurve( mode, width, position.x, position.y ); - } - else if ( mode === CurveManipulationMode.TILT || - mode === CurveManipulationMode.SHIFT ) { - this.positionManipulatedCurve( mode, position.x, position.y ); - } - else if ( mode === CurveManipulationMode.FREEFORM ) { - this.drawFreeformToPosition( position, penultimatePosition, antepenultimatePosition ); - } - else { - throw new Error( 'Unsupported Curve Manipulation Mode' ); - } - - // Signals that this Curve has changed. - this.curveChangedEmitter.emit(); - } - /** * Sets the y-value of points between position1 and position2 using a linear interpolation */ diff --git a/js/common/view/OriginalGraphNode.ts b/js/common/view/OriginalGraphNode.ts index 5de108b2..90cac4d5 100644 --- a/js/common/view/OriginalGraphNode.ts +++ b/js/common/view/OriginalGraphNode.ts @@ -160,19 +160,18 @@ export default class OriginalGraphNode extends GraphNode { ); // Update whichever curve is currently interactive. - let penultimatePosition: Vector2; + let penultimatePosition: Vector2 | null = null; let antepenultimatePosition: Vector2 | null = null; const updateCurve = ( listener: PressedDragListener ): void => { // These listener 'fields' are actually ES5 getters that allocate a Vector2, so call them only once. const modelPoint = listener.modelPoint; - const modelDelta = listener.modelDelta; // Current modelPosition const modelPosition = this.chartTransform.viewToModelPosition( modelPoint ); // Previous (model) position the drag - penultimatePosition = this.chartTransform.viewToModelPosition( modelPoint.minus( modelDelta ) ); + // Update curve based on mode and width interactiveCurveNodeProperty.value.transformedCurve.manipulateCurve( @@ -184,6 +183,7 @@ export default class OriginalGraphNode extends GraphNode { // Update antepenultimatePosition antepenultimatePosition = penultimatePosition; + penultimatePosition = modelPosition; }; // Instead of having a DragListener on each TransformedCurveNode, we have a single DragListener on the chartRectangle. @@ -200,8 +200,9 @@ export default class OriginalGraphNode extends GraphNode { // This must be called once at the start of dragging (and not on each micro drag-position change). interactiveCurveNodeProperty.value.transformedCurve.saveCurrentPoints(); - // Set the second to last position to null, since it is a new drag. + // Set the previous last positions to null, since it is a new drag. antepenultimatePosition = null; + penultimatePosition = null; updateCurve( listener ); }, drag: ( event, listener ) => updateCurve( listener ),