2010-12-30 2 views
2

나는 TextBlock에 애니메이션을 적용하고있다. 60 초가 지나면 FontSize이 8pt에서 200pt로 증가합니다. 텍스트가 커짐에 따라 애니메이션이 약간 위아래로 움직이는 것을 제외하면 모든 것이 잘 작동합니다. 왜 이런 일이 일어나고 이것을 피할 수 있습니까?WPF : 애니메이션이 부드럽 지 않다.

<Window x:Class="Timer.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Width="800" 
     Height="500" 
     Title="MainWindow" 
     Loaded="Window_Loaded"> 

    <Grid> 

     <TextBlock 
      Name="TimerTextBlock" 
      HorizontalAlignment="Center" 
      VerticalAlignment="Center" 
      Text="00h : 00m : 00.000s" /> 

    </Grid> 

</Window> 

그리고 코드 숨김 똑같이 간단한 :

public partial class MainWindow : Window 
{ 
    private const string timerFormat = "{0:hh'h : 'mm'm : 'ss'.'fff's'}"; 
    private DispatcherTimer dispatcherTimer; 
    private DateTime targetTime; 

    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     targetTime = DateTime.Now.AddSeconds(60); 
     double totalTime = targetTime.Subtract(DateTime.Now).TotalMilliseconds; 

     DoubleAnimation animation = new DoubleAnimation(); 
     animation.From = TimerTextBlock.FontSize; 
     animation.To = 200; 
     animation.Duration = new Duration(targetTime.Subtract(DateTime.Now)); 
     TimerTextBlock.BeginAnimation(TextBlock.FontSizeProperty, animation); 

     dispatcherTimer = new DispatcherTimer(); 
     dispatcherTimer.Interval = TimeSpan.FromMilliseconds(1); 
     dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick); 
     dispatcherTimer.Start(); 
    } 

    private void dispatcherTimer_Tick(object sender, EventArgs e) 
    { 
     if (DateTime.Compare(targetTime, DateTime.Now) > 0) 
     { 
      TimerTextBlock.Text = 
       string.Format(timerFormat, targetTime.Subtract(DateTime.Now)); 
     } 
    } 
} 

모든 해명 주셔서 감사합니다

내가

매우 간단한 XAML 파일이 있습니다.

+0

필자는 이것이 '픽셀 분할'에 대한 문제라고 확실히 결론을 내 렸습니다. 컨트롤이 두 픽셀 사이 어딘가에 그려져야하는 상황에 이르면 조금 잘리는 것이 합리적입니다. 그러나, 어떻게 든 이것을 피할 수있는 방법이 있습니까? – Boris

+0

나는 인터넷에서 해답을 찾고 있었고 몇몇 "MatrixAnimations"를 보았습니다. 그것은 무엇입니까, 그 트릭을 할 수 있을까요? (그리고 그렇다면, 어떻게?) – Boris

답변

2

수직 점핑 문제는 글꼴 렌더링 반올림으로 인한 것입니다. 특히 WPF는 글꼴 다듬기를 활성화하기 위해 하위 픽셀 글꼴 높이를 방지합니다. 이것을 방지하는 한 가지 방법은 텍스트를 경로 지오메트리로 변환 한 다음 스케일 변형을 사용하여 애니메이션에 적용하는 것입니다.

다음은 점프하지 않고 예제의 대체 버전입니다.

<Grid> 
    <Path Name="Path" HorizontalAlignment="Center" VerticalAlignment="Center"/> 
</Grid> 

새로운 코드는 윈도우로드 할 때 : 새로운 XAML은 당신에게

private void SetText(string text) 
{ 
    var formatted = new FormattedText(text, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface("Lucida Console"), 12, Brushes.Black); 
    Path.Data = formatted.BuildGeometry(new Point(0, 0)); 
    Path.Fill = Brushes.Black; 
} 

과 : anmiated되는 텍스트를 설정하는

SetText(""); 
var transform = new ScaleTransform(1, 1); 
Path.LayoutTransform = transform; 
var animationX = new DoubleAnimation(1, 10, new Duration(TimeSpan.FromSeconds(60))); 
transform.BeginAnimation(ScaleTransform.ScaleXProperty, animationX); 
var animationY = new DoubleAnimation(1, 10, new Duration(TimeSpan.FromSeconds(60))); 
transform.BeginAnimation(ScaleTransform.ScaleYProperty, animationY); 

하고 새로운 방법을 타이머 이벤트 핸들러에서 SetText를 호출해야합니다.

가로 튀어 나오지 않게하려면 고정 길이 텍스트 문자열과 고정 폭 글꼴을 사용해야합니다.

+0

+ 1 아주 좋네요. 텍스트는 이제 부드럽게 움직입니다. 그러나 텍스트가 커질수록 약간의 별칭이 생깁니다. 예상 되나요? –

+0

하위 픽셀 앤티 앨리어싱은 애니메이션의 매끄러움을 위해 필수적이므로 선명한 텍스트 또는 부드러운 애니메이션과 트레이드 오프입니다. –

+0

좋은 것. 고정 길이 텍스트 문자열과 고정 폭 글꼴로 제한되지만 텍스트를 가운데 정렬 할 수있는 다른 방법은 없습니다. – Boris

관련 문제