2014-10-15 8 views
0

C# 코드에서 WPF 애니메이션 관련 질문이 있습니다!
MouseWheel 이벤트에 대한 처리기 함수가 있습니다. 그냥 '확대'또는 '축소'되어 있는지 확인합니다. 코드를 살펴보면 중요한 줄은 RenderTransform이 설정된 네 번째 줄입니다.WPF에서 애니메이션 렌더링 RenderTransform

private void ZoomPanCanvas_MouseWheel(object sender, MouseWheelEventArgs e) { 
     var factor = (e.Delta > 0) ? (1.1) : (1/1.1); 
     currrentScale = factor * currrentScale; 
     mNetworkUI.RenderTransform = new ScaleTransform(currrentScale, currrentScale); 
     var pos = e.GetPosition(mNetworkUI); 
     mNetworkUI.Width = ZoomPanCanvas.ActualWidth/currrentScale; 
     mNetworkUI.Height = ZoomPanCanvas.ActualHeight /currrentScale; 
     var dummyTransform = new ScaleTransform(factor, factor, pos.X, pos.Y); 
     var offSet = new Point(dummyTransform.Value.OffsetX, dummyTransform.Value.OffsetY); 
     mNetworkUI.ViewModel.Network.SetTransformOffset(offSet); 
    } 

나는 코드의 나머지 부분을 완벽하게 유지했습니다.
내가 원하는 것은 이 RenderTransform의이 변경 사항을 애니메이션화하는 것입니다!

이미 스토리 보드 (UIElement.RenderTransformProperty 세트 사용)를 사용하려고했습니다. 가장 좋은 결과는 RenderTransform의 애니메이션이 아닌 변경이었습니다 (그러나이 네 번째 코드가 코드 달성과 같은 결과는 아니 었습니다).

어쩌면 당신이 나를 도울 수 있습니다, 나는 이미 여기에 다른 질문에서 몇 가지 제안 된 방법을 시도.

편집 : 여기

가 작동하지 않는 시도이고에서 위의 처음 chenged 코드 :

private void ZoomPanCanvas_MouseWheel(object sender, MouseWheelEventArgs e) { 
     var factor = (e.Delta > 0) ? (1.1) : (1/1.1); 
     currrentScale = factor * currrentScale; 
     ///mNetworkUI.RenderTransform = new ScaleTransform(currrentScale, currrentScale); 
     Helper.Animations.RenderTransformAnimation(mNetworkUI, new ScaleTransform(currrentScale, currrentScale)); 
     var pos = e.GetPosition(mNetworkUI); 
     mNetworkUI.Width = ZoomPanCanvas.ActualWidth/currrentScale; 
     mNetworkUI.Height = ZoomPanCanvas.ActualHeight /currrentScale; 
     var dummyTransform = new ScaleTransform(factor, factor, pos.X, pos.Y); 
     var offSet = new Point(dummyTransform.Value.OffsetX, dummyTransform.Value.OffsetY); 
     mNetworkUI.ViewModel.Network.SetTransformOffset(offSet); 
    } 

그리고 정적 도우미 함수 다음과

public static void RenderTransformAnimation(FrameworkElement element, Transform newTransform) { 
     MatrixAnimationUsingKeyFrames anim = new MatrixAnimationUsingKeyFrames(); 
     var key1 = new DiscreteMatrixKeyFrame(element.RenderTransform.Value, KeyTime.FromPercent(0)); 
     var key2 = new DiscreteMatrixKeyFrame(newTransform.Value, KeyTime.FromPercent(1)); 

     Storyboard.SetTarget(anim, element.RenderTransform); 
     Storyboard.SetTargetProperty(anim, new PropertyPath(UIElement.RenderTransformProperty)); 
     Storyboard sb = new Storyboard(); 
     sb.Children.Add(anim); 
     sb.Duration = AnimationDuration; 
     sb.Begin(); 
    } 

를이 항상 sb.Begin() 호출에서 예외를 던졌습니다. 내 'PropertyPath'에 문제가있는 것이 아닙니다. 직접 "TransformAnimation"을 직접 만들 수있는 방법이 없습니다. MatrixAnimations 만 사용할 수 있습니다.

답변

2

간단한 애니메이션을 제공했습니다. ScaleTransform 아래의 '최소'예제를 제공하기 위해 눈금 조정 만하고 마우스 위치에 따라 수행하는 오프셋 계산을 수행하지 않습니다. 이동 위치를 파악할 수 있어야합니다. 여기에서 :. 당신이 명시 적으로 설정 이유를 설명하면

private void OnMouseWheel(object sender, MouseWheelEventArgs e) 
{ 
    var factor = e.Delta > 0d ? 1.1d : 0.9d; 

    var t = mNetworkUI.RenderTransform as ScaleTransform; 
    if (t == null) 
    { 
     mNetworkUI.RenderTransform = t = new ScaleTransform(1d, 1d) 
             { 
              CenterX = 0.5d, 
              CenterY = 0.5d 
             }; 
    } 

    var oldScale = (double)t.GetAnimationBaseValue(ScaleTransform.ScaleXProperty); 
    var newScale = oldScale * factor; 

    // 
    // Make sure `GetAnimationBaseValue()` reflects the `To` value next time 
    // (needed to calculate `oldScale`, and for the animation to infer `From`). 
    // 
    t.ScaleX = newScale; 
    t.ScaleY = newScale; 

    var animation = new DoubleAnimation 
        { 
         To = newScale, 
         Duration = TimeSpan.FromSeconds(0.5d), 
         DecelerationRatio = 0.5d, 
         FillBehavior = FillBehavior.Stop 
        }; 

    // 
    // Use `HandoffBehavior.Compose` to transition more smoothly if an animation 
    // is already in progress. 
    // 
    t.BeginAnimation(
     ScaleTransform.ScaleXProperty, 
     animation, 
     HandoffBehavior.Compose); 

    t.BeginAnimation(
     ScaleTransform.ScaleYProperty, 
     animation, 
     HandoffBehavior.Compose); 
} 
+0

당신은 하나를 얻을 수't.ScaleX = newScale' 즉,이 애니메이션에 의해 무시 것, 그것은하지 않습니다, BTW 당신이를 지정할 필요가 없습니다? 'oldScale'입니다. 애니메이션에서 알 수 있습니다. –

+0

예, 애니메이션에 의해 스케일 값이 오버라이드되지만 애니메이션 지속 시간 동안에 만 적용됩니다. 애니메이션이 끝나면 속성에 여전히 'To'값이 있어야합니다. 그러나 예, 당신은 * To * 값 또는 * 그냥 * From 값을 지정하고 애니메이션 그림을 다른 것으로 만들 수 있습니다. –

+0

두 애니메이션을 스토리 보드에 포장하지 않으시겠습니까? 그렇지 않으면 이것이 나에게 맞는 것 같습니다. – BradleyDotNET