背水一戰 Windows 10 之 控制項(媒體類): 通過處理 Pointer 相關事件實現一個簡單的塗鴉板, InkCanvas 基礎知識 ...
背水一戰 Windows 10 (60) - 控制項(媒體類): Pointer 塗鴉板, InkCanvas 塗鴉板
作者:webabcd
介紹
背水一戰 Windows 10 之 控制項(媒體類)
- 通過處理 Pointer 相關事件實現一個簡單的塗鴉板
- InkCanvas 基礎知識
示例
1、演示如何通過 Pointer 相關事件的處理,來實現一個簡單的塗鴉板
Controls/MediaControl/InkSimple.xaml
<Page x:Class="Windows10.Controls.MediaControl.InkSimple" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:Windows10.Controls.MediaControl" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="Transparent"> <StackPanel Margin="10 0 10 10"> <Button Name="btnClear" Content="清除" Click="btnClear_Click" Margin="5" /> <Canvas Name="canvas" Background="Blue" Width="800" Height="480" HorizontalAlignment="Left" Margin="5" /> </StackPanel> </Grid> </Page>
Controls/MediaControl/InkSimple.xaml.cs
/* * 本例用於演示如何通過 Pointer 相關事件的處理,來實現一個簡單的塗鴉板 */ using System; using System.Collections.Generic; using Windows.Foundation; using Windows.UI; using Windows.UI.Input; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Shapes; namespace Windows10.Controls.MediaControl { public sealed partial class InkSimple : Page { // 用於保存觸摸點(PointerId - Point) private Dictionary<uint, Point?> _dicPoint; public InkSimple() { this.InitializeComponent(); canvas.PointerPressed += canvas_PointerPressed; canvas.PointerMoved += canvas_PointerMoved; canvas.PointerReleased += canvas_PointerReleased; canvas.PointerExited += canvas_PointerExited; _dicPoint = new Dictionary<uint, Point?>(); } void canvas_PointerPressed(object sender, PointerRoutedEventArgs e) { // 指針按下後,保存此觸摸點 PointerPoint pointerPoint = e.GetCurrentPoint(canvas); _dicPoint[pointerPoint.PointerId] = pointerPoint.Position; } void canvas_PointerMoved(object sender, PointerRoutedEventArgs e) { PointerPoint pointerPoint = e.GetCurrentPoint(canvas); if (_dicPoint.ContainsKey(pointerPoint.PointerId) && _dicPoint[pointerPoint.PointerId].HasValue) { Point currentPoint = pointerPoint.Position; Point previousPoint = _dicPoint[pointerPoint.PointerId].Value; // 如果指針移動過程中,兩個點間的距離超過 4 則在兩點間繪製一條直線,以完成塗鴉 if (ComputeDistance(currentPoint, previousPoint) > 4) { Line line = new Line() { X1 = previousPoint.X, Y1 = previousPoint.Y, X2 = currentPoint.X, Y2 = currentPoint.Y, StrokeThickness = 5, Stroke = new SolidColorBrush(Colors.Orange), StrokeEndLineCap = PenLineCap.Round }; _dicPoint[pointerPoint.PointerId] = currentPoint; canvas.Children.Add(line); } } } void canvas_PointerReleased(object sender, PointerRoutedEventArgs e) { // 指針釋放後,從字典中刪除此 PointerId 的數據 PointerPoint pointerPoint = e.GetCurrentPoint(canvas); if (_dicPoint.ContainsKey(pointerPoint.PointerId)) _dicPoint.Remove(pointerPoint.PointerId); } void canvas_PointerExited(object sender, PointerRoutedEventArgs e) { // 指針離開相當於指針釋放 canvas_PointerReleased(sender, e); } // 清除塗鴉 private void btnClear_Click(object sender, RoutedEventArgs e) { canvas.Children.Clear(); _dicPoint.Clear(); } // 計算兩個點(Point)之間的距離 private double ComputeDistance(Point point1, Point point2) { return Math.Sqrt(Math.Pow(point1.X - point2.X, 2) + Math.Pow(point1.Y - point2.Y, 2)); } } }
2、演示 InkCanvas 基礎知識
Controls/MediaControl/InkCanvasDemo1.xaml
<Page x:Class="Windows10.Controls.MediaControl.InkCanvasDemo1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:Windows10.Controls.MediaControl" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="Transparent"> <StackPanel Margin="10 0 10 10"> <Border Background="White" Width="480" Height="320" Margin="5" HorizontalAlignment="Left"> <!-- InkCanvas - 塗鴉板控制項 --> <InkCanvas Name="inkCanvas" /> </Border> <ComboBox Name="drawingColor" Header="Color" SelectedIndex="0" SelectionChanged="UpdateDefaultDrawingAttributes_Handler" Margin="5"> <x:String>Red</x:String> <x:String>Green</x:String> <x:String>Blue</x:String> </ComboBox> <Slider Name="drawingSize" Foreground="Orange" Background="Red" Style="{StaticResource MySliderStyle}" Header="Size" Minimum="1" Maximum="20" Value="5" ValueChanged="UpdateDefaultDrawingAttributes_Handler" Margin="5" /> <CheckBox Name="drawingDrawAsHighlighter" Content="DrawAsHighlighter" IsChecked="False" Checked="UpdateDefaultDrawingAttributes_Handler" Unchecked="UpdateDefaultDrawingAttributes_Handler" Margin="5" /> <CheckBox Name="drawingFitToCurve" Content="FitToCurve" IsChecked="True" Checked="UpdateDefaultDrawingAttributes_Handler" Unchecked="UpdateDefaultDrawingAttributes_Handler" Margin="5" /> <ToggleSwitch Name="drawingPenTip" Style="{StaticResource MyToggleSwitchStyle}" OnContent="PenTipShape.Circle" OffContent="PenTipShape.Rectangle" IsOn="True" Toggled="UpdateDefaultDrawingAttributes_Handler" Margin="5" /> <CheckBox Name="drawingPenTipTransform" Content="通過 PenTipTransform 轉換 PenTip 來實現筆尖形狀的自定義" IsChecked="False" Checked="UpdateDefaultDrawingAttributes_Handler" Unchecked="UpdateDefaultDrawingAttributes_Handler" Margin="5" /> <CheckBox Name="chkErasing" Content="將輸入指定為擦除模式" IsChecked="False" Checked="UpdateDefaultDrawingAttributes_Handler" Unchecked="UpdateDefaultDrawingAttributes_Handler" Margin="5" /> <CheckBox Name="chkIsInputEnabled" Content="IsInputEnabled" IsChecked="True" Checked="UpdateDefaultDrawingAttributes_Handler" Unchecked="UpdateDefaultDrawingAttributes_Handler" Margin="5" /> <Button Name="buttonClear" Content="全部清除" Click="buttonClear_Click" /> </StackPanel> </Grid> </Page>
Controls/MediaControl/InkCanvasDemo1.xaml.cs
/* * InkCanvas - 塗鴉板控制項(繼承自 FrameworkElement, 請參見 /Controls/BaseControl/FrameworkElementDemo/) * InkPresenter - 獲取 InkPresenter 對象 * * InkPresenter - 塗鴉板 * IsInputEnabled - 是否啟用塗鴉板 * InputDeviceTypes - 輸入設備的類型(None, Touch, Pen, Mouse) * InputProcessingConfiguration.Mode - 輸入模式(None, Inking, Erasing) * CopyDefaultDrawingAttributes() - 獲取 InkDrawingAttributes 對象 * UpdateDefaultDrawingAttributes(InkDrawingAttributes value) - 設置 InkDrawingAttributes 對象 * * InkDrawingAttributes - 塗鴉筆尖屬性 * IgnorePressure - 是否忽略觸摸壓力 * Color - 筆尖的顏色 * Size - 筆尖的尺寸(寬和高) * DrawAsHighlighter - 覆蓋之前的塗鴉時(false - 直接覆蓋;true - 高亮顯示覆蓋區域) * FitToCurve - 塗鴉時(true - 使用貝塞爾曲線生成塗鴉;false - 使用直線生成塗鴉) * PenTip - 筆尖的形狀(Circle, Rectangle) * PenTipTransform - 用於轉換 PenTip 的 Matrix3x2 仿射轉換矩陣(Matrix3x2 提供了一些簡便的方法:CreateRotation, CreateScale, CreateSkew, CreateTranslation 等)。通過它可以自定義筆尖的形狀 */ using System.Numerics; using Windows.Foundation; using Windows.UI; using Windows.UI.Core; using Windows.UI.Input.Inking; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; namespace Windows10.Controls.MediaControl { public sealed partial class InkCanvasDemo1 : Page { private InkPresenter _inkPresenter; public InkCanvasDemo1() { this.InitializeComponent(); _inkPresenter = inkCanvas.InkPresenter; _inkPresenter.InputDeviceTypes = CoreInputDeviceTypes.Mouse | CoreInputDeviceTypes.Pen | CoreInputDeviceTypes.Touch; UpdateDefaultDrawingAttributes(); } private void UpdateDefaultDrawingAttributes_Handler(object sender, RoutedEventArgs e) { UpdateDefaultDrawingAttributes(); } private void buttonClear_Click(object sender, RoutedEventArgs e) { _inkPresenter.StrokeContainer.Clear(); } private void UpdateDefaultDrawingAttributes() { if (_inkPresenter != null) { InkDrawingAttributes drawingAttributes = _inkPresenter.CopyDefaultDrawingAttributes(); drawingAttributes.IgnorePressure = true; switch (drawingColor.SelectedValue.ToString()) { case "Red": drawingAttributes.Color = Colors.Red; break; case "Green": drawingAttributes.Color = Colors.Green; break; case "Blue": drawingAttributes.Color = Colors.Blue; break; } drawingAttributes.Size = new Size(drawingSize.Value, drawingSize.Value); drawingAttributes.DrawAsHighlighter = drawingDrawAsHighlighter.IsChecked.Value; drawingAttributes.FitToCurve = drawingFitToCurve.IsChecked.Value; drawingAttributes.PenTip = drawingPenTip.IsOn ? PenTipShape.Circle : PenTipShape.Rectangle; if (drawingPenTipTransform.IsChecked == true) drawingAttributes.PenTipTransform = Matrix3x2.CreateSkew(4, 4); else drawingAttributes.PenTipTransform = Matrix3x2.Identity; _inkPresenter.UpdateDefaultDrawingAttributes(drawingAttributes); if (chkErasing.IsChecked == true) _inkPresenter.InputProcessingConfiguration.Mode = InkInputProcessingMode.Erasing; else _inkPresenter.InputProcessingConfiguration.Mode = InkInputProcessingMode.Inking; _inkPresenter.IsInputEnabled = chkIsInputEnabled.IsChecked.Value; } } } }
OK
[源碼下載]