View Issue Details

IDProjectCategoryView StatusLast Update
0000508NoesisGUIUnitypublic2018-11-23 16:52
ReporterMrHayato Assigned Tosfernandez  
PriorityhighSeveritymajor 
Status resolvedResolutionfixed 
Fixed in Version2.1.0f1 
Summary0000508: ColorAnimationUsingKeyframes does not animate the dependency property
Description

When using a ColorAnimationUsingKeyframes, and you use Dynamic Resources as the value for the keyframes, the actual resource itself gets modified. For example:

<Color x:Key="Theme1Color">#FFFFFFFF</Color>
<Color x:Key="Theme2Color">#FF000000</Color>

<Storyboard x:Key="ChangeSelectedTextColorTransition">
<ColorAnimationUsingKeyFrames BeginTime="0:0:0"
Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="0:0:0"
Value="{DynamicResource Theme1Color}" />
<EasingColorKeyFrame KeyTime="0:0:0.250"
Value="{DynamicResource Theme2Color}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>

When running this storyboard via C# and passing in a TextBlock as the FrameworkElement to animate, it looks like the textblock is animating from white to black as it should. However, everything else that uses the Theme1Color resource is now black. It seems like the animation isn't animating the TextBlock's color, but it's actually modifying the Color resource itself.

PlatformAny

Activities

MrHayato

MrHayato

2014-12-03 00:41

reporter   ~0001856

Actually, turns out the problem is because the TextBlock has a binding to Foreground like so:

<TextBlock Foreground="{Binding TextColorBrush}" />

And TextColor is a reference to the original Color brush (which I get from the ResourceDictionary programmatically), and is getting modified because of the binding. Setting Mode=OneWay does not solve the problem unfortunately.

sfernandez

sfernandez

2015-01-21 13:04

manager   ~0002000

Hi,

I tried the following sample in WPF:


<Grid
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="Red">
<Grid.Resources>
<Color x:Key="Theme1Color">#FFFFFFFF</Color>
<Color x:Key="Theme2Color">#FF000000</Color>
<SolidColorBrush x:Key="TextColorBrush" Color="{DynamicResource Theme1Color}"/>
<Storyboard x:Key="ChangeSelectedTextColorTransition">
<ColorAnimationUsingKeyFrames
Storyboard.TargetName="txt"
Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="0:0:0" Value="{StaticResource Theme1Color}" />
<EasingColorKeyFrame KeyTime="0:0:2" Value="{StaticResource Theme2Color}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</Grid.Resources>
<Grid.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<EventTrigger.Actions>
<BeginStoryboard Storyboard="{StaticResource ChangeSelectedTextColorTransition}"/>
</EventTrigger.Actions>
</EventTrigger>
</Grid.Triggers>
<Rectangle x:Name="rect" Fill="{StaticResource TextColorBrush}" Width="200" Height="100"/>
<TextBlock x:Name="txt" Text="Hello World" FontSize="40" Foreground="{Binding Fill, ElementName=rect}"/>
</Grid>

And the animation is modifying the color of the rectangle too, so I think we are doing the correct thing here.

You can Freeze the resource obtained from the ResourceDictionary, so it gets cloned when animation tries to modify it.

Let me know if this solution works for you.

MrHayato

MrHayato

2015-01-26 21:56

reporter   ~0002015

I'm not sure that's a viable solution. To me, the Color itself should not change. It should be making a copy of the color and animating that rather than modifying the original resource. We use the same color key throughout the application so it's not possible for us to Freeze the value every time we need to animate it.

Right now, we have to animate everything through code to prevent this issue. Our current solution is something along the lines of:

    private ColorAnimation CreateSelectAnimation()
    {
        var colorAnim = new ColorAnimation();

        colorAnim.SetFrom(new NullableColor(Theming.GetColor("BlackColor")));
        colorAnim.SetTo(new NullableColor(Theming.GetColor("Theme1Color")));
        colorAnim.SetDuration(new Duration(new TimeSpan(0.250)));

        return colorAnim;
    }
MrHayato

MrHayato

2015-01-26 22:24

reporter   ~0002016

