Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

wpf - WinRT (C#/XAML) Scale without blurring

I've put together a basic animation which has a Control scaling from 0.1 to 1.0 (x & y). The problem I keep seeing throughout is this "blurring" of the said controls before they settle on the final static state.

An Example is this screen cam I took.

Watch Screen Cam

I'm not sure what's causing this. Its a default Animation / Storyboard that you would generate via Blend.

<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)" Storyboard.TargetName="UIBorder" >
            <EasingDoubleKeyFrame KeyTime="0" Value="0.2">
                <EasingDoubleKeyFrame.EasingFunction>
                    <BackEase EasingMode="EaseInOut"/>
                </EasingDoubleKeyFrame.EasingFunction>
            </EasingDoubleKeyFrame>
            <EasingDoubleKeyFrame KeyTime="0:0:1.4" Value="1">
                <EasingDoubleKeyFrame.EasingFunction>
                    <BackEase EasingMode="EaseInOut" Amplitude="3"/>
                </EasingDoubleKeyFrame.EasingFunction>
            </EasingDoubleKeyFrame>
        </DoubleAnimationUsingKeyFrames>

The said control:

<Grid x:Name="UIBorder" Width="555"  HorizontalAlignment="Center" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.5">
            <Grid.RenderTransform>
                <CompositeTransform ScaleY="0.2" ScaleX="0.2"/>
            </Grid.RenderTransform>

            <Grid Margin="122,0,0,0" RenderTransformOrigin="0.5,0.5" >
                <Border Background="#FF343434" ManipulationMode="None" IsDoubleTapEnabled="False" IsHoldingEnabled="False" IsRightTapEnabled="False" IsTapEnabled="False" RenderTransformOrigin="0.5,0.5"  >
                    <Border.RenderTransform>
                        <CompositeTransform/>
                    </Border.RenderTransform>
                </Border>
            </Grid>
            <Image HorizontalAlignment="Left" VerticalAlignment="Center" Source="ms-appx:///Assets/Chrome/LoginSeal.png" Stretch="None"/>
        </Grid>

Note:

  • I've had this blurring confirmed on both a Windows 8 PC and Surface RT Tablet from two independent sources (ie not hardware specific).
  • I've tried BitmapCache to see if that had any changes to it (got worse as it would).
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Seems like a bug. Apparently WinRT is turning CacheMode to BitmapCache automatically during animations and it caches the object at the low scale. While I couldn't reproduce what you are seeing now I had a similar problem in one of the prerelease versions of Windows 8 when animating projection properties of TextBlocks. I think what likely happens is it uses the highest size of your control used before starting the animation to determing the RenderAtScale property value used for BitmapCache (which is not available in WinRT, but existed in Silverlight or WPF and it seems like a version of it exists in WinRT, it just isn't exposed to users of the API). One workaround then might be to somehow invisibly set the ScaleX/ScaleY values of your bitmap to 1 when it loads and then back to 0.2 before the bitmap first shows up. Alternatively you could have the control's opacity set to 0 and scale to 1 before the animation starts, then fade-in the control after animating the scale to 0.2. If you really need the small one to show up before the animation - you could have two copies of the control - one small one that disappears right after the start of the animation and another that starts big but invisible (or at Opacity="0.005") and very quickly animates to Opacity 1, Scale 0.2 when the animation starts.

This looked fine to me:

<Page
    x:Class="App76.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App76"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <Page.Resources>
        <Storyboard
            x:Name="anim"
            SpeedRatio="0.2">
            <DoubleAnimationUsingKeyFrames
                Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)"
                Storyboard.TargetName="UIBorder">
                <EasingDoubleKeyFrame
                    KeyTime="0"
                    Value="0.2">
                    <EasingDoubleKeyFrame.EasingFunction>
                        <BackEase
                            EasingMode="EaseInOut" />
                    </EasingDoubleKeyFrame.EasingFunction>
                </EasingDoubleKeyFrame>
                <EasingDoubleKeyFrame
                    KeyTime="0:0:1.4"
                    Value="1">
                    <EasingDoubleKeyFrame.EasingFunction>
                        <BackEase
                            EasingMode="EaseInOut"
                            Amplitude="3" />
                    </EasingDoubleKeyFrame.EasingFunction>
                </EasingDoubleKeyFrame>
            </DoubleAnimationUsingKeyFrames>
            <DoubleAnimationUsingKeyFrames
                Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)"
                Storyboard.TargetName="UIBorder">
                <EasingDoubleKeyFrame
                    KeyTime="0"
                    Value="0.2">
                    <EasingDoubleKeyFrame.EasingFunction>
                        <BackEase
                            EasingMode="EaseInOut" />
                    </EasingDoubleKeyFrame.EasingFunction>
                </EasingDoubleKeyFrame>
                <EasingDoubleKeyFrame
                    KeyTime="0:0:1.4"
                    Value="1">
                    <EasingDoubleKeyFrame.EasingFunction>
                        <BackEase
                            EasingMode="EaseInOut"
                            Amplitude="3" />
                    </EasingDoubleKeyFrame.EasingFunction>
                </EasingDoubleKeyFrame>
            </DoubleAnimationUsingKeyFrames>

        </Storyboard>
    </Page.Resources>
    <Grid
        Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Grid
            x:Name="UIBorder"
            Width="555"
            HorizontalAlignment="Center"
            VerticalAlignment="Center"
            RenderTransformOrigin="0.5,0.5">
            <!--<Grid.CacheMode>
                <BitmapCache
                    />
            </Grid.CacheMode>-->
            <Grid.RenderTransform>
                <CompositeTransform
                    x:Name="ct"
                    ScaleY="0.2"
                    ScaleX="0.2" />
            </Grid.RenderTransform>

            <Grid
                Margin="122,0,0,0"
                RenderTransformOrigin="0.5,0.5">
                <Border
                    Background="#FF343434"
                    ManipulationMode="None"
                    IsDoubleTapEnabled="False"
                    IsHoldingEnabled="False"
                    IsRightTapEnabled="False"
                    IsTapEnabled="False"
                    RenderTransformOrigin="0.5,0.5">
                    <Border.RenderTransform>
                        <CompositeTransform />
                    </Border.RenderTransform>
                </Border>
            </Grid>
            <Image
                HorizontalAlignment="Left"
                VerticalAlignment="Center"
                Source="ms-appx:///Assets/SplashScreen.png"
                Stretch="None" />
        </Grid>
        <Button
            VerticalAlignment="Bottom"
            HorizontalAlignment="Left"
            Content="TEST"
            Click="ButtonBase_OnClick" />
    </Grid>
</Page>

using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace App76
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            ct.ScaleX = 1;
            ct.ScaleY = 1;
            this.Loaded += MainPage_Loaded;
        }

        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            ct.ScaleX = 0.2;
            ct.ScaleY = 0.2;
        }

        private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
        {
            anim.Begin();
        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...