GSI

사용자 삽입 이미지

본 프로그램은 위의 그림의 Grid 객체가 중앙을 기준으로 회전하는 에니메이션 예제 입니다.
Start Angle, End Angle의 값을 변경해서 시작과 끝의 각도를 정해줄 수 있습니다.
Start, End의 회전각도를 정하고 Start 버튼을 누르면 원하는 각도만큼 회전할 수 있습니다.

본 예제는 Animation을 진행할 때 Value의 객체를 cs 파일에서 접근해서 처리 하기가 힘든 기존의 부분을 처리 하기 쉽도록 테스트를 해본 겁니다. ^^ (개인적으로 힘들었어요)

[코드 설명]
Animation의 SplineDoubleKeyFrame에 들어 가는 Value의 값을 바꾸기 위해서
처리용 클래스를 하나 제작했습니다.

    public class AniControl
    {
        private int start;
        private int end;

        public int Start
        {
            set { start = value; }
            get { return start; }
        }

        public int End
        {
            set { end = value; }
            get { return end; }
        }
    }

이제 연동을 위해서 xaml 코드에 추가작업을 했습니다.

xmlns:src="clr-namespace:CircleRotate" <-- 네임스페이스를 <Window.. 여기에 추가했습니다.

Window.Resources 내부에 미리 값을 지정하면서 aniControl을 하나 제작생성했습니다.

<src:AniControl x:Key="aniControl" Start="10" End="180" />

미리 제작한 Timeline1의 에니메이션 코드의 SplineDoubleKeyFrame 의 Value에 DataBind를 연결합니다.

<Storyboard x:Key="Timeline1">
 <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="grid" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)">
        <SplineDoubleKeyFrame KeyTime="00:00:00"
                              Value="{Binding Source={StaticResource aniControl}, Path=Start}"/>
  <SplineDoubleKeyFrame KeyTime="00:00:02"
                              Value="{Binding Source={StaticResource aniControl}, Path=End}"/>
 </DoubleAnimationUsingKeyFrames>
</Storyboard>

이렇게 해서 실행해 보면 객체를 회전시킬 수 있습니다.
여기서 조금더 추가를 해서 Start, End의 값을 TextBox를 통해서 값을 받아서 회전 값을 처리하도록 구현했습니다.
TextBox의 값을 바로 바인딩해도 되지만 aniControl로 값을 보내도록 해봤습니다.

<TextBox HorizontalAlignment="Left" Margin="90,80,0,0" VerticalAlignment="Top" Width="56" Height="24"
         Text="{Binding Source={StaticResource aniControl}, Path=Start, Mode=TwoWay}"
         TextWrapping="Wrap" RenderTransformOrigin="0,0.333" x:Name="txtStart"/>
<TextBox HorizontalAlignment="Left" Margin="90,108,0,0" VerticalAlignment="Top" Width="56" Height="24"
         Text="{Binding Source={StaticResource aniControl}, Path=End, Mode=TwoWay}"

자세한 코드 내용은 소스를 한번 보시구요.
모르는거 있으시면 연락 주세요 ^^.

관련 소스 :

Posted by gsi
:

Blend를 사용해서 Animation을 작성하다 보면 Blend에서 작성한 코드만 가지고 안될때가 많다. 코드 중간 중간 실시간적으로 받은 데이터의 값을 에니메이션 Value에 추가해서 사용해야 할때가 많아 진다.

이럴 경우 코드 비하인드에서 스토리 보드 부터 다 짜게 되면야.
값 접근하는게 어렵지는 않다. 하지만 에니메이션 정보를 코드로 다 짜준다는건 캐 노가다거나 거의 비효율적인 작업이 될 것이다. 그래서 몇가지 예제를 찾아 봤는데.

다른 방법이 하나 있긴 하다 공도님 사이트에서 본것 ^^..
이것 > http://gongdo.tistory.com/110

하지만 그것도 좀 그렇다. 왠지 작업량이 복잡해 지고 불편하다.

그래서 내부 구조를 조금씩 보면서 아래와 같은 접근 방법을 사용하였다.

<Storyboard x:Key="Timeline1">
 <DoubleAnimationUsingKeyFrames x:Name="TestAni1" BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
  <SplineDoubleKeyFrame x:Name="TestSpline1" KeyTime="00:00:00" Value="0"/>
  <SplineDoubleKeyFrame x:Name="TestSpline2" KeyTime="00:00:01" Value="192"/>
 </DoubleAnimationUsingKeyFrames>
 <DoubleAnimationUsingKeyFrames x:Name="TestAni2" BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)">
  <SplineDoubleKeyFrame x:Name="TestSpline3" KeyTime="00:00:00" Value="0"/>
  <SplineDoubleKeyFrame x:Name="TestSpline4" KeyTime="00:00:01" Value="62.206"/>
 </DoubleAnimationUsingKeyFrames>
</Storyboard>

