add:实时笔锋及墨迹预测

This commit is contained in:
2026-03-28 17:04:50 +08:00
parent d325a58f17
commit de3f5d16a2
8 changed files with 161 additions and 55 deletions
+54 -18
View File
@@ -836,22 +836,6 @@
Toggled="ToggleSwitchDisablePressure_Toggled" /> Toggled="ToggleSwitchDisablePressure_Toggled" />
</ikw:SimpleStackPanel> </ikw:SimpleStackPanel>
<TextBlock Text="{i18n:I18n Key=Canvas_DisablePressureHint}" TextWrapping="Wrap" Foreground="#a1a1aa" /> <TextBlock Text="{i18n:I18n Key=Canvas_DisablePressureHint}" TextWrapping="Wrap" Foreground="#a1a1aa" />
<ikw:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<TextBlock Foreground="#fafafa" Text="{i18n:I18n Key=Canvas_InkStrokePrediction}" VerticalAlignment="Center"
FontSize="14" Margin="0,0,16,0" />
<ui:ToggleSwitch OnContent="" OffContent="" Name="ToggleSwitchEnableInkStrokePrediction"
IsOn="True" FontFamily="Microsoft YaHei UI" FontWeight="Bold"
Toggled="ToggleSwitchEnableInkStrokePrediction_Toggled" />
</ikw:SimpleStackPanel>
<TextBlock Text="{i18n:I18n Key=Canvas_InkStrokePredictionHint}" TextWrapping="Wrap" Foreground="#a1a1aa" />
<ikw:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<TextBlock Foreground="#fafafa" Text="{i18n:I18n Key=Canvas_VelocityBrushTip}" VerticalAlignment="Center"
FontSize="14" Margin="0,0,16,0" />
<ui:ToggleSwitch OnContent="" OffContent="" Name="ToggleSwitchEnableVelocityBrushTip"
IsOn="True" FontFamily="Microsoft YaHei UI" FontWeight="Bold"
Toggled="ToggleSwitchEnableVelocityBrushTip_Toggled" />
</ikw:SimpleStackPanel>
<TextBlock Text="{i18n:I18n Key=Canvas_VelocityBrushTipHint}" TextWrapping="Wrap" Foreground="#a1a1aa" />
<ikw:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left"> <ikw:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<TextBlock Foreground="#fafafa" Text="{i18n:I18n Key=Canvas_EraserSize}" VerticalAlignment="Center" <TextBlock Foreground="#fafafa" Text="{i18n:I18n Key=Canvas_EraserSize}" VerticalAlignment="Center"
@@ -5641,6 +5625,8 @@
FontFamily="Microsoft YaHei UI" /> FontFamily="Microsoft YaHei UI" />
<ComboBoxItem Content="关闭笔锋" <ComboBoxItem Content="关闭笔锋"
FontFamily="Microsoft YaHei UI" /> FontFamily="Microsoft YaHei UI" />
<ComboBoxItem Content="实时"
FontFamily="Microsoft YaHei UI" />
</ComboBox> </ComboBox>
</ikw:SimpleStackPanel> </ikw:SimpleStackPanel>
<Controls:UniformGrid Columns="3" Width="300" <Controls:UniformGrid Columns="3" Width="300"
@@ -5688,7 +5674,31 @@
IsOn="False" /> IsOn="False" />
</ikw:SimpleStackPanel> </ikw:SimpleStackPanel>
</Controls:UniformGrid> </Controls:UniformGrid>
<ikw:SimpleStackPanel Orientation="Horizontal"
Margin="0,10,0,0" VerticalAlignment="Center">
<Label Content="墨迹预测" FontSize="12"
VerticalAlignment="Center"
Foreground="{DynamicResource FloatBarForeground}"
Margin="0,0,10,0" />
<ui:ToggleSwitch
x:Name="BoardToggleSwitchInkStrokePredictionPanel"
MinWidth="0" Width="80"
FontFamily="Microsoft YaHei UI"
Toggled="ToggleSwitchInkStrokePredictionPanel_Toggled" />
<ComboBox x:Name="BoardComboBoxInkStrokePredictionLead"
Width="130" Height="30" Margin="12,0,0,0"
FontFamily="Microsoft YaHei UI"
VerticalAlignment="Center"
Visibility="Collapsed"
SelectionChanged="ComboBoxInkStrokePredictionLead_SelectionChanged">
<ComboBoxItem Content="自动"
FontFamily="Microsoft YaHei UI" />
<ComboBoxItem Content="25ms"
FontFamily="Microsoft YaHei UI" />
<ComboBoxItem Content="50ms"
FontFamily="Microsoft YaHei UI" />
</ComboBox>
</ikw:SimpleStackPanel>
<StackPanel Orientation="Horizontal" Height="30"> <StackPanel Orientation="Horizontal" Height="30">
<Label Margin="0,0,10,0" Content="粗细" <Label Margin="0,0,10,0" Content="粗细"
@@ -8689,6 +8699,8 @@
FontFamily="Microsoft YaHei UI" /> FontFamily="Microsoft YaHei UI" />
<ComboBoxItem Content="关闭笔锋" <ComboBoxItem Content="关闭笔锋"
FontFamily="Microsoft YaHei UI" /> FontFamily="Microsoft YaHei UI" />
<ComboBoxItem Content="实时"
FontFamily="Microsoft YaHei UI" />
</ComboBox> </ComboBox>
</ikw:SimpleStackPanel> </ikw:SimpleStackPanel>
<Controls:UniformGrid Columns="3" Width="300" Height="55"> <Controls:UniformGrid Columns="3" Width="300" Height="55">
@@ -8731,7 +8743,31 @@
IsOn="{Binding ElementName=ToggleSwitchInkFadeInPanel, Path=IsOn}" /> IsOn="{Binding ElementName=ToggleSwitchInkFadeInPanel, Path=IsOn}" />
</ikw:SimpleStackPanel> </ikw:SimpleStackPanel>
</Controls:UniformGrid> </Controls:UniformGrid>
<ikw:SimpleStackPanel Orientation="Horizontal"
Margin="0,10,0,0" VerticalAlignment="Center">
<Label Content="墨迹预测" FontSize="12"
VerticalAlignment="Center"
Foreground="{DynamicResource FloatBarForeground}"
Margin="0,0,10,0" />
<ui:ToggleSwitch
x:Name="ToggleSwitchInkStrokePredictionPanel"
MinWidth="0" Width="80"
FontFamily="Microsoft YaHei UI"
Toggled="ToggleSwitchInkStrokePredictionPanel_Toggled" />
<ComboBox x:Name="ComboBoxInkStrokePredictionLead"
Width="130" Height="30" Margin="12,0,0,0"
FontFamily="Microsoft YaHei UI"
VerticalAlignment="Center"
Visibility="Collapsed"
SelectionChanged="ComboBoxInkStrokePredictionLead_SelectionChanged">
<ComboBoxItem Content="自动"
FontFamily="Microsoft YaHei UI" />
<ComboBoxItem Content="25ms"
FontFamily="Microsoft YaHei UI" />
<ComboBoxItem Content="50ms"
FontFamily="Microsoft YaHei UI" />
</ComboBox>
</ikw:SimpleStackPanel>
<StackPanel Orientation="Horizontal" Height="30"> <StackPanel Orientation="Horizontal" Height="30">
<Label Margin="0,0,10,0" Content="粗细" FontWeight="Bold" <Label Margin="0,0,10,0" Content="粗细" FontWeight="Bold"
+41 -9
View File
@@ -4,12 +4,11 @@ using System.Windows.Controls;
using System.Windows.Ink; using System.Windows.Ink;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Shapes;
namespace Ink_Canvas namespace Ink_Canvas
{ {
/// <summary> /// <summary>
/// 墨迹预测书写中速度外推预览线)与笔锋相关输入状态,思路参考智绘教 Inkeys 的 RTS 速度与低延迟手感 /// 墨迹预测书写过程中根据速度与选项外推一小段预览线,减轻感知延迟
/// </summary> /// </summary>
public partial class MainWindow public partial class MainWindow
{ {
@@ -21,12 +20,21 @@ namespace Ink_Canvas
private double _inkPredictionVx; private double _inkPredictionVx;
private double _inkPredictionVy; private double _inkPredictionVy;
private void ResetInkPredictionState() private void SyncInkStrokePredictionLeadComboVisibility()
{ {
_inkPredictionStrokeActive = false; try
_inkPredictionHasSample = false; {
_inkPredictionHasVelocity = false; bool on = Settings?.Canvas != null && Settings.Canvas.EnableInkStrokePrediction;
ClearInkPredictionOverlay(); var v = on ? Visibility.Visible : Visibility.Collapsed;
if (ComboBoxInkStrokePredictionLead != null)
ComboBoxInkStrokePredictionLead.Visibility = v;
if (BoardComboBoxInkStrokePredictionLead != null)
BoardComboBoxInkStrokePredictionLead.Visibility = v;
}
catch
{
// ignore
}
} }
private void ClearInkPredictionOverlay() private void ClearInkPredictionOverlay()
@@ -75,6 +83,30 @@ namespace Ink_Canvas
ClearInkPredictionOverlay(); 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) private void inkCanvas_PreviewStylusMove(object sender, StylusEventArgs e)
{ {
try try
@@ -155,11 +187,11 @@ namespace Ink_Canvas
_inkPredictionVy = velocitySmooth * _inkPredictionVy + (1.0 - velocitySmooth) * vy; _inkPredictionVy = velocitySmooth * _inkPredictionVy + (1.0 - velocitySmooth) * vy;
} }
const double leadMs = 24.0; double leadMs = GetInkPredictionLeadMs();
double predX = pos.X + _inkPredictionVx * (leadMs / 1000.0); double predX = pos.X + _inkPredictionVx * (leadMs / 1000.0);
double predY = pos.Y + _inkPredictionVy * (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 dx = predX - pos.X;
double dy = predY - pos.Y; double dy = predY - pos.Y;
double len = Math.Sqrt(dx * dx + dy * dy); double len = Math.Sqrt(dx * dx + dy * dy);
+24 -5
View File
@@ -2700,21 +2700,40 @@ namespace Ink_Canvas
SaveSettingsToFile(); SaveSettingsToFile();
} }
private void ToggleSwitchEnableInkStrokePrediction_Toggled(object sender, RoutedEventArgs e) private void ToggleSwitchInkStrokePredictionPanel_Toggled(object sender, RoutedEventArgs e)
{ {
if (!isLoaded) return; if (!isLoaded) return;
Settings.Canvas.EnableInkStrokePrediction = ToggleSwitchEnableInkStrokePrediction.IsOn; bool on = ReferenceEquals(sender, BoardToggleSwitchInkStrokePredictionPanel)
if (!Settings.Canvas.EnableInkStrokePrediction) ? 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(); EndInkPredictionStroke();
SaveSettingsToFile(); SaveSettingsToFile();
} }
private void ToggleSwitchEnableVelocityBrushTip_Toggled(object sender, RoutedEventArgs e) private void ComboBoxInkStrokePredictionLead_SelectionChanged(object sender, SelectionChangedEventArgs e)
{ {
if (!isLoaded) return; 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(); SaveSettingsToFile();
} }
+22 -4
View File
@@ -824,6 +824,15 @@ namespace Ink_Canvas
ToggleSwitchDisablePressure.IsOn = Settings.Canvas.DisablePressure; ToggleSwitchDisablePressure.IsOn = Settings.Canvas.DisablePressure;
inkCanvas.DefaultDrawingAttributes.IgnorePressure = 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; ComboBoxPenStyle.SelectedIndex = Settings.Canvas.InkStyle;
BoardComboBoxPenStyle.SelectedIndex = Settings.Canvas.InkStyle; BoardComboBoxPenStyle.SelectedIndex = Settings.Canvas.InkStyle;
@@ -942,10 +951,19 @@ namespace Ink_Canvas
ToggleSwitchLineEndpointSnapping.IsOn = Settings.Canvas.LineEndpointSnapping; ToggleSwitchLineEndpointSnapping.IsOn = Settings.Canvas.LineEndpointSnapping;
ToggleSwitchCompressPicturesUploaded.IsOn = Settings.Canvas.IsCompressPicturesUploaded; ToggleSwitchCompressPicturesUploaded.IsOn = Settings.Canvas.IsCompressPicturesUploaded;
if (ToggleSwitchEnableInkStrokePrediction != null) int leadMode = Settings.Canvas.InkStrokePredictionLeadMode;
ToggleSwitchEnableInkStrokePrediction.IsOn = Settings.Canvas.EnableInkStrokePrediction; if (leadMode < 0 || leadMode > 2) leadMode = 0;
if (ToggleSwitchEnableVelocityBrushTip != null) Settings.Canvas.InkStrokePredictionLeadMode = leadMode;
ToggleSwitchEnableVelocityBrushTip.IsOn = Settings.Canvas.EnableVelocityBrushTip;
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 else
{ {
@@ -315,7 +315,7 @@ namespace Ink_Canvas
} }
} }
if (Settings.Canvas.EnableVelocityBrushTip if (Settings.Canvas.InkStyle == 3
&& !touchPressureSimulationApplied && !touchPressureSimulationApplied
&& !Settings.Canvas.DisablePressure && !Settings.Canvas.DisablePressure
&& penType != 1 && penType != 1
@@ -825,6 +825,8 @@ namespace Ink_Canvas
} }
catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); }
break;
case 3:
break; break;
} }
} }
-4
View File
@@ -374,10 +374,6 @@
<data name="Canvas_EnablePressureTouchHint" xml:space="preserve"><value># When on, touch screens that support pressure will show pressure; for devices not recognized by the system.</value></data> <data name="Canvas_EnablePressureTouchHint" xml:space="preserve"><value># When on, touch screens that support pressure will show pressure; for devices not recognized by the system.</value></data>
<data name="Canvas_DisablePressure" xml:space="preserve"><value>Ignore pressure</value></data> <data name="Canvas_DisablePressure" xml:space="preserve"><value>Ignore pressure</value></data>
<data name="Canvas_DisablePressureHint" xml:space="preserve"><value># When on, all strokes use uniform thickness; mutually exclusive with pressure-sensitive touch.</value></data> <data name="Canvas_DisablePressureHint" xml:space="preserve"><value># When on, all strokes use uniform thickness; mutually exclusive with pressure-sensitive touch.</value></data>
<data name="Canvas_InkStrokePrediction" xml:space="preserve"><value>Ink stroke prediction (latency hint)</value></data>
<data name="Canvas_InkStrokePredictionHint" xml:space="preserve"><value># While inking, draws a short semi-transparent segment ahead along motion to reduce perceived latency (similar idea to Inkeys).</value></data>
<data name="Canvas_VelocityBrushTip" xml:space="preserve"><value>Velocity brush tip (pressure blend)</value></data>
<data name="Canvas_VelocityBrushTipHint" xml:space="preserve"><value># For pen pressure, blends speed with hardware pressure: faster strokes thinner, slower thicker. Touch simulated pressure is unchanged.</value></data>
<data name="Canvas_EraserSize" xml:space="preserve"><value>Eraser size</value></data> <data name="Canvas_EraserSize" xml:space="preserve"><value>Eraser size</value></data>
<data name="Canvas_EraserSize_VerySmall" xml:space="preserve"><value>Very small</value></data> <data name="Canvas_EraserSize_VerySmall" xml:space="preserve"><value>Very small</value></data>
<data name="Canvas_EraserSize_Small" xml:space="preserve"><value>Small</value></data> <data name="Canvas_EraserSize_Small" xml:space="preserve"><value>Small</value></data>
-4
View File
@@ -389,10 +389,6 @@
<data name="Canvas_EnablePressureTouchHint" xml:space="preserve"><value># 开启后,触屏设备也将支持压感效果,适用于部分支持压感但无法被系统识别的触屏设备。</value></data> <data name="Canvas_EnablePressureTouchHint" xml:space="preserve"><value># 开启后,触屏设备也将支持压感效果,适用于部分支持压感但无法被系统识别的触屏设备。</value></data>
<data name="Canvas_DisablePressure" xml:space="preserve"><value>屏蔽压感</value></data> <data name="Canvas_DisablePressure" xml:space="preserve"><value>屏蔽压感</value></data>
<data name="Canvas_DisablePressureHint" xml:space="preserve"><value># 开启后,将忽略所有设备的压感信息,使所有笔画具有统一的粗细。与压感触屏模式互斥。</value></data> <data name="Canvas_DisablePressureHint" xml:space="preserve"><value># 开启后,将忽略所有设备的压感信息,使所有笔画具有统一的粗细。与压感触屏模式互斥。</value></data>
<data name="Canvas_InkStrokePrediction" xml:space="preserve"><value>墨迹预测(低延迟预览线)</value></data>
<data name="Canvas_InkStrokePredictionHint" xml:space="preserve"><value># 书写时沿运动方向外推一小段半透明预览线,减轻显示与采样延迟;思路类似智绘教 Inkeys 的流畅笔迹。</value></data>
<data name="Canvas_VelocityBrushTip" xml:space="preserve"><value>速度笔锋(压感混合)</value></data>
<data name="Canvas_VelocityBrushTipHint" xml:space="preserve"><value># 对触控笔等真实压感,按运笔速度与硬件压感混合:快画略细、慢画略粗;触屏模拟压感路径仍单独处理,避免重复叠加。</value></data>
<data name="Canvas_EraserSize" xml:space="preserve"><value>橡皮大小</value></data> <data name="Canvas_EraserSize" xml:space="preserve"><value>橡皮大小</value></data>
<data name="Canvas_EraserSize_VerySmall" xml:space="preserve"><value>很小</value></data> <data name="Canvas_EraserSize_VerySmall" xml:space="preserve"><value>很小</value></data>
<data name="Canvas_EraserSize_Small" xml:space="preserve"><value>较小</value></data> <data name="Canvas_EraserSize_Small" xml:space="preserve"><value>较小</value></data>
+17 -10
View File
@@ -69,6 +69,7 @@ namespace Ink_Canvas
public double InkAlpha { get; set; } = 255; public double InkAlpha { get; set; } = 255;
[JsonProperty("isShowCursor")] [JsonProperty("isShowCursor")]
public bool IsShowCursor { get; set; } public bool IsShowCursor { get; set; }
/// <summary>笔锋:0 基于点集,1 基于速率,2 关闭,3 实时(速度与压感混合)。</summary>
[JsonProperty("inkStyle")] [JsonProperty("inkStyle")]
public int InkStyle { get; set; } public int InkStyle { get; set; }
[JsonProperty("eraserSize")] [JsonProperty("eraserSize")]
@@ -147,29 +148,35 @@ namespace Ink_Canvas
public int EraserAutoSwitchBackDelaySeconds { get; set; } = 10; // 默认10秒 public int EraserAutoSwitchBackDelaySeconds { get; set; } = 10; // 默认10秒
/// <summary> /// <summary>
/// 书写时根据速度外推一小段预览线,补偿显示/采样延迟(类似智绘教 Inkeys 的低延迟手感)。 /// 是否在笔工具中启用墨迹预测预览线(由笔属性面板「墨迹预测」开关控制)。
/// </summary> /// </summary>
[JsonProperty("enableInkStrokePrediction")] [JsonProperty("enableInkStrokePrediction")]
public bool EnableInkStrokePrediction { get; set; } = true; public bool EnableInkStrokePrediction { get; set; } = false;
/// <summary> /// <summary>
/// 预测线段最大长度(与设备无关的逻辑像素/DIP),过大易飘,过小不明显 /// 墨迹预测提前量模式:0 自动(随书写速度调整),1 固定 25ms,2 固定 50ms
/// </summary>
[JsonProperty("inkStrokePredictionLeadMode")]
public int InkStrokePredictionLeadMode { get; set; } = 0;
/// <summary>
/// 预测线段基准最大长度(逻辑像素/DIP);「自动」模式下会随速度在此值基础上略增。
/// </summary> /// </summary>
[JsonProperty("inkStrokePredictionMaxDistance")] [JsonProperty("inkStrokePredictionMaxDistance")]
public double InkStrokePredictionMaxDistance { get; set; } = 18.0; public double InkStrokePredictionMaxDistance { get; set; } = 18.0;
/// <summary> /// <summary>
/// 用笔等真实压感设备时,将速度与硬件压感按 <see cref="VelocityBrushTipMix"/> 混合,使快画偏细、慢画偏粗(参考 Inkeys RTSSpeed 思路) /// 「实时」笔锋(<see cref="InkStyle"/> = 3)下,速度项与硬件压感的混合比例 0–1
/// </summary>
[JsonProperty("enableVelocityBrushTip")]
public bool EnableVelocityBrushTip { get; set; } = true;
/// <summary>
/// 速度笔锋混合比例 0–1,越大速度对粗细影响越明显。
/// </summary> /// </summary>
[JsonProperty("velocityBrushTipMix")] [JsonProperty("velocityBrushTipMix")]
public double VelocityBrushTipMix { get; set; } = 0.22; public double VelocityBrushTipMix { get; set; } = 0.22;
/// <summary>
/// 已弃用:请使用 <see cref="InkStyle"/> = 3(笔锋下拉选「实时」)。仅用于反序列化旧版配置。
/// </summary>
[JsonProperty("enableVelocityBrushTip")]
public bool EnableVelocityBrushTip { get; set; }
} }
public enum OptionalOperation public enum OptionalOperation