Ответ 1
Ну, инверсия цвета может быть выполнена как растровый эффект, но есть более простой способ.
Сделайте Grid
, который будет контейнером для 3 дочерних панелей, чтобы эти дочерние панели полностью перекрывали друг друга:
Поместите текст там, где вы хотите, на панели с фоном Transparent
(по умолчанию). Назовите эту маску панели.
Сделайте еще одну панель под названием "mainbackground" и придайте ей главный градиент в качестве фона. Поместите это после панели "маска", чтобы она покрывала текст
Сделайте еще одну панель под названием "invertedforeground" и придайте ей противоположный градиент. Для каждого значения цвета в главном градиенте дайте это противоположное (например, если один цвет #FF0000
, поместите #00FFFF
). Вы можете анимировать этот градиент так же, как вы можете анимировать первый, просто с противоположными значениями. Затем вы установите для OpacityMask
этой панели значение VisualBrush
и установите для свойства VisualBrushes
Visual
значение {Binding ElementName=mask}
.
<Grid>
<Grid.Resources>
<local:MyColorConverter x:Key="colorConverter" />
</Grid.Resources>
<Grid
Name="mask">
<TextBlock
Name="mytext"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="32"
Foreground="White"
FontWeight="Bold">Blah blah blah</TextBlock>
</Grid>
<Grid Name="mainbackground">
<Grid.Background>
<LinearGradientBrush
ColorInterpolationMode="ScRgbLinearInterpolation"
EndPoint="1,0">
<GradientStop x:Name="stop1"
Color="#FF0000"
Offset="0" />
<GradientStop x:Name="stop2"
Color="#00FF00"
Offset="0.5" />
<GradientStop x:Name="stop3"
Color="#0000FF"
Offset="1" />
</LinearGradientBrush>
</Grid.Background>
</Grid>
<Grid Name="invertedforeground">
<Grid.Background>
<LinearGradientBrush
ColorInterpolationMode="ScRgbLinearInterpolation"
EndPoint="1,0">
<GradientStop
Color="{Binding ElementName=stop1, Path=Color, Converter={StaticResource colorConverter}}"
Offset="0" />
<GradientStop
Color="{Binding ElementName=stop2, Path=Color, Converter={StaticResource colorConverter}}"
Offset="0.5" />
<GradientStop
Color="{Binding ElementName=stop3, Path=Color, Converter={StaticResource colorConverter}}"
Offset="1" />
</LinearGradientBrush>
</Grid.Background>
<Grid.OpacityMask>
<VisualBrush
Visual="{Binding ElementName=mask}" />
</Grid.OpacityMask>
</Grid>
</Grid>
Вероятно, вы можете использовать конвертеры привязки и значений, чтобы вам нужно было только оживить один градиент, а другой - просто.
Изменить: Я попытался настроить перевернутую кисть переднего плана для текста, но он будет придерживаться координат TextBlock
, поэтому я вернулся к предыдущему решению использовать текст как OpacityMask
.
Изменить 2: Я добавил пример использования пользовательского IValueConverter
и привязки цветов градиента текста к исходному градиенту. Вы также можете использовать привязку и конвертер где-то выше, например привязку свойства invertedforeground
Background
к свойству mainbackground
Background
, а конвертер принимает кисть градиента ввода и возвращает другую кисть градиента (это позволяет создавать градиент с совершенно другой конфигурацией в качестве оригинала).