위의 코드도 결국 cs 파일에서 하는거 처름 다 추가 되는거라고 생각하고.
아래와 같이 분해 해보았다.

이런 XAML 코드가 있다고 하고 192라는 값을 코드 중간에 바꾸고자 할때
아래와 같이 하면 접근이 되는 것을 확인 하였다.

// 스토리 보드를 가져 온다.
Storyboard st = (Storyboard)this.FindResource("Timeline1");
// 스토리 보드의 내부 타임 라인 그룹정보를 가져 온다.
TimelineCollection tgroup = (TimelineCollection)st.Children;
// TimelineCollection 안에 있는 객체 하나를 가져 온다.
// 근데 여기서 int형 배열 정보만 받는다. 그럼 내가 몇번째 것을 제어 하고 싶은지
// 알아야 할거 같다.
DoubleAnimationUsingKeyFrames dAniFrame = (DoubleAnimationUsingKeyFrames)tgroup[0];
// SplineDoubleKeyFrame  정보를 가져 오기 위해서
// DoubleKeyFrameCollection 의 정보를 가져 온다.
DoubleKeyFrameCollection dAniFrameGroup = (DoubleKeyFrameCollection)dAniFrame.KeyFrames;
// SplineDoubleKeyFrame  정보를 가져 온다.
SplineDoubleKeyFrame spAniFrame = (SplineDoubleKeyFrame)dAniFrameGroup[1];
// Value 값을 조정할 수 있게 된다.
spAniFrame.Value = 500;

코드 량은 좀 되는거 같아도 접근을 할 수 있는거 같은데요.
사실 이거 말고 다른게 있을듯도 한데.. ms가 이거 만들면서 이런거 고민했을텐데.
사실 다른건 아직 방법을 찾지 못했네요.

혹시 아시면 코멘트 부탁해요.

Posted by gsi
:

세삼 느끼는 거지만 msdn의 예제는 너무 xaml 중심으로 되어 있다.
이런 코드의 예제가 절실하게 필요한 때인거 같다.

-- XAML CODE—

 

<Storyboard x:Key="OnCalendarLoaded">

 <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"

Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(SkewTransform.AngleX)"

Storyboard.TargetName="TargetShape">

                        <SplineDoubleKeyFrame   KeySpline="0.5,0.5,0.5,0.5" Value="0" KeyTime="00:00:00"/>

                        <SplineDoubleKeyFrame   KeySpline="0.5,0.5,0.5,0.5" Value="15" KeyTime="00:00:01"/>

            </DoubleAnimationUsingKeyFrames>

      </Storyboard>

….

          <Rectangle Stroke="White" Margin="0,20,0,0"

            Width="120" Height="100"

            x:Name="TargetShape"

            Fill="sc#0.400752217, 0.3677801, 0.3677801, 0.3677801">

              <Rectangle.RenderTransform>

                <TransformGroup>

                  <TranslateTransform X="0" Y="0"/>

                  <ScaleTransform ScaleX="0" ScaleY="0"/>

                  <SkewTransform AngleX="15" AngleY="0"/>

                  <RotateTransform Angle="0"/>

                  <TranslateTransform X="0" Y="0"/>

                  <TranslateTransform X="0" Y="0"/>

                </TransformGroup>

              </Rectangle.RenderTransform>

            </Rectangle>

 

Void StartAnimationsFunction()

{

      Storyboard story = (Storyboard)this.FindResource("OnCalendarLoaded");

      BeginStoryboard(story); // IT WORKS!

}

 


 

-- C# CODE --

 

<Storyboard x:Key="OnCalendarLoaded">

      </Storyboard>

 

 

Void StartAnimationsFunction ()

{

      Storyboard story = (Storyboard)this.FindResource("OnCalendarLoaded");

story.Children.Add(getAnimation1("TargetShape"));

      BeginStoryboard(story); // NOTHING HAPPENS!

}

       

        private DoubleAnimationUsingKeyFrames getAnimation1(string name)

        {

            DoubleAnimationUsingKeyFrames anim = new DoubleAnimationUsingKeyFrames();

            anim.BeginTime = new TimeSpan(0, 0, 0);

 

            Storyboard.SetTargetName(anim, name);

            Storyboard.SetTargetProperty(anim,

                new PropertyPath("0.1[2].2", new DependencyProperty[] {

                    UIElement.RenderTransformProperty,

                    TransformGroup.ChildrenProperty,

                    SkewTransform.AngleXProperty}));

 

            anim.KeyFrames.Add(new SplineDoubleKeyFrame(0, KeyTime.FromTimeSpan(new TimeSpan(0, 0, 0)), new KeySpline(.5, .5, .5, .5)));

            anim.KeyFrames.Add(new SplineDoubleKeyFrame(15, KeyTime.FromTimeSpan(new TimeSpan(0, 0, 1)), new KeySpline(.5, .5, .5, .5)));

 

            return anim;

        }

Posted by gsi
: