[update] IccInkCanvas 实时笔锋优化
This commit is contained in:
parent
ab24d8240e
commit
856762f555
@ -10,11 +10,23 @@
|
||||
<Grid>
|
||||
<StackPanel Orientation="Vertical" Margin="8">
|
||||
<TextBlock FontSize="24">IccInkCanvasDemo</TextBlock>
|
||||
<iccInkCanvas:IccBoard Name="IccBoard" Width="512" Height="512"/>
|
||||
<iccInkCanvas:IccBoard EditingMode="None" Name="IccBoard" Width="512" Height="512"/>
|
||||
<WrapPanel Orientation="Horizontal">
|
||||
<Button Content="EditingMode = None" Click="EditingModeChangeToNone_ButtonClick"/>
|
||||
<Button Content="EditingMode = Writing" Click="EditingModeChangeToWriting_ButtonClick"/>
|
||||
</WrapPanel>
|
||||
<TextBlock Name="BoardSettingsTextBlock"/>
|
||||
<WrapPanel Orientation="Horizontal">
|
||||
<Button Content="BoardSettings.NibSize = 2" Click="BoardSettingsNibSizeChangeTo2_ButtonClick"/>
|
||||
<Button Content="BoardSettings.NibSize = 4" Click="BoardSettingsNibSizeChangeTo4_ButtonClick"/>
|
||||
<Button Content="BoardSettings.NibSize = 6" Click="BoardSettingsNibSizeChangeTo6_ButtonClick"/>
|
||||
<Button Content="BoardSettings.NibColor = Red" Click="BoardSettingsNibColorChangeToRed_ButtonClick"/>
|
||||
<Button Content="BoardSettings.NibColor = Blue" Click="BoardSettingsNibColorChangeToBlue_ButtonClick"/>
|
||||
<Button Content="BoardSettings.NibColor = Green" Click="BoardSettingsNibColorChangeToGreen_ButtonClick"/>
|
||||
<Button Content="BoardSettings.NibColor = Black" Click="BoardSettingsNibColorChangeToBlack_ButtonClick"/>
|
||||
<Button Content="BoardSettings.StrokeNibStyle = Solid" Click="BoardSettingsStrokeNibStyleChangeToSolid_ButtonClick"/>
|
||||
<Button Content="BoardSettings.StrokeNibStyle = Beautiful" Click="BoardSettingsStrokeNibStyleChangeToBeautiful_ButtonClick"/>
|
||||
</WrapPanel>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
@ -22,13 +22,56 @@ namespace InkCanvasForClass.IccInkCanvas.Demo {
|
||||
public partial class MainWindow : Window {
|
||||
public MainWindow() {
|
||||
InitializeComponent();
|
||||
RegisterEventsForBoardSettings();
|
||||
UpdateBoardSettingsTextBlock();
|
||||
}
|
||||
|
||||
private void UpdateBoardSettingsTextBlock() {
|
||||
BoardSettingsTextBlock.Text =
|
||||
$@"Width:{IccBoard.BoardSettings.NibWidth} Height:{IccBoard.BoardSettings.NibHeight} Color:{IccBoard.BoardSettings.NibColor.ToString()}";
|
||||
}
|
||||
|
||||
private void RegisterEventsForBoardSettings() {
|
||||
IccBoard.BoardSettings.NibWidthChanged += (s, e) => UpdateBoardSettingsTextBlock();
|
||||
IccBoard.BoardSettings.NibHeightChanged += (s, e) => UpdateBoardSettingsTextBlock();
|
||||
IccBoard.BoardSettings.NibColorChanged += (s, e) => UpdateBoardSettingsTextBlock();
|
||||
}
|
||||
|
||||
private void EditingModeChangeToNone_ButtonClick(object sender, RoutedEventArgs e) {
|
||||
IccBoard.EditingMode = EditingMode.None;
|
||||
IccBoard.EditingMode = EditingMode.NoneWithHitTest;
|
||||
}
|
||||
private void EditingModeChangeToWriting_ButtonClick(object sender, RoutedEventArgs e) {
|
||||
IccBoard.EditingMode = EditingMode.Writing;
|
||||
}
|
||||
private void BoardSettingsNibSizeChangeTo2_ButtonClick(object sender, RoutedEventArgs e) {
|
||||
IccBoard.BoardSettings.NibWidth = 2;
|
||||
IccBoard.BoardSettings.NibHeight = 2;
|
||||
}
|
||||
private void BoardSettingsNibSizeChangeTo4_ButtonClick(object sender, RoutedEventArgs e) {
|
||||
IccBoard.BoardSettings.NibWidth = 4;
|
||||
IccBoard.BoardSettings.NibHeight = 4;
|
||||
}
|
||||
private void BoardSettingsNibSizeChangeTo6_ButtonClick(object sender, RoutedEventArgs e) {
|
||||
IccBoard.BoardSettings.NibWidth = 6;
|
||||
IccBoard.BoardSettings.NibHeight = 6;
|
||||
}
|
||||
private void BoardSettingsNibColorChangeToRed_ButtonClick(object sender, RoutedEventArgs e) {
|
||||
IccBoard.BoardSettings.NibColor = Color.FromRgb(220, 38, 38);
|
||||
}
|
||||
private void BoardSettingsNibColorChangeToBlue_ButtonClick(object sender, RoutedEventArgs e) {
|
||||
IccBoard.BoardSettings.NibColor = Color.FromRgb(37, 99, 235);
|
||||
}
|
||||
private void BoardSettingsNibColorChangeToGreen_ButtonClick(object sender, RoutedEventArgs e) {
|
||||
IccBoard.BoardSettings.NibColor = Color.FromRgb(34, 197, 94);
|
||||
}
|
||||
private void BoardSettingsNibColorChangeToBlack_ButtonClick(object sender, RoutedEventArgs e) {
|
||||
IccBoard.BoardSettings.NibColor = Colors.Black;
|
||||
}
|
||||
private void BoardSettingsStrokeNibStyleChangeToSolid_ButtonClick(object sender, RoutedEventArgs e) {
|
||||
IccBoard.BoardSettings.StrokeNibStyle = StrokeNibStyle.Solid;
|
||||
}
|
||||
private void BoardSettingsStrokeNibStyleChangeToBeautiful_ButtonClick(object sender, RoutedEventArgs e) {
|
||||
IccBoard.BoardSettings.StrokeNibStyle = StrokeNibStyle.Beautiful;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -96,6 +96,16 @@ namespace InkCanvasForClass.IccInkCanvas {
|
||||
|
||||
#endregion
|
||||
|
||||
#region BoardSettings
|
||||
|
||||
private void RegisterEventsForBoardSettings() {
|
||||
BoardSettings.NibWidthChanged += (s,e)=>InkCanvas.DefaultDrawingAttributes.Width = BoardSettings.NibWidth;
|
||||
BoardSettings.NibHeightChanged += (s,e)=>InkCanvas.DefaultDrawingAttributes.Height = BoardSettings.NibHeight;
|
||||
BoardSettings.NibColorChanged += (s,e)=>InkCanvas.DefaultDrawingAttributes.Color = BoardSettings.NibColor;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public IccBoard() {
|
||||
InitializeComponent();
|
||||
}
|
||||
@ -123,6 +133,9 @@ namespace InkCanvasForClass.IccInkCanvas {
|
||||
ic.DefaultDrawingAttributes.Color = BoardSettings.NibColor;
|
||||
|
||||
ic.BoardSettings = BoardSettings;
|
||||
|
||||
// BoardSettings 事件注册
|
||||
RegisterEventsForBoardSettings();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,12 +17,21 @@ using InkCanvasForClass.IccInkCanvas.Settings;
|
||||
namespace InkCanvasForClass.IccInkCanvas {
|
||||
class CustomDynamicRenderer : DynamicRenderer {
|
||||
|
||||
private class StylusProcessedCallbackData {
|
||||
public int StylusDeviceID;
|
||||
public int TabletDeviceID;
|
||||
}
|
||||
|
||||
private Point prevPoint;
|
||||
|
||||
private IccInkCanvas _inkCanvas;
|
||||
|
||||
private List<StylusPoint> pointsList = new List<StylusPoint>();
|
||||
|
||||
private StylusProcessedCallbackData _stylusProcessedCallbackData;
|
||||
|
||||
public InputtingDeviceType InputType = InputtingDeviceType.None;
|
||||
|
||||
private void ClearPointsList() {
|
||||
pointsList.Clear();
|
||||
}
|
||||
@ -41,14 +50,38 @@ namespace InkCanvasForClass.IccInkCanvas {
|
||||
protected override void OnStylusDown(RawStylusInput rawStylusInput) {
|
||||
prevPoint = new Point(double.NegativeInfinity, double.NegativeInfinity);
|
||||
ClearPointsList();
|
||||
|
||||
// 判断当前设备类型
|
||||
var styDevice = rawStylusInput.StylusDeviceId;
|
||||
var tabletDevice = rawStylusInput.TabletDeviceId;
|
||||
|
||||
var pts = rawStylusInput.GetStylusPoints();
|
||||
if (pts.Count == 1) {
|
||||
PushPoint(pts.Single());
|
||||
} else if (pts.Count > 1) {
|
||||
PushPoint(pts[pts.Count-1]);
|
||||
}
|
||||
Trace.WriteLine(pointsList.Count);
|
||||
|
||||
base.OnStylusDown(rawStylusInput);
|
||||
|
||||
_stylusProcessedCallbackData = new StylusProcessedCallbackData() {
|
||||
StylusDeviceID = styDevice,
|
||||
TabletDeviceID = tabletDevice,
|
||||
};
|
||||
}
|
||||
|
||||
protected override void OnStylusDownProcessed(object callbackData, bool targetVerified) {
|
||||
var data = _stylusProcessedCallbackData;
|
||||
var tabletDevices = Tablet.TabletDevices;
|
||||
if (data.StylusDeviceID == 0 && data.TabletDeviceID == 0) InputType = InputtingDeviceType.Mouse;
|
||||
foreach (TabletDevice tabletDevice in tabletDevices) {
|
||||
if (tabletDevice.Id == data.TabletDeviceID && tabletDevice.Type == TabletDeviceType.Stylus)
|
||||
InputType = InputtingDeviceType.Stylus;
|
||||
if (tabletDevice.Id == data.TabletDeviceID && tabletDevice.Type == TabletDeviceType.Touch)
|
||||
InputType = InputtingDeviceType.Touch;
|
||||
}
|
||||
|
||||
base.OnStylusDownProcessed(callbackData, targetVerified);
|
||||
}
|
||||
|
||||
protected override void OnStylusMove(RawStylusInput rawStylusInput) {
|
||||
@ -57,15 +90,17 @@ namespace InkCanvasForClass.IccInkCanvas {
|
||||
if (pts.Count == 1) {
|
||||
PushPoint(pts.Single());
|
||||
} else if (pts.Count > 1) {
|
||||
PushPoint(pts[pts.Count-1]);
|
||||
if (InputType != InputtingDeviceType.Stylus) PushPoint(pts[pts.Count-1]);
|
||||
}
|
||||
Trace.WriteLine(pointsList.Count);
|
||||
}
|
||||
|
||||
protected override void OnDraw(DrawingContext drawingContext,
|
||||
StylusPointCollection stylusPoints,
|
||||
Geometry geometry, Brush fillBrush) {
|
||||
if (_inkCanvas.BoardSettings.StrokeNibStyle == StrokeNibStyle.Beautiful) {
|
||||
protected override void OnStylusUpProcessed(object callbackData, bool targetVerified) {
|
||||
//InputType = InputtingDeviceType.None;
|
||||
// TODO: 触摸支持
|
||||
base.OnStylusUpProcessed(callbackData, targetVerified);
|
||||
}
|
||||
|
||||
private void DrawBeautifulNibStroke(DrawingContext drawingContext) {
|
||||
try {
|
||||
var sp = new StylusPointCollection();
|
||||
var n = pointsList.Count - 1;
|
||||
@ -107,6 +142,55 @@ namespace InkCanvasForClass.IccInkCanvas {
|
||||
var stk = new Stroke(sp, da);
|
||||
stk.Draw(drawingContext);
|
||||
} catch {}
|
||||
}
|
||||
|
||||
private void DrawSolidNibStroke(DrawingContext drawingContext) {
|
||||
try {
|
||||
var sp = new StylusPointCollection();
|
||||
foreach (var pt in pointsList) {
|
||||
var point = new StylusPoint();
|
||||
point.PressureFactor = (float)0.5;
|
||||
point.X = pt.X;
|
||||
point.Y = pt.Y;
|
||||
sp.Add(point);
|
||||
}
|
||||
var da = DrawingAttributes.Clone();
|
||||
da.Width -= 0.5;
|
||||
da.Height -= 0.5;
|
||||
var stk = new Stroke(sp, da);
|
||||
stk.Draw(drawingContext);
|
||||
}
|
||||
catch {}
|
||||
}
|
||||
|
||||
private void DrawSolidNibStrokeForStylus(StylusPointCollection stylusPoints, DrawingContext drawingContext) {
|
||||
try {
|
||||
var sp = new StylusPointCollection();
|
||||
foreach (var pt in stylusPoints) {
|
||||
var point = new StylusPoint();
|
||||
point.PressureFactor = (float)0.5;
|
||||
point.X = pt.X;
|
||||
point.Y = pt.Y;
|
||||
sp.Add(point);
|
||||
}
|
||||
var da = DrawingAttributes.Clone();
|
||||
var stk = new Stroke(sp, da);
|
||||
stk.Draw(drawingContext);
|
||||
}
|
||||
catch {}
|
||||
}
|
||||
|
||||
protected override void OnDraw(DrawingContext drawingContext,
|
||||
StylusPointCollection stylusPoints,
|
||||
Geometry geometry, Brush fillBrush) {
|
||||
if (_inkCanvas.BoardSettings.StrokeNibStyle == StrokeNibStyle.Beautiful && InputType != InputtingDeviceType.Stylus) {
|
||||
DrawBeautifulNibStroke(drawingContext);
|
||||
} else if (_inkCanvas.BoardSettings.StrokeNibStyle == StrokeNibStyle.Solid && InputType != InputtingDeviceType.Stylus) {
|
||||
DrawSolidNibStroke(drawingContext);
|
||||
} else if (_inkCanvas.BoardSettings.StrokeNibStyle == StrokeNibStyle.Solid && InputType == InputtingDeviceType.Stylus) {
|
||||
DrawSolidNibStrokeForStylus(stylusPoints, drawingContext);
|
||||
} else if (_inkCanvas.BoardSettings.StrokeNibStyle == StrokeNibStyle.Default) {
|
||||
base.OnDraw(drawingContext, stylusPoints, geometry, fillBrush);
|
||||
} else {
|
||||
base.OnDraw(drawingContext, stylusPoints, geometry, fillBrush);
|
||||
}
|
||||
@ -160,7 +244,7 @@ namespace InkCanvasForClass.IccInkCanvas {
|
||||
this.Strokes.Add(customStroke);
|
||||
}
|
||||
|
||||
if (BoardSettings.StrokeNibStyle == StrokeNibStyle.Beautiful) {
|
||||
if (BoardSettings.StrokeNibStyle == StrokeNibStyle.Beautiful && customDynamicRenderer.InputType != InputtingDeviceType.Stylus) {
|
||||
try {
|
||||
var stylusPoints = new StylusPointCollection();
|
||||
var n = customStroke.StylusPoints.Count - 1;
|
||||
@ -199,6 +283,18 @@ namespace InkCanvasForClass.IccInkCanvas {
|
||||
|
||||
customStroke.StylusPoints = stylusPoints;
|
||||
} catch { }
|
||||
} else if (BoardSettings.StrokeNibStyle == StrokeNibStyle.Solid) {
|
||||
try {
|
||||
var sp = new StylusPointCollection();
|
||||
foreach (var pt in customStroke.StylusPoints) {
|
||||
var point = new StylusPoint();
|
||||
point.PressureFactor = (float)0.5;
|
||||
point.X = pt.X;
|
||||
point.Y = pt.Y;
|
||||
sp.Add(point);
|
||||
}
|
||||
customStroke.StylusPoints = sp;
|
||||
} catch { }
|
||||
}
|
||||
|
||||
InkCanvasStrokeCollectedEventArgs args =
|
||||
@ -207,5 +303,7 @@ namespace InkCanvasForClass.IccInkCanvas {
|
||||
}
|
||||
|
||||
public event EventHandler<RoutedEventArgs> DeleteKeyCommandFired;
|
||||
|
||||
public InputtingDeviceType InputtingDeviceType { get; private set; }
|
||||
}
|
||||
}
|
||||
|
@ -9,34 +9,103 @@ namespace InkCanvasForClass.IccInkCanvas.Settings {
|
||||
public class BoardSettings {
|
||||
public BoardSettings() {}
|
||||
|
||||
private double _NibWidth { get; set; } = 4.00;
|
||||
|
||||
/// <summary>
|
||||
/// 笔尖长度
|
||||
/// </summary>
|
||||
public double NibWidth { get; set; } = 4.00;
|
||||
public double NibWidth {
|
||||
get => _NibWidth;
|
||||
set {
|
||||
if (Math.Abs(_NibWidth - value) < 0.0001) return;
|
||||
_NibWidth = value;
|
||||
NibWidthChanged?.Invoke(this,EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
private double _NibHeight { get; set; } = 4.00;
|
||||
|
||||
/// <summary>
|
||||
/// 笔尖高度
|
||||
/// </summary>
|
||||
public double NibHeight { get; set; } = 4.00;
|
||||
|
||||
/// <summary>
|
||||
/// 笔尖大小,适合笔尖类型为普通笔时使用
|
||||
/// </summary>
|
||||
public double NibSize {
|
||||
get => (NibWidth + NibHeight) / 2;
|
||||
set => NibWidth = NibHeight = value;
|
||||
public double NibHeight {
|
||||
get => _NibWidth;
|
||||
set {
|
||||
if (Math.Abs(_NibHeight - value) < 0.0001) return;
|
||||
_NibHeight = value;
|
||||
NibHeightChanged?.Invoke(this,EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
public NibType NibType { get; set; } = NibType.Default;
|
||||
private NibType _NibType { get; set; } = NibType.Default;
|
||||
|
||||
public NibType NibType {
|
||||
get => _NibType;
|
||||
set {
|
||||
if (_NibType == value) return;
|
||||
_NibType = value;
|
||||
NibTypeChanged?.Invoke(this,EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
private Color _NibColor { get; set; } = Colors.Black;
|
||||
|
||||
/// <summary>
|
||||
/// 笔尖颜色
|
||||
/// </summary>
|
||||
public Color NibColor { get; set; } = Colors.Black;
|
||||
public Color NibColor {
|
||||
get => _NibColor;
|
||||
set {
|
||||
if (_NibColor.Equals(value)) return;
|
||||
_NibColor = value;
|
||||
NibColorChanged?.Invoke(this,EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
private StrokeNibStyle _StrokeNibStyle { get; set; } = StrokeNibStyle.Beautiful;
|
||||
|
||||
/// <summary>
|
||||
/// 笔锋样式类型,默认有笔锋
|
||||
/// </summary>
|
||||
public StrokeNibStyle StrokeNibStyle { get; set; } = StrokeNibStyle.Beautiful;
|
||||
public StrokeNibStyle StrokeNibStyle {
|
||||
get => _StrokeNibStyle;
|
||||
set {
|
||||
if (_StrokeNibStyle == value) return;
|
||||
_StrokeNibStyle = value;
|
||||
StrokeNibStyleChanged?.Invoke(this,EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
private bool _IsForceIgnoreStylusPressure { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 强制忽略支持压力传感的输入设备返回的真实压力值(比如支持压感的手写笔)
|
||||
/// </summary>
|
||||
public bool IsForceIgnoreStylusPressure {
|
||||
get => _IsForceIgnoreStylusPressure;
|
||||
set {
|
||||
if (_IsForceIgnoreStylusPressure == value) return;
|
||||
_IsForceIgnoreStylusPressure = value;
|
||||
IsForceIgnoreStylusPressureChanged?.Invoke(this,EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
#region Events
|
||||
|
||||
public event EventHandler<EventArgs> NibWidthChanged;
|
||||
public event EventHandler<EventArgs> NibHeightChanged;
|
||||
public event EventHandler<EventArgs> NibColorChanged;
|
||||
public event EventHandler<EventArgs> NibTypeChanged;
|
||||
public event EventHandler<EventArgs> StrokeNibStyleChanged;
|
||||
public event EventHandler<EventArgs> IsForceIgnoreStylusPressureChanged;
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public enum InputtingDeviceType {
|
||||
None,
|
||||
Mouse,
|
||||
Touch,
|
||||
Stylus
|
||||
}
|
||||
}
|
||||
|
@ -25,11 +25,15 @@ namespace InkCanvasForClass.IccInkCanvas.Settings {
|
||||
/// </summary>
|
||||
public enum StrokeNibStyle {
|
||||
/// <summary>
|
||||
/// 无笔锋
|
||||
/// 默认,直接根据输入设备提供的压力值正常渲染
|
||||
/// </summary>
|
||||
Default,
|
||||
/// <summary>
|
||||
/// 强制无笔锋
|
||||
/// </summary>
|
||||
Solid,
|
||||
/// <summary>
|
||||
/// 有笔锋,基于固定点集算法计算
|
||||
/// 有笔锋,基于固定点集算法计算,触笔设备不套用算法
|
||||
/// </summary>
|
||||
Beautiful
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user