Windows Community Toolkit 3.0 - InfiniteCanvas

來源:互聯網
上載者:User

標籤:http   can   not   官方   mic   建立   god   point   nes   

概述

InfiniteCanvas 是一個 Canvas 控制項,它支援無限畫布的滾動,支援 Ink,文本,格式文本,畫布縮放操作,撤銷重做操作,匯入和匯出資料。

這是一個非常實用的控制項,在“來畫視頻” UWP app的繪畫功能中,也用到了這個控制項,它對不同畫筆的選擇,橡皮擦,直尺和圓形尺,文字輸入和字型選擇等都提供了很便捷的支援,而且支援匯入和匯出資料,可以很方便的創作繪畫作品,並能匯出和分享給別人。 

下面是 Windows Community Toolkit Sample App 的樣本和 code/doc 地址:

Windows Community Toolkit Doc - InfiniteCanvas

Windows Community Toolkit Source Code - InfiniteCanvas

Namespace: Microsoft.Toolkit.Uwp.UI.Controls; Nuget: Microsoft.Toolkit.Uwp.UI.Controls;

 

開發過程

代碼結構分析

首先來看 InfiniteCanvas 的代碼結構,組成如下:

  • Commands - InfiniteCanvas 對應的所有命令,包括 redo/undo,Ink,Text 等,如上面樣本圖中 Toolbar 上所示;
  • Controls - InfiniteCanvas 的主要控制項都在這個檔案夾裡;
  • Drawables - Text 和 Ink 主要的繪製功能在這個檔案夾裡;
  • JsonConverters - 序列化和還原序列化的主要功能,以及自訂的 Ink 屬性等;
  • InfiniteCanvas.Events.cs - InfiniteCanvas 的主要事件處理邏輯;
  • InfiniteCanvas.TextBox.cs - InfiniteCanvas 添加文字的文字框控制項處理邏輯;
  • InfiniteCanvas.cs - InfiniteCanvas 控制項的主要處理邏輯;
  • InfiniteCanvas.xaml - InfiniteCanvas 控制項的 XAML 樣式檔案;

 

InfiniteCanvas 整體類結構很清晰,每個類的功能也很明確,下面我們選取幾個重要的類來做分析。

1.  InfiniteCanvasCreateInkCommand

Command 檔案夾的每一個類都比較簡單,我們找一個建立 Ink 命令看一下;該類實現了 IInfiniteCanvasCommand 這個介面,實現了 Execute() 和 Undo() 兩個方法;Command 初始化也很簡單,建立一個 InkDrawable 對象,初始化 drawableList 對象,執行建立時加入該 drawable,撤銷時把它從 drawableList 中去掉。  

internal class InfiniteCanvasCreateInkCommand : IInfiniteCanvasCommand{    private readonly List<IDrawable> _drawableList;    private readonly InkDrawable _drawable;    public InfiniteCanvasCreateInkCommand(List<IDrawable> drawableList, IReadOnlyList<InkStroke> strokes)    {        _drawable = new InkDrawable(strokes);        _drawableList = drawableList;    }    public void Execute()    {        _drawableList.Add(_drawable);    }    public void Undo()    {        _drawableList.Remove(_drawable);    }}

2. InfiniteCanvasTextBox

用於 InfiniteCanvas 的文字框控制項,從的結構中可以看到完整的文字框屬性定義方法,包括設定文字,設定編輯地區尺寸,文字變化的處理,游標位置的限制等。

來看一下判斷游標能夠下移一行的 CannotGoDown() 方法,按照分行符號來切割文字行,如果只有一行則不可下移;當前選擇的結束,在最後一行時,也不可下移,其他情況都可以下移;

internal bool CannotGoDown(){    var lines = _editZone.Text.Split(‘\r‘);    if (lines.Count() == 1)    {        return true;    }    var lastLine = lines.ElementAt(lines.Length - 1);    if ((_editZone.Text.Length - lastLine.Length) <= (_editZone.SelectionStart + _editZone.SelectionLength))    {        return true;    }    return false;}

3. InfiniteCanvasVirtualDrawingSurface

用於渲染 Ink 和 Text 的虛擬 drawing surface,它有幾個部分類組成:

主要的處理邏輯,是利用 Commands 來操作 Ink 和 Text 的渲染執行和撤銷操作,計算渲染的尺寸空間,組織渲染的內容。

4. InkDrawable 和 TextDrawable

Ink 和 Text 可繪畫元素的繪畫邏輯,分別來看一下兩個類的組成:

 

我們看一下兩個類的 Draw 方法:

Draw() - InkDrawable:

獲得 Strokes 中每個線條的每個點,加入到集合中,從點集合建立線條,最後產生新的 Stroke 列表;遍曆完成後,把新的 Stroke 列表用於 drawingSession 的 DrawInk 方法來實現繪製; 

public void Draw(CanvasDrawingSession drawingSession, Rect sessionBounds){    var finalStrokeList = new List<InkStroke>(Strokes.Count);    foreach (var stroke in Strokes)    {        var points = stroke.GetInkPoints();        var finalPointList = new List<InkPoint>(points.Count);        foreach (var point in points)        {            finalPointList.Add(MapPointToToSessionBounds(point, sessionBounds));        }        StrokeBuilder.SetDefaultDrawingAttributes(stroke.DrawingAttributes);        var newStroke = StrokeBuilder.CreateStrokeFromInkPoints(finalPointList, stroke.PointTransform);        finalStrokeList.Add(newStroke);    }    drawingSession.DrawInk(finalStrokeList);}

Draw() - TextDrawble:

設定 Canvas 中文本的格式,使用文本和格式設定的 textLayout 來用於 drawingSession 的 DrawTextLayout 方法實現繪製;根據字型大小設定橫向位移 HorizontalMarginBasedOnFont,固定的縱向位移 verticalMargin;

public void Draw(CanvasDrawingSession drawingSession, Rect sessionBounds){    const int verticalMargin = 3;    CanvasTextFormat format = new CanvasTextFormat    {        FontSize = FontSize,        WordWrapping = CanvasWordWrapping.NoWrap,        FontWeight = IsBold ? FontWeights.Bold : FontWeights.Normal,        FontStyle = IsItalic ? FontStyle.Italic : FontStyle.Normal    };    CanvasTextLayout textLayout = new CanvasTextLayout(drawingSession, Text, format, 0.0f, 0.0f);    drawingSession.DrawTextLayout(textLayout, (float)(Bounds.X - sessionBounds.X + HorizontalMarginBasedOnFont), (float)(Bounds.Y - sessionBounds.Y + verticalMargin), TextColor);} 

5. InfiniteCanvas

InfiniteCanvas 是主要邏輯處理,由 InfiniteCanvas.cs,InfiniteCanvas.Events.cs,InfiniteCanvas.TextBox.cs 三個部分類組成。

  • 其中 InfiniteCanvas.cs 這個類中主要是實現 OnApplyTemplate(),DependencyProperty 處理,控制項的定義,事件註冊,Canvas 的基礎事件處理等,InfiniteCanvas 中實現了一個 InkCanvas 所以可以實現各種筆觸的筆跡繪製;
  • InfiniteCanvas.Events.cs 主要是 Canvas 中的各種按鈕點擊等事件處理;
  • InfiniteCanvas.TextBox.cs 主要是 Canvas 中 TextBox 控制項對應的控制項定義和事件處理;

 

調用樣本

InfiniteCanvas 控制項的調用非常簡單,下面看看 XAML 中的調用:

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"      xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"      mc:Ignorable="d">  <Grid>    <controls:InfiniteCanvas Name="canvas" IsToolbarVisible="True"/>  </Grid></Page>

 

總結

到這裡我們就把 Windows Community Toolkit 3.0 中的 InfiniteCanvas 的原始碼實現過程講解完成了,希望能對大家更好的理解和使用這個功能有所協助。InfiniteCanvas 控制項在繪畫類情境中有非常多的應用,控制項預設實現了多種筆觸的繪畫,橡皮,文字,redo undo 等重要功能,開發人員也可以根據 InfiniteCanvas 的實現自訂 Toolbar 的樣式和更多的繪畫筆觸,不同的筆畫儲存方式等。

最後,再跟大家安利一下 WindowsCommunityToolkit 的官方微博:https://weibo.com/u/6506046490, 大家可以通過微博關注最新動向。

衷心感謝 WindowsCommunityToolkit 的作者們傑出的工作,感謝每一位貢獻者,Thank you so much, ALL WindowsCommunityToolkit AUTHORS !!!

Windows Community Toolkit 3.0 - InfiniteCanvas

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.