add:实时笔锋及墨迹预测
This commit is contained in:
@@ -4,12 +4,11 @@ using System.Windows.Controls;
|
||||
using System.Windows.Ink;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace Ink_Canvas
|
||||
{
|
||||
/// <summary>
|
||||
/// 墨迹预测(书写中速度外推预览线)与笔锋相关输入状态,思路参考智绘教 Inkeys 的 RTS 速度与低延迟手感。
|
||||
/// 墨迹预测:书写过程中根据速度与选项外推一小段预览线,减轻感知延迟。
|
||||
/// </summary>
|
||||
public partial class MainWindow
|
||||
{
|
||||
@@ -21,12 +20,21 @@ namespace Ink_Canvas
|
||||
private double _inkPredictionVx;
|
||||
private double _inkPredictionVy;
|
||||
|
||||
private void ResetInkPredictionState()
|
||||
private void SyncInkStrokePredictionLeadComboVisibility()
|
||||
{
|
||||
_inkPredictionStrokeActive = false;
|
||||
_inkPredictionHasSample = false;
|
||||
_inkPredictionHasVelocity = false;
|
||||
ClearInkPredictionOverlay();
|
||||
try
|
||||
{
|
||||
bool on = Settings?.Canvas != null && Settings.Canvas.EnableInkStrokePrediction;
|
||||
var v = on ? Visibility.Visible : Visibility.Collapsed;
|
||||
if (ComboBoxInkStrokePredictionLead != null)
|
||||
ComboBoxInkStrokePredictionLead.Visibility = v;
|
||||
if (BoardComboBoxInkStrokePredictionLead != null)
|
||||
BoardComboBoxInkStrokePredictionLead.Visibility = v;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
private void ClearInkPredictionOverlay()
|
||||
@@ -75,6 +83,30 @@ namespace Ink_Canvas
|
||||
ClearInkPredictionOverlay();
|
||||
}
|
||||
|
||||
private double GetInkPredictionLeadMs()
|
||||
{
|
||||
int mode = Settings?.Canvas?.InkStrokePredictionLeadMode ?? 0;
|
||||
if (mode == 1) return 25.0;
|
||||
if (mode == 2) return 50.0;
|
||||
|
||||
double speed = Math.Sqrt(_inkPredictionVx * _inkPredictionVx + _inkPredictionVy * _inkPredictionVy);
|
||||
double norm = Math.Min(1.0, speed / 2600.0);
|
||||
double lead = 16.0 + norm * 34.0;
|
||||
return Math.Max(14.0, Math.Min(52.0, lead));
|
||||
}
|
||||
|
||||
private double GetInkPredictionMaxDistance(double leadMs)
|
||||
{
|
||||
double baseD = Math.Max(4.0, Settings?.Canvas?.InkStrokePredictionMaxDistance ?? 18.0);
|
||||
int mode = Settings?.Canvas?.InkStrokePredictionLeadMode ?? 0;
|
||||
if (mode != 0)
|
||||
return Math.Max(6.0, Math.Min(42.0, baseD * (leadMs / 24.0)));
|
||||
|
||||
double speed = Math.Sqrt(_inkPredictionVx * _inkPredictionVx + _inkPredictionVy * _inkPredictionVy);
|
||||
double norm = Math.Min(1.0, speed / 2200.0);
|
||||
return Math.Max(6.0, Math.Min(48.0, baseD + norm * baseD * 0.9));
|
||||
}
|
||||
|
||||
private void inkCanvas_PreviewStylusMove(object sender, StylusEventArgs e)
|
||||
{
|
||||
try
|
||||
@@ -155,11 +187,11 @@ namespace Ink_Canvas
|
||||
_inkPredictionVy = velocitySmooth * _inkPredictionVy + (1.0 - velocitySmooth) * vy;
|
||||
}
|
||||
|
||||
const double leadMs = 24.0;
|
||||
double leadMs = GetInkPredictionLeadMs();
|
||||
double predX = pos.X + _inkPredictionVx * (leadMs / 1000.0);
|
||||
double predY = pos.Y + _inkPredictionVy * (leadMs / 1000.0);
|
||||
|
||||
double maxDist = Math.Max(4.0, Settings.Canvas.InkStrokePredictionMaxDistance);
|
||||
double maxDist = GetInkPredictionMaxDistance(leadMs);
|
||||
double dx = predX - pos.X;
|
||||
double dy = predY - pos.Y;
|
||||
double len = Math.Sqrt(dx * dx + dy * dy);
|
||||
|
||||
@@ -2700,21 +2700,40 @@ namespace Ink_Canvas
|
||||
SaveSettingsToFile();
|
||||
}
|
||||
|
||||
private void ToggleSwitchEnableInkStrokePrediction_Toggled(object sender, RoutedEventArgs e)
|
||||
private void ToggleSwitchInkStrokePredictionPanel_Toggled(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!isLoaded) return;
|
||||
|
||||
Settings.Canvas.EnableInkStrokePrediction = ToggleSwitchEnableInkStrokePrediction.IsOn;
|
||||
if (!Settings.Canvas.EnableInkStrokePrediction)
|
||||
bool on = ReferenceEquals(sender, BoardToggleSwitchInkStrokePredictionPanel)
|
||||
? BoardToggleSwitchInkStrokePredictionPanel.IsOn
|
||||
: ToggleSwitchInkStrokePredictionPanel.IsOn;
|
||||
|
||||
if (ReferenceEquals(sender, ToggleSwitchInkStrokePredictionPanel) && BoardToggleSwitchInkStrokePredictionPanel != null)
|
||||
BoardToggleSwitchInkStrokePredictionPanel.IsOn = on;
|
||||
else if (ReferenceEquals(sender, BoardToggleSwitchInkStrokePredictionPanel) && ToggleSwitchInkStrokePredictionPanel != null)
|
||||
ToggleSwitchInkStrokePredictionPanel.IsOn = on;
|
||||
|
||||
Settings.Canvas.EnableInkStrokePrediction = on;
|
||||
SyncInkStrokePredictionLeadComboVisibility();
|
||||
if (!on)
|
||||
EndInkPredictionStroke();
|
||||
SaveSettingsToFile();
|
||||
}
|
||||
|
||||
private void ToggleSwitchEnableVelocityBrushTip_Toggled(object sender, RoutedEventArgs e)
|
||||
private void ComboBoxInkStrokePredictionLead_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (!isLoaded) return;
|
||||
var cb = sender as ComboBox;
|
||||
if (cb?.SelectedIndex < 0) return;
|
||||
|
||||
int idx = cb.SelectedIndex;
|
||||
Settings.Canvas.InkStrokePredictionLeadMode = idx;
|
||||
|
||||
if (ReferenceEquals(cb, ComboBoxInkStrokePredictionLead) && BoardComboBoxInkStrokePredictionLead != null)
|
||||
BoardComboBoxInkStrokePredictionLead.SelectedIndex = idx;
|
||||
else if (ReferenceEquals(cb, BoardComboBoxInkStrokePredictionLead) && ComboBoxInkStrokePredictionLead != null)
|
||||
ComboBoxInkStrokePredictionLead.SelectedIndex = idx;
|
||||
|
||||
Settings.Canvas.EnableVelocityBrushTip = ToggleSwitchEnableVelocityBrushTip.IsOn;
|
||||
SaveSettingsToFile();
|
||||
}
|
||||
|
||||
|
||||
@@ -824,6 +824,15 @@ namespace Ink_Canvas
|
||||
ToggleSwitchDisablePressure.IsOn = Settings.Canvas.DisablePressure;
|
||||
inkCanvas.DefaultDrawingAttributes.IgnorePressure = Settings.Canvas.DisablePressure;
|
||||
|
||||
if (Settings.Canvas.EnableVelocityBrushTip)
|
||||
{
|
||||
Settings.Canvas.InkStyle = 3;
|
||||
Settings.Canvas.EnableVelocityBrushTip = false;
|
||||
}
|
||||
|
||||
if (Settings.Canvas.InkStyle < 0 || Settings.Canvas.InkStyle > 3)
|
||||
Settings.Canvas.InkStyle = 0;
|
||||
|
||||
ComboBoxPenStyle.SelectedIndex = Settings.Canvas.InkStyle;
|
||||
BoardComboBoxPenStyle.SelectedIndex = Settings.Canvas.InkStyle;
|
||||
|
||||
@@ -942,10 +951,19 @@ namespace Ink_Canvas
|
||||
ToggleSwitchLineEndpointSnapping.IsOn = Settings.Canvas.LineEndpointSnapping;
|
||||
ToggleSwitchCompressPicturesUploaded.IsOn = Settings.Canvas.IsCompressPicturesUploaded;
|
||||
|
||||
if (ToggleSwitchEnableInkStrokePrediction != null)
|
||||
ToggleSwitchEnableInkStrokePrediction.IsOn = Settings.Canvas.EnableInkStrokePrediction;
|
||||
if (ToggleSwitchEnableVelocityBrushTip != null)
|
||||
ToggleSwitchEnableVelocityBrushTip.IsOn = Settings.Canvas.EnableVelocityBrushTip;
|
||||
int leadMode = Settings.Canvas.InkStrokePredictionLeadMode;
|
||||
if (leadMode < 0 || leadMode > 2) leadMode = 0;
|
||||
Settings.Canvas.InkStrokePredictionLeadMode = leadMode;
|
||||
|
||||
if (ToggleSwitchInkStrokePredictionPanel != null)
|
||||
ToggleSwitchInkStrokePredictionPanel.IsOn = Settings.Canvas.EnableInkStrokePrediction;
|
||||
if (BoardToggleSwitchInkStrokePredictionPanel != null)
|
||||
BoardToggleSwitchInkStrokePredictionPanel.IsOn = Settings.Canvas.EnableInkStrokePrediction;
|
||||
if (ComboBoxInkStrokePredictionLead != null)
|
||||
ComboBoxInkStrokePredictionLead.SelectedIndex = leadMode;
|
||||
if (BoardComboBoxInkStrokePredictionLead != null)
|
||||
BoardComboBoxInkStrokePredictionLead.SelectedIndex = leadMode;
|
||||
SyncInkStrokePredictionLeadComboVisibility();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -315,7 +315,7 @@ namespace Ink_Canvas
|
||||
}
|
||||
}
|
||||
|
||||
if (Settings.Canvas.EnableVelocityBrushTip
|
||||
if (Settings.Canvas.InkStyle == 3
|
||||
&& !touchPressureSimulationApplied
|
||||
&& !Settings.Canvas.DisablePressure
|
||||
&& penType != 1
|
||||
@@ -825,6 +825,8 @@ namespace Ink_Canvas
|
||||
}
|
||||
catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); }
|
||||
|
||||
break;
|
||||
case 3:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user