Y-answer: Нет, вы можете рисовать текст только на CompositionDrawingSurface
, используя Win2d CanvasDrawingSession
. Но вы можете получить Visual
из XAML TextBlock
с помощью ElementCompositionPreview.GetElementVisual(yourTextBlock)
и анимировать его с помощью выражений API композиции + цветных раскадровок XAML.
X-answer: Вы можете создать альфа-маску из своего текста CompositionDrawingSurface
и применить ее к 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);
}
Теперь вы можете анимировать цвет и перспективу для своих целей.
Перегружение обычно является пугалом заключенных типом языков (по крайней мере, когда, как F#, система типов не достаточно мощна для содержания классов типа). Существует много вариантов, которые Вы имеете в F#:
Для конкретного примера, я, вероятно, просто использовал бы перегрузку метода:
type MathOps =
static member sqrt_int(x:int) = x |> float |> sqrt |> int
static member sqrt_int(x:int64) = x |> float |> sqrt |> int64
let x = MathOps.sqrt_int 9
let y = MathOps.sqrt_int 100L
Да, это может быть сделано. Смотрите на этот поток hubFS .
В этом случае, решение было бы:
let inline retype (x:'a) : 'b = (# "" x : 'b #)
let inline sqrt_int (n:'a) = retype (sqrt (float n)) : 'a
Протест : никакая проверка типа времени компиляции. Т.е. sqrt_int "blabla"
прекрасные компиляции, но Вы получите FormatException во времени выполнения.
Вот другой способ использовать проверки типа выполнения...
let sqrt_int<'a> (x:'a) : 'a = // '
match box x with
| :? int as i -> downcast (i |> float |> sqrt |> int |> box)
| :? int64 as i -> downcast (i |> float |> sqrt |> int64 |> box)
| _ -> failwith "boo"
let a = sqrt_int 9
let b = sqrt_int 100L
let c = sqrt_int "foo" // boom
Уже не отнять у корректных ответов, если, но можно на самом деле использовать ограничения типа в сопоставлении с образцом. Синтаксис:
| :? type ->
Или если Вы хотите объединить проверку типа и бросок:
| :? type as foo ->