@@ -3,10 +3,10 @@ import log from '../../log/log';
33import keyMirror from 'keymirror' ;
44
55import Modes from '../../lib/modes' ;
6- import { isBoundsItem } from '../item' ;
7- import { hoverBounds , hoverItem } from '../guides' ;
8- import { sortItemsByZIndex } from '../math' ;
9- import { getSelectedLeafItems , getSelectedSegments } from '../selection' ;
6+ import { isBoundsItem } from '../item' ;
7+ import { hoverBounds , hoverItem } from '../guides' ;
8+ import { sortItemsByZIndex } from '../math' ;
9+ import { getSelectedLeafItems , getSelectedSegments } from '../selection' ;
1010import MoveTool from './move-tool' ;
1111import PointTool from './point-tool' ;
1212import HandleTool from './handle-tool' ;
@@ -32,23 +32,23 @@ const ReshapeModes = keyMirror({
3232 */
3333class ReshapeTool extends paper . Tool {
3434 /** Distance within which mouse is considered to be hitting an item */
35- static get TOLERANCE ( ) {
35+ static get TOLERANCE ( ) {
3636 return ReshapeTool . HANDLE_RADIUS + ReshapeTool . HANDLE_PADDING ;
3737 }
3838 /**
3939 * Units of padding around the visible handle area that will still register clicks as "touching the handle"
4040 */
41- static get HANDLE_PADDING ( ) {
41+ static get HANDLE_PADDING ( ) {
4242 return 1 ;
4343 }
4444 /**
4545 * Handles' radius, including the stroke
4646 */
47- static get HANDLE_RADIUS ( ) {
47+ static get HANDLE_RADIUS ( ) {
4848 return 5.25 ;
4949 }
5050 /** Clicks registered within this amount of time are registered as double clicks */
51- static get DOUBLE_CLICK_MILLIS ( ) {
51+ static get DOUBLE_CLICK_MILLIS ( ) {
5252 return 250 ;
5353 }
5454 /**
@@ -59,7 +59,7 @@ class ReshapeTool extends paper.Tool {
5959 * @param {!function } onUpdateImage A callback to call when the image visibly changes
6060 * @param {!function } switchToTextTool A callback to call to switch to the text tool
6161 */
62- constructor ( setHoveredItem , clearHoveredItem , setSelectedItems , clearSelectedItems , onUpdateImage ,
62+ constructor ( setHoveredItem , clearHoveredItem , setSelectedItems , clearSelectedItems , onUpdateImage ,
6363 switchToTextTool ) {
6464 super ( ) ;
6565 this . setHoveredItem = setHoveredItem ;
@@ -97,7 +97,7 @@ class ReshapeTool extends paper.Tool {
9797 * to be grabbable. (Segments are the little circles)
9898 * @return {object } See paper.Item.hitTest for definition of options
9999 */
100- getSelectedSegmentHitOptions ( ) {
100+ getSelectedSegmentHitOptions ( ) {
101101 const hitOptions = {
102102 segments : true ,
103103 tolerance : ReshapeTool . TOLERANCE / paper . view . zoom ,
@@ -116,7 +116,7 @@ class ReshapeTool extends paper.Tool {
116116 * legitimate hits on other things (like if the handle is over part of the fill). (Handles are the diamonds)
117117 * @return {object } See paper.Item.hitTest for definition of options
118118 */
119- getHandleHitOptions ( ) {
119+ getHandleHitOptions ( ) {
120120 const hitOptions = {
121121 handles : true ,
122122 tolerance : ReshapeTool . TOLERANCE / paper . view . zoom ,
@@ -137,7 +137,7 @@ class ReshapeTool extends paper.Tool {
137137 * unselected things and fills.
138138 * @return {object } See paper.Item.hitTest for definition of options
139139 */
140- getSelectedStrokeHitOptions ( ) {
140+ getSelectedStrokeHitOptions ( ) {
141141 const hitOptions = {
142142 segments : false ,
143143 stroke : false ,
@@ -161,7 +161,7 @@ class ReshapeTool extends paper.Tool {
161161 * selected.
162162 * @return {object } See paper.Item.hitTest for definition of options
163163 */
164- getUnselectedAndFillHitOptions ( ) {
164+ getUnselectedAndFillHitOptions ( ) {
165165 const hitOptions = {
166166 fill : true ,
167167 stroke : true ,
@@ -181,15 +181,15 @@ class ReshapeTool extends paper.Tool {
181181 * @param {paper.Item } prevHoveredItemId ID of the highlight item that indicates the mouse is
182182 * over a given item currently
183183 */
184- setPrevHoveredItemId ( prevHoveredItemId ) {
184+ setPrevHoveredItemId ( prevHoveredItemId ) {
185185 this . prevHoveredItemId = prevHoveredItemId ;
186186 }
187187 /**
188188 * Given the point at which the mouse is, return the prioritized hit result, or null if nothing was hit.
189189 * @param {paper.Point } point Point to hit test on canvas
190190 * @return {?paper.HitResult } hitResult
191191 */
192- getHitResult ( point ) {
192+ getHitResult ( point ) {
193193 // Prefer hits on segments to other types of hits, since segments always overlap curves.
194194 let hitResults =
195195 paper . project . hitTestAll ( point , this . getSelectedSegmentHitOptions ( ) ) ;
@@ -215,7 +215,7 @@ class ReshapeTool extends paper.Tool {
215215 }
216216 return hitResult ;
217217 }
218- handleMouseDown ( event ) {
218+ handleMouseDown ( event ) {
219219 if ( event . event . button > 0 ) return ; // only first mouse button
220220 this . active = true ;
221221 this . clearHoveredItem ( ) ;
@@ -248,9 +248,9 @@ class ReshapeTool extends paper.Tool {
248248 // If item is not yet selected, don't behave differently depending on if they clicked a segment
249249 // (since those were invisible), just select the whole thing as if they clicked the fill.
250250 if ( ! hitResult . item . selected ||
251- hitResult . type === 'fill' ||
252- hitResult . type === 'stroke' ||
253- ( hitResult . type !== 'segment' && doubleClicked ) ) {
251+ hitResult . type === 'fill' ||
252+ hitResult . type === 'stroke' ||
253+ ( hitResult . type !== 'segment' && doubleClicked ) ) {
254254 this . mode = ReshapeModes . FILL ;
255255 this . _modeMap [ this . mode ] . onMouseDown ( hitProperties ) ;
256256 } else if ( hitResult . type === 'segment' ) {
@@ -273,7 +273,7 @@ class ReshapeTool extends paper.Tool {
273273 this . _modeMap [ this . mode ] . onMouseDown ( hitProperties ) ;
274274 }
275275 }
276- handleMouseMove ( event ) {
276+ handleMouseMove ( event ) {
277277 const hitResult = this . getHitResult ( event . point ) ;
278278 let hoveredItem ;
279279
@@ -289,17 +289,17 @@ class ReshapeTool extends paper.Tool {
289289 }
290290
291291 if ( ( ! hoveredItem && this . prevHoveredItemId ) || // There is no longer a hovered item
292- ( hoveredItem && ! this . prevHoveredItemId ) || // There is now a hovered item
293- ( hoveredItem && this . prevHoveredItemId &&
294- hoveredItem . id !== this . prevHoveredItemId ) ) { // hovered item changed
292+ ( hoveredItem && ! this . prevHoveredItemId ) || // There is now a hovered item
293+ ( hoveredItem && this . prevHoveredItemId &&
294+ hoveredItem . id !== this . prevHoveredItemId ) ) { // hovered item changed
295295 this . setHoveredItem ( hoveredItem ? hoveredItem . id : null ) ;
296296 }
297297 }
298- handleMouseDrag ( event ) {
298+ handleMouseDrag ( event ) {
299299 if ( event . event . button > 0 || ! this . active ) return ; // only first mouse button
300300 this . _modeMap [ this . mode ] . onMouseDrag ( event ) ;
301301 }
302- handleMouseUp ( event ) {
302+ handleMouseUp ( event ) {
303303 if ( event . event . button > 0 || ! this . active ) return ; // only first mouse button
304304 if ( this . mode === ReshapeModes . SELECTION_BOX ) {
305305 this . _modeMap [ this . mode ] . onMouseUpVector ( event ) ;
@@ -309,7 +309,7 @@ class ReshapeTool extends paper.Tool {
309309 this . mode = ReshapeModes . SELECTION_BOX ;
310310 this . active = false ;
311311 }
312- handleKeyDown ( event ) {
312+ handleKeyDown ( event ) {
313313 if ( event . event . target instanceof HTMLInputElement || event . event . target instanceof HTMLTextAreaElement ) {
314314 // Ignore nudge if a text input field is focused
315315 return ;
@@ -329,15 +329,19 @@ class ReshapeTool extends paper.Tool {
329329 } else if ( event . key === 'right' ) {
330330 translation = new paper . Point ( nudgeAmount , 0 ) ;
331331 } else if ( event . key == 'i' || event . key == 'o' ) {
332-
332+
333333 const segments = getSelectedSegments ( ) ;
334334 for ( const seg of segments ) {
335335 let parent = seg . path ;
336336 let p = seg . point ;
337+ let o = parent . getOffsetOf ( p ) ;
338+ let o1 = o + 0.01 ;
339+ let o2 = o + ( parent . length - 0.01 ) ;
340+ let n = ( parent . getNormalAt ( o1 % parent . length ) . add ( parent . getNormalAt ( o2 % parent . length ) ) ) . divide ( 2 ) ;
337341 if ( event . key == 'o' ) {
338- seg . point = p . add ( parent . getNormalAt ( parent . getOffsetOf ( p ) ) ) ;
342+ seg . point = p . add ( n ) ;
339343 } else {
340- seg . point = p . subtract ( parent . getNormalAt ( parent . getOffsetOf ( p ) ) ) ;
344+ seg . point = p . subtract ( n ) ;
341345 }
342346 }
343347 }
@@ -356,15 +360,15 @@ class ReshapeTool extends paper.Tool {
356360 }
357361 }
358362 }
359- handleKeyUp ( event ) {
363+ handleKeyUp ( event ) {
360364 const selected = getSelectedLeafItems ( ) ;
361365 if ( selected . length === 0 ) return ;
362366
363367 if ( event . key === 'up' || event . key === 'down' || event . key === 'left' || event . key === 'right' ) {
364368 this . onUpdateImage ( ) ;
365369 }
366370 }
367- deactivateTool ( ) {
371+ deactivateTool ( ) {
368372 paper . settings . handleSize = 0 ;
369373 this . clearHoveredItem ( ) ;
370374 this . setHoveredItem = null ;
0 commit comments