您好,登錄后才能下訂單哦!
之前用PointLight做了一個(gè)番茄鐘,效果還不錯(cuò),具體可見這篇文章:
[UWP]使用PointLight并實(shí)現(xiàn)動(dòng)畫效果
后來(lái)試玩了Win2D,這次就用Win2D實(shí)現(xiàn)文字的鏤空效果,配合PointLight做一個(gè)內(nèi)斂不張揚(yáng)的番茄鐘。
實(shí)現(xiàn)鏤空文字的核心思想是使用CanvasGeometry.CreateText從TextLayout獲取一個(gè)Geometry,然后使用DrawGeometry將它畫到DrawingSurface。這篇文章介紹了具體的實(shí)現(xiàn)步驟。
Win2D Gallery提供了大量Win2D的Sample,這次就參考了其中的文字鏤空效果例子,地址和運(yùn)行效果如下:
https://github.com/microsoft/Win2D-Samples/blob/master/ExampleGallery/TextOutlines.xaml.cs
Sample的代碼量雖多,其實(shí)核心并不復(fù)雜,下面講講需要用到的API:
因?yàn)橐玫絎in2D,所以首先要引用Win2D.uwp nuget包。因?yàn)槲业哪繕?biāo)不是輸出到CanvasControl上,而是想要輸出到一個(gè)SpriteVisual上,所以使用CanvasDevice:
var canvasDevice = CanvasDevice.GetSharedDevice();
然后創(chuàng)建一個(gè)Compositor,并將這個(gè)Compositor和CanvasDevice關(guān)聯(lián)起來(lái),這里需要使用 CanvasComposition 創(chuàng)建 GraphicsDevice:
var compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;
var graphicsDevice = CanvasComposition.CreateCompositionGraphicsDevice(compositor, canvasDevice);
然后使用CompositionGraphicsDevice.CreateDrawingSurface創(chuàng)建一個(gè)CompositionDrawingSurface對(duì)象,它是用來(lái)繪畫內(nèi)容的表面:
var drawingSurface = graphicsDevice.CreateDrawingSurface(e.NewSize, DirectXPixelFormat.B8G8R8A8UIntNormalized, DirectXAlphaMode.Premultiplied);
使用Compositor.CreateSurfaceBrush創(chuàng)建一個(gè)CompositionSurfaceBrush
,它的作用是使用像素繪制SpriteVisual,簡(jiǎn)單來(lái)說它就是一張位圖,然后輸出到SpriteVisual上:
var maskSurfaceBrush = compositor.CreateSurfaceBrush(drawingSurface);
spriteTextVisual.Brush = maskSurfaceBrush;
有了CompositionDrawingSurface就可以為所欲為了,將這個(gè)DrawingSurface作為參數(shù),調(diào)用CanvasComposition.CreateDrawingSession創(chuàng)建DrawingSession,DrawingSession提供了多個(gè)函數(shù),可以自由地在DrawingSurface上畫文字、形狀、圖片甚至SVG。
using (var session = CanvasComposition.CreateDrawingSession(drawingSurface))
{
}
要再DrawingSurface上寫字,需要CanvasTextLayout,而CanvasTextLayout中的文字大小、格式等則由CanvasTextFormat定義:
using (var textFormat = new CanvasTextFormat()
{
FontSize = (float)FontSize,
Direction = CanvasTextDirection.LeftToRightThenTopToBottom,
VerticalAlignment = CanvasVerticalAlignment.Center,
HorizontalAlignment = CanvasHorizontalAlignment.Center,
})
{
using (var textLayout = new CanvasTextLayout(session, Text, textFormat, width, height))
{
Color fontColor = FontColor;
session.DrawTextLayout(textLayout, 0, 0, fontColor);
}
}
因?yàn)槲业哪繕?biāo)是鏤空的文字,所以不能直接使用DrawTextLayout。這里需要使用CanvasGeometry.CreateText從TextLayout獲取一個(gè)Geometry,然后使用DrawGeometry將它畫到DrawingSurface。CanvasStrokeStyle是可選的,它控制邊框的虛線。
using (var textGeometry = CanvasGeometry.CreateText(textLayout))
{
var dashedStroke = new CanvasStrokeStyle()
{
DashStyle = DashStyle
};
session.DrawGeometry(textGeometry, OutlineColor, (float)StrokeWidth, dashedStroke);
}
將上面的代碼總結(jié)一下,封裝為一個(gè)OutlineTextControl 控件,它提供了Text、OutlineColor、FontColor等屬性,在控件SizeChanged時(shí),或者各個(gè)屬性改變時(shí)調(diào)用DrawText
重新在CompositionDrawingSurface上繪制文字。代碼大致如下:
public class OutlineTextControl : Control
{
private CompositionDrawingSurface _drawingSurface;
public OutlineTextControl()
{
var compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;
var graphicsDevice = CanvasComposition.CreateCompositionGraphicsDevice(compositor, CanvasDevice.GetSharedDevice());
var spriteTextVisual = compositor.CreateSpriteVisual();
ElementCompositionPreview.SetElementChildVisual(this, spriteTextVisual);
SizeChanged += (s, e) =>
{
_drawingSurface = graphicsDevice.CreateDrawingSurface(e.NewSize, DirectXPixelFormat.B8G8R8A8UIntNormalized, DirectXAlphaMode.Premultiplied);
DrawText();
var maskSurfaceBrush = compositor.CreateSurfaceBrush(_drawingSurface);
spriteTextVisual.Brush = maskSurfaceBrush;
spriteTextVisual.Size = e.NewSize.ToVector2();
};
RegisterPropertyChangedCallback(FontSizeProperty, new DependencyPropertyChangedCallback((s, e) =>
{
DrawText();
}));
}
private void DrawText()
{
if (ActualHeight == 0 || ActualWidth == 0 || string.IsNullOrWhiteSpace(Text) || _drawingSurface == null)
return;
var width = (float)ActualWidth;
var height = (float)ActualHeight;
using (var session = CanvasComposition.CreateDrawingSession(_drawingSurface))
{
session.Clear(Colors.Transparent);
using (var textFormat = new CanvasTextFormat()
{
FontSize = (float)FontSize,
Direction = CanvasTextDirection.LeftToRightThenTopToBottom,
VerticalAlignment = CanvasVerticalAlignment.Center,
HorizontalAlignment = CanvasHorizontalAlignment.Center,
})
{
using (var textLayout = new CanvasTextLayout(session, Text, textFormat, width, height))
{
if (ShowNonOutlineText)
{
session.DrawTextLayout(textLayout, 0, 0, FontColor);
}
using (var textGeometry = CanvasGeometry.CreateText(textLayout))
{
var dashedStroke = new CanvasStrokeStyle()
{
DashStyle = DashStyle
};
session.DrawGeometry(textGeometry, OutlineColor, (float)StrokeWidth, dashedStroke);
}
}
}
}
}
//SOME CODE AND PROPERTIES
}
文章開頭的那個(gè)番茄鐘源碼可以在這里查看:
OnePomodoro_OutlineTextView.xaml at master
也可以安裝我的番茄鐘應(yīng)用試玩一下,安裝地址:
一個(gè)番茄鐘
CanvasComposition Class
CanvasDrawingSession Class
CanvasGeometry Class
CompositionGraphicsDevice Class (Windows.UI.Composition) - Windows UWP applications _ Microsoft Docs
CompositionDrawingSurface Class (Windows.UI.Composition) - Windows UWP applications _ Microsoft Docs
CompositionGraphicsDevice Class (Windows.UI.Composition) - Windows UWP applications _ Microsoft Docs
CompositionSurfaceBrush Class (Windows.UI.Composition) - Windows UWP applications _ Microsoft Docs
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。