@@ -12,6 +12,8 @@ let brushSize = 3;
1212let autofill = false ;
1313
1414let trailPoints = [ ] ;
15+ let lineToolStart = null ;
16+ let lineToolPreview = null ;
1517
1618function pressure ( e ) {
1719 const pid = Number . isFinite ( e ?. pointerId ) ? e . pointerId : - 1 ;
@@ -338,6 +340,17 @@ function startStroke(e) {
338340 startPan ( e ) ;
339341 return ;
340342 }
343+ if ( tool === "line" ) {
344+ isDrawing = true ;
345+ const hex = colorToHex ( currentColor ) ;
346+ strokeHex = activeLayer === LAYER . FILL ? fillWhite : hex ;
347+ activeSubColor [ activeLayer ] = strokeHex ;
348+ ensureSublayer ( activeLayer , strokeHex ) ;
349+ renderLayerSwatches ( activeLayer ) ;
350+ lineToolStart = { x, y } ;
351+ lineToolPreview = { x, y } ;
352+ return ;
353+ }
341354 if ( activeLayer === PAPER_LAYER ) {
342355 return ;
343356 }
@@ -404,6 +417,11 @@ function continueStroke(e) {
404417 } ;
405418 return ;
406419 }
420+ if ( tool === "line" ) {
421+ lineToolPreview = { x, y } ;
422+ queueRenderAll ( ) ;
423+ return ;
424+ }
407425 if ( tool === "fill-eraser" || tool === "fill-brush" ) {
408426 fxTransform ( ) ;
409427 fxStamp1px ( lastPt . x , lastPt . y , x , y ) ;
@@ -474,6 +492,25 @@ function endStroke() {
474492 stabilizedPt = null ;
475493 return ;
476494 }
495+ if ( tool === "line" && lineToolStart && lineToolPreview ) {
496+ const hex = strokeHex || activeSubColor ?. [ activeLayer ] || colorToHex ( currentColor ) ;
497+ const off = getFrameCanvas ( activeLayer , currentFrame , hex ) ;
498+ const ctx = off . getContext ( "2d" ) ;
499+ ctx . lineCap = "round" ;
500+ ctx . lineJoin = "round" ;
501+ ctx . lineWidth = brushSize ;
502+ ctx . strokeStyle = hex ;
503+ ctx . beginPath ( ) ;
504+ ctx . moveTo ( lineToolStart . x , lineToolStart . y ) ;
505+ ctx . lineTo ( lineToolPreview . x , lineToolPreview . y ) ;
506+ ctx . stroke ( ) ;
507+ markFrameHasContent ( activeLayer , currentFrame , hex ) ;
508+ lineToolStart = null ;
509+ lineToolPreview = null ;
510+ queueRenderAll ( ) ;
511+ updateTimelineHasContent ( currentFrame ) ;
512+ return ;
513+ }
477514 if ( tool === "lasso-erase" && lassoActive ) {
478515 lassoActive = false ;
479516 applyLassoErase ( ) ;
@@ -843,6 +880,20 @@ function drawRectSelectionOverlay(ctx) {
843880 ctx . strokeRect ( rectSelection . x , rectSelection . y , rectSelection . w , rectSelection . h ) ;
844881 ctx . restore ( ) ;
845882}
883+ function drawLineToolPreview ( ctx ) {
884+ if ( ! lineToolStart || ! lineToolPreview ) return ;
885+ ctx . save ( ) ;
886+ ctx . lineCap = "round" ;
887+ ctx . lineJoin = "round" ;
888+ ctx . lineWidth = brushSize ;
889+ ctx . strokeStyle = currentColor ;
890+ ctx . globalAlpha = 0.5 ;
891+ ctx . beginPath ( ) ;
892+ ctx . moveTo ( lineToolStart . x , lineToolStart . y ) ;
893+ ctx . lineTo ( lineToolPreview . x , lineToolPreview . y ) ;
894+ ctx . stroke ( ) ;
895+ ctx . restore ( ) ;
896+ }
846897function beginRectSelect ( e ) {
847898 if ( activeLayer === PAPER_LAYER ) return ;
848899 const pos = getCanvasPointer ( e ) ;
0 commit comments