首页 > 代码库 > 背水一战 Windows 10 (60) - 控件(媒体类): Pointer 涂鸦板, InkCanvas 涂鸦板

背水一战 Windows 10 (60) - 控件(媒体类): 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
[源码下载]

背水一战 Windows 10 (60) - 控件(媒体类): Pointer 涂鸦板, InkCanvas 涂鸦板