2012-10-01 3 views
1

내가 WPF 애니메이션을 부드럽게하는 방법은 무엇입니까?

WPF 애니메이션

스무딩에 어려움을 겪고 있어요 사실 내 애니메이션 코드는 다음과 같다 :

private void AnimateX (FrameworkElement element, double XMoveStart, double XMoveEnd, int secondX) 
{ 

    SineEase eEase = new SineEase(); 
    eEase.EasingMode = EasingMode.EaseInOut; 
    Storyboard sb = new Storyboard(); 

    DoubleAnimation daX = new DoubleAnimation(XMoveStart, XMoveEnd, new Duration(new TimeSpan(0, 0, 0, secondX, 0))); 
    daX.EasingFunction = eEase; 
    Storyboard.SetTargetProperty(daX, new PropertyPath("(Canvas.Left)")); 

    sb.Children.Add(daX); 

    element.BeginStoryboard(sb); 
} 

위의 코드는 사인 쉽게 수평으로 객체를 이동하는 방법이다. 한 물체 만 움직이면 괜찮습니다. 그러나 두 개 이상의 객체가 함께 움직일 때마다 (이전 애니메이션이 아직 완료되지 않은 상태에서 다른 객체의 AnimateX 메소드 호출) 애니메이션이 불안해지기 시작합니다. jittery로 말하자면, 객체는 애니메이션 과정 중에 흔들리는 종류입니다.

+0

컴퓨터가 소프트웨어 렌더링으로 애니메이션을 수행하고 있는지 또는 하드웨어가 가속화되어 있는지 알고 계십니까? –

+0

네, RenderCapability로 테스트하기 만하면 하드웨어 가속입니다. – nan

+0

주 스레드가 Invokes를 사용하여 다른 작업을 수행하고 있습니까? 애니메이션은 주 스레드에서 실행되며 다중 스레드 응용 프로그램을 사용하는 경우 UI에서 다른 스레드를 업데이트하는 데 주 스레드가 사용 중일 수 있습니다. –

답변

0

스토리 보드를 사용하여 직접 속성을 애니메이션하면 어떻게 될까요?

private void AnimateX(FrameworkElement element, double xMoveStart, double xMoveEnd, double durationSeconds) 
{ 
    DoubleAnimation animation = new DoubleAnimation 
    { 
     From = xMoveStart, 
     To = xMoveEnd, 
     Duration = TimeSpan.FromSeconds(durationSeconds), 
     EasingFunction = new SineEase { EasingMode = EasingMode.EaseInOut } 
    }; 

    element.BeginAnimation(Canvas.LeftProperty, animation); 
} 
+0

. 불행히도 이것은 도움이되지 못했습니다. 여전히 애니메이션은 매끄럽지 않습니다. – nan

1

나는 여러 번 동일한 문제에 직면했다. 캔버스에 추가하는 객체에 따라 WPF는 모든 프레임에서 이러한 객체의 표현을 재생성해야한다는 것을 알았습니다 (사용자가 조작하는 UI 요소의 유형에 따라 귀하의 경우 일 수 있습니다). WPF에 캔버스의 표현을 비트 맵에 캐시하도록 지시하여 지터 문제를 해결할 수 있습니다. 이 캔버스의 당신의 XAML 정의에 다음과 같이 매우 간단하게 이루어집니다 : 이것은 당신의 WPF 응용 프로그램의 부하를 감소

<Canvas ...Your canvas properties...> 
    <Canvas.CacheMode> 
     <BitmapCache /> 
    </Canvas.CacheMode> 
    ...Your objects... 
</Canvas>` 

단순히 비트 맵 이미지와 같은 객체의 표현을 저장으로, 그리고 결과로 응용 프로그램은 매 프레임마다 다시 그릴 필요가 없습니다. 이 솔루션은 애니메이션이 외부에서 캔버스에 적용되고 캔버스에 그려진 개별 오브젝트에 적용되는 진행중인 로컬 애니메이션이없는 경우에만 작동합니다. 코드의 다른 애니메이션이 두 객체를 서로에 대해 이동하는 경우 자체 캐싱을 사용하여 분리 캔버스를 만드는 것이 좋습니다.

일부 전략적 요소로 인해 UI 요소가 완화되지 않습니다. 그러나이 전략은 텍스트 상자 등을 비롯하여 기하학적 모양을 비롯한 많은 요소에서 효율적으로 작동하는 것으로 나타났습니다. 어쨌든 항상 시도해 볼 가치가 있습니다.

둘째, 로컬 표현을 캐시하는 것으로 충분하지 않은 경우 코드 성능을 살펴보고 잠시 UI를 일시적으로 차단할 수있는 프로세스가 있는지 확인할 수 있습니다. 이 측면에 관한 획일적 인 해결책은 없으며 애플리케이션 UI에 부담을주는 요소가 무엇인지에 달려 있습니다. 코드를 정리하고 관련성이있는 경우 비동기 프로세스를 사용하면 도움이 될 수 있습니다.

마지막으로 이러한 모든 검사가 끝난 후에도 응용 프로그램의 전체 요구량이 너무 높게 유지되면 일반 프레임 속도를 줄여 응용 프로그램에 약간의 부담을 줄 수 있으며 기본값은 60입니다. 30 또는 40

Timeline.DesiredFrameRateProperty.OverrideMetadata(typeof(Timeline), new FrameworkPropertyMetadata { DefaultValue = 40 }); 
관련 문제