diff --git a/Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs b/Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs index fcc8edf8..eda21e3c 100644 --- a/Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs +++ b/Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs @@ -452,20 +452,47 @@ namespace Ink_Canvas if (isWaitUntilNextTouchDown && dec.Count > 1) return; if (dec.Count > 1) { - try + // 修复:双曲线绘制时,多指触摸不应该删除第一笔的辅助线 + if ((drawingShapeMode == 24 || drawingShapeMode == 25) && drawMultiStepShapeCurrentStep == 1) { - inkCanvas.Strokes.Remove(lastTempStroke); - inkCanvas.Strokes.Remove(lastTempStrokeCollection); + // 第二笔绘制双曲线时,只删除第二笔的临时笔画,保留第一笔的辅助线 + try + { + inkCanvas.Strokes.Remove(lastTempStroke); + } + catch { } + return; } - catch + else { - Trace.WriteLine("lastTempStrokeCollection failed."); + // 其他情况正常删除临时笔画 + try + { + inkCanvas.Strokes.Remove(lastTempStroke); + inkCanvas.Strokes.Remove(lastTempStrokeCollection); + } + catch + { + Trace.WriteLine("lastTempStrokeCollection failed."); + } + return; } - return; } - // 在几何绘制模式下,确保处理单点触控的移动事件 + + // 修复:双曲线绘制时,第二笔应该基于第一笔的起点,而不是触摸实时位置 Point touchPoint = e.GetTouchPoint(inkCanvas).Position; - MouseTouchMove(touchPoint); + if ((drawingShapeMode == 24 || drawingShapeMode == 25) && drawMultiStepShapeCurrentStep == 1) + { + // 第二笔绘制双曲线时,使用触摸位置作为终点,但保持第一笔的起点 + // 这里不需要特殊处理,因为MouseTouchMove函数内部已经正确处理了双曲线的绘制逻辑 + MouseTouchMove(touchPoint); + } + else + { + // 其他情况正常处理 + MouseTouchMove(touchPoint); + } + return; // 处理完几何绘制后直接返回,不执行后面的代码 } @@ -944,9 +971,18 @@ namespace Ink_Canvas GenerateDashedLineStrokeCollection(new Point(2 * iniP.X - endP.X, 2 * iniP.Y - endP.Y), endP)); strokes.Add(GenerateDashedLineStrokeCollection(new Point(2 * iniP.X - endP.X, endP.Y), - new Point(endP.X, 2 * iniP.Y - endP.Y))); + new Point(endP.X, 2 * iniP.Y - endP.Y))); drawMultiStepShapeSpecialParameter3 = k; drawMultiStepShapeSpecialStrokeCollection = strokes; + + // 修复:第一笔绘制的辅助线应该立即显示在画布上 + try + { + inkCanvas.Strokes.Remove(lastTempStrokeCollection); + } + catch { } + lastTempStrokeCollection = strokes; + inkCanvas.Strokes.Add(strokes); } else { @@ -1032,17 +1068,40 @@ namespace Ink_Canvas } } + // 修复:双曲线绘制完成后,需要将第一笔的辅助线和第二笔的双曲线合并 try { + // 删除第二笔的临时笔画 inkCanvas.Strokes.Remove(lastTempStrokeCollection); + + // 创建包含辅助线和双曲线的完整笔画集合 + var completeStrokes = new StrokeCollection(); + + // 添加第一笔的辅助线 + if (drawMultiStepShapeSpecialStrokeCollection != null && drawMultiStepShapeSpecialStrokeCollection.Count > 0) + { + foreach (var stroke1 in drawMultiStepShapeSpecialStrokeCollection) + { + completeStrokes.Add(stroke1.Clone()); + } + } + + // 添加第二笔的双曲线 + foreach (var stroke1 in strokes) + { + completeStrokes.Add(stroke1.Clone()); + } + + lastTempStrokeCollection = completeStrokes; + inkCanvas.Strokes.Add(completeStrokes); } - catch + catch (Exception ex) { - Trace.WriteLine("lastTempStrokeCollection failed."); + Trace.WriteLine($"双曲线绘制完成处理失败: {ex.Message}"); + // 如果合并失败,至少添加双曲线部分 + lastTempStrokeCollection = strokes; + inkCanvas.Strokes.Add(strokes); } - - lastTempStrokeCollection = strokes; - inkCanvas.Strokes.Add(strokes); break; case 20: _currentCommitType = CommitReason.ShapeDrawing; @@ -1811,9 +1870,12 @@ namespace Ink_Canvas private bool NeedUpdateIniP() { + // 修复:双曲线绘制时,第二笔不应该更新起点,保持第一笔的起点 if (drawingShapeMode == 24 || drawingShapeMode == 25) + { if (drawMultiStepShapeCurrentStep == 1) - return false; + return false; // 第二笔不更新起点 + } return true; } diff --git a/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs b/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs index 787dc8c2..6174a350 100644 --- a/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs +++ b/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs @@ -350,53 +350,83 @@ namespace Ink_Canvas ViewboxFloatingBar.IsHitTestVisible = false; BlackboardUIGridForInkReplay.IsHitTestVisible = false; - // 只记录几何绘制的起点,不记录触摸轨迹 - if (dec.Count == 0) - { - var touchPoint = e.GetTouchPoint(inkCanvas); - iniP = touchPoint.Position; - lastTouchDownStrokeCollection = inkCanvas.Strokes.Clone(); - } - dec.Add(e.TouchDevice.Id); - return; - } - SetCursorBasedOnEditingMode(inkCanvas); - - inkCanvas.CaptureTouch(e.TouchDevice); - ViewboxFloatingBar.IsHitTestVisible = false; - BlackboardUIGridForInkReplay.IsHitTestVisible = false; - - dec.Add(e.TouchDevice.Id); - // Palm Eraser 逻辑 - if (Settings.Canvas.EnablePalmEraser && dec.Count >= 2 && !isPalmEraserActive) - { - var bounds = e.GetTouchPoint(inkCanvas).Bounds; - double palmThreshold = 40; // 触摸面积阈值,可根据实际调整 - if (bounds.Width >= palmThreshold || bounds.Height >= palmThreshold) - { - // 记录当前编辑模式和高光状态 - palmEraserLastEditingMode = inkCanvas.EditingMode; - palmEraserLastIsHighlighter = drawingAttributes.IsHighlighter; - // 切换为橡皮擦 - EraserIcon_Click(null, null); - isPalmEraserActive = true; - } - } - //设备1个的时候,记录中心点 - if (dec.Count == 1) + // 修复:几何绘制模式下,只记录几何绘制的起点,不记录触摸轨迹 + if (dec.Count == 0) { var touchPoint = e.GetTouchPoint(inkCanvas); - centerPoint = touchPoint.Position; - - // 只允许在此处赋值iniP,防止TouchMove等其他地方覆盖,保证几何绘制起点一致 - if (drawingShapeMode != 0) + // 对于双曲线绘制,第一笔时记录起点,第二笔时不更新起点 + if (drawingShapeMode == 24 || drawingShapeMode == 25) { + // 双曲线绘制:第一笔记录起点,第二笔保持第一笔的起点 + if (drawMultiStepShapeCurrentStep == 0) + { + iniP = touchPoint.Position; + } + // 第二笔时不更新iniP,保持第一笔的起点 + } + else + { + // 其他图形正常记录起点 iniP = touchPoint.Position; } - - //记录第一根手指点击时的 StrokeCollection lastTouchDownStrokeCollection = inkCanvas.Strokes.Clone(); } + dec.Add(e.TouchDevice.Id); + return; + } + + // 非几何绘制模式下的正常触摸处理 + SetCursorBasedOnEditingMode(inkCanvas); + inkCanvas.CaptureTouch(e.TouchDevice); + ViewboxFloatingBar.IsHitTestVisible = false; + BlackboardUIGridForInkReplay.IsHitTestVisible = false; + dec.Add(e.TouchDevice.Id); + + // Palm Eraser 逻辑 + if (Settings.Canvas.EnablePalmEraser && dec.Count >= 2 && !isPalmEraserActive) + { + var bounds = e.GetTouchPoint(inkCanvas).Bounds; + double palmThreshold = 40; // 触摸面积阈值,可根据实际调整 + if (bounds.Width >= palmThreshold || bounds.Height >= palmThreshold) + { + // 记录当前编辑模式和高光状态 + palmEraserLastEditingMode = inkCanvas.EditingMode; + palmEraserLastIsHighlighter = drawingAttributes.IsHighlighter; + // 切换为橡皮擦 + EraserIcon_Click(null, null); + isPalmEraserActive = true; + } + } + + // 设备1个的时候,记录中心点 + if (dec.Count == 1) + { + var touchPoint = e.GetTouchPoint(inkCanvas); + centerPoint = touchPoint.Position; + + // 修复:只允许在此处赋值iniP,防止TouchMove等其他地方覆盖,保证几何绘制起点一致 + if (drawingShapeMode != 0) + { + // 对于双曲线绘制,第一笔时记录起点,第二笔时不更新起点 + if (drawingShapeMode == 24 || drawingShapeMode == 25) + { + // 双曲线绘制:第一笔记录起点,第二笔保持第一笔的起点 + if (drawMultiStepShapeCurrentStep == 0) + { + iniP = touchPoint.Position; + } + // 第二笔时不更新iniP,保持第一笔的起点 + } + else + { + // 其他图形正常记录起点 + iniP = touchPoint.Position; + } + } + + // 记录第一根手指点击时的 StrokeCollection + lastTouchDownStrokeCollection = inkCanvas.Strokes.Clone(); + } //设备两个及两个以上,将画笔功能关闭 if (dec.Count > 1 || isSingleFingerDragMode || !Settings.Gesture.IsEnableTwoFingerGesture) { @@ -447,20 +477,43 @@ namespace Ink_Canvas } isPalmEraserActive = false; } - // 新增:几何绘制模式下,触摸抬手时自动落笔 + // 修复:几何绘制模式下,触摸抬手时应该正确处理,而不是简单模拟鼠标事件 if (drawingShapeMode != 0) { - var mouseArgs = new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Left) + // 对于双曲线等需要多步绘制的图形,触摸抬手时应该进入下一步 + if (drawingShapeMode == 24 || drawingShapeMode == 25) { - RoutedEvent = MouseLeftButtonUpEvent, - Source = inkCanvas - }; - inkCanvas_MouseUp(inkCanvas, mouseArgs); + // 双曲线绘制:触摸抬手时进入下一步,但不自动触发鼠标抬起事件 + // 让用户继续绘制第二笔 + if (drawMultiStepShapeCurrentStep == 0) + { + // 第一笔完成,进入第二笔 + drawMultiStepShapeCurrentStep = 1; + } + else + { + // 第二笔完成,完成绘制 + var mouseArgs = new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Left) + { + RoutedEvent = MouseLeftButtonUpEvent, + Source = inkCanvas + }; + inkCanvas_MouseUp(inkCanvas, mouseArgs); + } + } + else + { + // 其他单步绘制的图形,触摸抬手时完成绘制 + var mouseArgs = new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Left) + { + RoutedEvent = MouseLeftButtonUpEvent, + Source = inkCanvas + }; + inkCanvas_MouseUp(inkCanvas, mouseArgs); + } } - //手势完成后切回之前的状态 - // 修复:改进多指手势恢复逻辑,确保从橡皮擦切换到笔时多指手势能正确恢复 - // 修复:几何绘制模式下不自动切换到Ink模式,避免触摸轨迹被收集 + // 手势完成后切回之前的状态 if (drawingShapeMode == 0) { if (dec.Count > 1)