UWP Composition 是否有非 Win2D 文本解决方案 API
Is There a Non-Win2D Text Solution for UWP Composition API
为了避免 XY 问题,首先是 Y:有没有办法在不需要 Win2D 的 SpriteVisual 上创建文本?
现在 X:我要解决的问题是我需要 SpriteVisual(而不是 TextBlock)上的文本来应用透视旋转 3D 表达式动画。 SpriteVisual 上的文本可以使用 Win2D 完成。这是 Microsoft sample code:
的一部分
using (var ds = CanvasComposition.CreateDrawingSession(_drawingSurface))
{
ds.Clear(Colors.Transparent);
var rect = new Rect(new Point(2, 2), (_drawingSurface.Size.ToVector2() - new Vector2(4, 4)).ToSize());
ds.FillRoundedRectangle(rect, 15, 15, Colors.LightBlue);
ds.DrawRoundedRectangle(rect, 15, 15, Colors.Gray, 2);
ds.DrawText("This is a composition drawing surface", rect, Colors.Black, new CanvasTextFormat()
{
FontFamily = "Comic Sans MS",
FontSize = 32,
WordWrapping = CanvasWordWrapping.WholeWord,
VerticalAlignment = CanvasVerticalAlignment.Center,
HorizontalAlignment = CanvasHorizontalAlignment.Center
}
);
_drawingBrush.Surface = _drawingSurface;
_drawingVisual = _compositor.CreateSpriteVisual();
_drawingVisual.Brush = _drawingBrush;
要为其中的文本着色需要 Win2D ICanvasBrush。但我想在 Expression Animation 中为颜色设置动画,因此我需要来自 CompositionBrush 的文本颜色。现在我可以创建一个 CompositionMaskBrush,其中文本画笔作为遮罩,CompositionBrush 作为源。但是对于 CompositionMaskBrush,我无法为其添加额外的遮罩或任何其他合成效果,这对我来说是个问题。
是否有我不熟悉的 Insider Build 中的替代方法或增强组合 API?
Y-answer:不能,您只能使用 Win2d CanvasDrawingSession
在 CompositionDrawingSurface
上绘制文本。但是您可以使用 ElementCompositionPreview.GetElementVisual(yourTextBlock)
从 XAML TextBlock
获得 Visual
并使用 Composition API 表达式 + XAML 颜色故事板对其进行动画处理。
X-answer:您可以从文本 CompositionDrawingSurface
创建一个 alpha 蒙版并将其应用于 CompositionColorBrush
:
private void CreateColoredText(string text)
{
var compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;
var graphicsDevice = CanvasComposition.CreateCompositionGraphicsDevice(compositor, CanvasDevice.GetSharedDevice());
var spriteTextVisual = compositor.CreateSpriteVisual();
spriteTextVisual.Size = new Vector2(512, 512);
var maskDrawingSurface = graphicsDevice.CreateDrawingSurface(new Size(512, 512), DirectXPixelFormat.B8G8R8A8UIntNormalized, DirectXAlphaMode.Premultiplied);
using (var ds = CanvasComposition.CreateDrawingSession(maskDrawingSurface))
{
ds.Clear(Colors.Transparent);
ds.DrawText(text, new Rect(0, 0, 512, 512), Colors.Lime, new CanvasTextFormat
{
FontSize = 32,
FontWeight = FontWeights.Bold,
VerticalAlignment = CanvasVerticalAlignment.Center,
HorizontalAlignment = CanvasHorizontalAlignment.Center,
LineSpacing = 32
});
}
var maskSurfaceBrush = compositor.CreateSurfaceBrush(maskDrawingSurface);
var surfaceTextBrush = compositor.CreateColorBrush(Colors.DeepPink);
var maskBrush = compositor.CreateMaskBrush();
maskBrush.Mask = maskSurfaceBrush;
maskBrush.Source = surfaceTextBrush;
var colorAnimation = compositor.CreateColorKeyFrameAnimation();
colorAnimation.InsertKeyFrame(0.5f, Colors.DeepSkyBlue);
colorAnimation.InsertKeyFrame(1, Colors.DeepPink);
colorAnimation.Duration = TimeSpan.FromMilliseconds(1500);
colorAnimation.IterationBehavior = AnimationIterationBehavior.Forever;
surfaceTextBrush.StartAnimation("Color", colorAnimation);
spriteTextVisual.Brush = maskBrush;
ElementCompositionPreview.SetElementChildVisual(Grid, spriteTextVisual);
}
现在您可以为您的目的设置颜色和透视动画。
为了避免 XY 问题,首先是 Y:有没有办法在不需要 Win2D 的 SpriteVisual 上创建文本?
现在 X:我要解决的问题是我需要 SpriteVisual(而不是 TextBlock)上的文本来应用透视旋转 3D 表达式动画。 SpriteVisual 上的文本可以使用 Win2D 完成。这是 Microsoft sample code:
的一部分using (var ds = CanvasComposition.CreateDrawingSession(_drawingSurface))
{
ds.Clear(Colors.Transparent);
var rect = new Rect(new Point(2, 2), (_drawingSurface.Size.ToVector2() - new Vector2(4, 4)).ToSize());
ds.FillRoundedRectangle(rect, 15, 15, Colors.LightBlue);
ds.DrawRoundedRectangle(rect, 15, 15, Colors.Gray, 2);
ds.DrawText("This is a composition drawing surface", rect, Colors.Black, new CanvasTextFormat()
{
FontFamily = "Comic Sans MS",
FontSize = 32,
WordWrapping = CanvasWordWrapping.WholeWord,
VerticalAlignment = CanvasVerticalAlignment.Center,
HorizontalAlignment = CanvasHorizontalAlignment.Center
}
);
_drawingBrush.Surface = _drawingSurface;
_drawingVisual = _compositor.CreateSpriteVisual();
_drawingVisual.Brush = _drawingBrush;
要为其中的文本着色需要 Win2D ICanvasBrush。但我想在 Expression Animation 中为颜色设置动画,因此我需要来自 CompositionBrush 的文本颜色。现在我可以创建一个 CompositionMaskBrush,其中文本画笔作为遮罩,CompositionBrush 作为源。但是对于 CompositionMaskBrush,我无法为其添加额外的遮罩或任何其他合成效果,这对我来说是个问题。
是否有我不熟悉的 Insider Build 中的替代方法或增强组合 API?
Y-answer:不能,您只能使用 Win2d CanvasDrawingSession
在 CompositionDrawingSurface
上绘制文本。但是您可以使用 ElementCompositionPreview.GetElementVisual(yourTextBlock)
从 XAML TextBlock
获得 Visual
并使用 Composition API 表达式 + XAML 颜色故事板对其进行动画处理。
X-answer:您可以从文本 CompositionDrawingSurface
创建一个 alpha 蒙版并将其应用于 CompositionColorBrush
:
private void CreateColoredText(string text)
{
var compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;
var graphicsDevice = CanvasComposition.CreateCompositionGraphicsDevice(compositor, CanvasDevice.GetSharedDevice());
var spriteTextVisual = compositor.CreateSpriteVisual();
spriteTextVisual.Size = new Vector2(512, 512);
var maskDrawingSurface = graphicsDevice.CreateDrawingSurface(new Size(512, 512), DirectXPixelFormat.B8G8R8A8UIntNormalized, DirectXAlphaMode.Premultiplied);
using (var ds = CanvasComposition.CreateDrawingSession(maskDrawingSurface))
{
ds.Clear(Colors.Transparent);
ds.DrawText(text, new Rect(0, 0, 512, 512), Colors.Lime, new CanvasTextFormat
{
FontSize = 32,
FontWeight = FontWeights.Bold,
VerticalAlignment = CanvasVerticalAlignment.Center,
HorizontalAlignment = CanvasHorizontalAlignment.Center,
LineSpacing = 32
});
}
var maskSurfaceBrush = compositor.CreateSurfaceBrush(maskDrawingSurface);
var surfaceTextBrush = compositor.CreateColorBrush(Colors.DeepPink);
var maskBrush = compositor.CreateMaskBrush();
maskBrush.Mask = maskSurfaceBrush;
maskBrush.Source = surfaceTextBrush;
var colorAnimation = compositor.CreateColorKeyFrameAnimation();
colorAnimation.InsertKeyFrame(0.5f, Colors.DeepSkyBlue);
colorAnimation.InsertKeyFrame(1, Colors.DeepPink);
colorAnimation.Duration = TimeSpan.FromMilliseconds(1500);
colorAnimation.IterationBehavior = AnimationIterationBehavior.Forever;
surfaceTextBrush.StartAnimation("Color", colorAnimation);
spriteTextVisual.Brush = maskBrush;
ElementCompositionPreview.SetElementChildVisual(Grid, spriteTextVisual);
}
现在您可以为您的目的设置颜色和透视动画。