And this is our other animation code for animating a color when we don't know what color we're animating from:

    private void Animate(TextBlock depObj, Action callback)
    {
        var sb = new Storyboard();
        var currentColor = depObj.GetForeground().As<SolidColorBrush>().GetColor();

        //TODO: Refactor once we get DataTriggers.
        //Bug in Noesis prevents us from using the values directly in a storyboard...
        depObj.SetForeground(new SolidColorBrush(new Color(currentColor.GetRedF(), currentColor.GetGreenF(), currentColor.GetBlueF(), currentColor.GetAlphaF())));

        Storyboard.SetTarget(_selectAnimation, depObj);
        Storyboard.SetTargetProperty(_selectAnimation, new PropertyPath("(TextBlock.Foreground).(SolidColorBrush.Color)"));

        sb.GetChildren().Add(_selectAnimation);
        BeginStoryboard(depObj, sb, callback);
    }
MrHayato

MrHayato

2015-02-13 06:43

reporter   ~0002079

Hi Sergio, I looked into this a little further as I encountered this problem again. The way to fix it in WPF is to add 'x:Shared="False"' to the SolorColorBrush. This isn't supported in the Unity version of Noesis, but it would solve the problem. This creates a new instance of the color object instead of using the reference. Here's the working WPF example:

<Grid
    Background="Red">
    <Grid.Resources>
        <Color x:Key="Theme1Color">#FFFFFFFF</Color>
        <Color x:Key="Theme2Color">#FF000000</Color>
        <SolidColorBrush x:Key="Theme1Brush" x:Shared="False" Color="{StaticResource Theme1Color}" />
        <SolidColorBrush x:Key="Theme2Brush" x:Shared="False" Color="{StaticResource Theme2Color}" />

        <Storyboard x:Key="ChangeSelectedTextColorTransition">
            <ColorAnimationUsingKeyFrames RepeatBehavior="Forever"
                                          AutoReverse="True"
                                          Storyboard.TargetName="txt"
                                          Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)">
                <EasingColorKeyFrame KeyTime="0:0:0" Value="{StaticResource Theme1Color}" />
                <EasingColorKeyFrame KeyTime="0:0:2" Value="{StaticResource Theme2Color}" />
            </ColorAnimationUsingKeyFrames>
        </Storyboard>
    </Grid.Resources>

    <Grid.Triggers>
        <EventTrigger RoutedEvent="FrameworkElement.Loaded">
            <EventTrigger.Actions>
                <BeginStoryboard Storyboard="{StaticResource ChangeSelectedTextColorTransition}" />
            </EventTrigger.Actions>
        </EventTrigger>
    </Grid.Triggers>

    <Rectangle x:Name="rect" Fill="{StaticResource Theme1Brush}" Width="200" Height="100" />
    <TextBlock x:Name="txt" Text="Hello World" FontSize="40" Foreground="{StaticResource Theme1Brush}" />
</Grid>

Issue History

Date Modified Username Field Change
2014-12-03 00:01 MrHayato New Issue
2014-12-03 00:41 MrHayato Note Added: 0001856
2014-12-03 01:32 sfernandez Assigned To => sfernandez
2014-12-03 01:32 sfernandez Status new => confirmed
2015-01-21 13:04 sfernandez Note Added: 0002000
2015-01-21 13:04 sfernandez Status confirmed => feedback
2015-01-26 21:56 MrHayato Note Added: 0002015
2015-01-26 21:56 MrHayato Status feedback => assigned
2015-01-26 22:24 MrHayato Note Added: 0002016
2015-02-13 06:43 MrHayato Note Added: 0002079
2015-07-23 02:38 jsantos Category Unity Package => Unity3D
2018-11-01 02:14 jsantos View Status public => private
2018-11-21 13:45 jsantos View Status private => public
2018-11-21 13:45 jsantos Platform => Any
2018-11-23 16:52 sfernandez Status assigned => resolved
2018-11-23 16:52 sfernandez Resolution open => fixed
2018-11-23 16:52 sfernandez Fixed in Version => 2.1.0f1
2025-10-10 13:29 jsantos Category Unity3D => Unity