2013-03-10 3 views
14

텍스트를 TranslateTransform으로 스크롤 할 수 있지만 애니메이션이 끝나기가 가까울 때 다시 시작하고 싶습니다. 뱀 :WPF 텍스트 텍스트 애니메이션

처럼 이것은 내가있어 무엇 :

<StackPanel Orientation="Horizontal" Margin="0,0,0,0"> 
    <StackPanel.RenderTransform> 
     <TranslateTransform x:Name="transferCurreny" X="-40"/> 
    </StackPanel.RenderTransform> 
    <StackPanel.Triggers> 
     <EventTrigger RoutedEvent="StackPanel.Loaded"> 
      <BeginStoryboard> 
       <Storyboard> 
        <DoubleAnimation From="0" To="-900" Duration="00:00:10" 
         Storyboard.TargetProperty="X" 
         Storyboard.TargetName="transferCurreny" 
         RepeatBehavior="Forever"/> 
       </Storyboard> 
      </BeginStoryboard> 
     </EventTrigger> 
    </StackPanel.Triggers> 
    <TextBlock FontSize="25" x:Name="txtKron" Margin="10,0,7,0"/> 
</StackPanel> 

이것은 내가 원하는 무엇인가 :이 같은

enter image description here

+0

문제는 무엇입니까? 원하는 행동은 무엇입니까? 어떤 행동을합니까? –

+0

질문입니다. 나는 텍스트를 움직이지 만 뱀처럼 좋아한다. – meymetkaplan

+0

나는 아직도 이해하지 못한다. 사진을 칠할 수 있습니까? 또는 이전에이 효과를 본 적이있는 장소를 알려주십시오. –

답변

12

뭔가 트릭을 할해야합니다.

는 당신은 다른 블록이보기에 올 것이다 오프 스크린 텍스트의 첫 번째 블록이 갈 때 다음의 StackPanelActualWidth 0과 한 세트를 배치합니다 StackPanelTextBlocks 한 2 세트에 Canvas를 추가 할 수 있습니다. Canvas 실제로 ClipToBounds="false"이가 그것 Canvas 자체

의 경계 외부에 배치해도 2 TextBlock 우리는 또한 얻을 수있는 IValueConverter을 필요로 볼 수 있습니다 지원하는 유일한 요소이기 때문에

내가 Canvas을 사용하는 이유는 오른쪽에서 왼쪽으로 스크롤하려는 경우 올바른 음수 값.

SizeChanged에 이벤트 트리거를 추가 했으므로 창이 크기가 조정되면 애니메이션 값이 올바르게 업데이트됩니다.

코드 :

namespace WpfApplication9 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 

     public MainWindow() 
     { 
      InitializeComponent(); 
     } 
    } 

    public class NegatingConverter : IValueConverter 
    { 

     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      if (value is double) 
      { 
       return -((double)value); 
      } 
      return value; 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      if (value is double) 
      { 
       return +(double)value; 
      } 
      return value; 
     } 
    } 
} 

XAML :

<Window x:Class="WpfApplication9.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:WpfApplication9" 
     Title="MainWindow" Height="83" Width="222" Name="UI" Tag="Tol Level"> 
    <StackPanel Orientation="Horizontal" x:Name="stack"> 
     <StackPanel.Resources> 
      <local:NegatingConverter x:Key="NegatingConverter" /> 
      <Storyboard x:Key="slide"> 
       <DoubleAnimation From="0" To="{Binding Width, ElementName=canvas, Converter={StaticResource NegatingConverter}}" Duration="00:00:10" 
         Storyboard.TargetProperty="X" 
         Storyboard.TargetName="transferCurreny" 
         RepeatBehavior="Forever"/> 
      </Storyboard> 
     </StackPanel.Resources> 
     <StackPanel.RenderTransform> 
      <TranslateTransform x:Name="transferCurreny" X="0"/> 
     </StackPanel.RenderTransform> 
     <StackPanel.Triggers> 
      <EventTrigger RoutedEvent="StackPanel.Loaded"> 
       <BeginStoryboard Storyboard="{StaticResource slide}" /> 
      </EventTrigger> 
      <EventTrigger RoutedEvent="StackPanel.SizeChanged"> 
       <BeginStoryboard Storyboard="{StaticResource slide}" /> 
      </EventTrigger> 
     </StackPanel.Triggers> 
     <Canvas x:Name="canvas" Width="{Binding ActualWidth, ElementName=stack}"> 
      <TextBlock Text="StackOverflow" FontSize="25" x:Name="txtKron" Canvas.Left="0"/> 
      <TextBlock Text="{Binding Text, ElementName=txtKron}" FontSize="25" Canvas.Left="{Binding Width, ElementName=canvas}"/> 
     </Canvas> 
    </StackPanel> 
</Window> 

결과 :

enter image description hereenter image description here

편집 : 왼쪽 0,123

를 오른쪽으로
<StackPanel Orientation="Horizontal" x:Name="stack"> 
     <StackPanel.Resources> 
      <local:NegatingConverter x:Key="NegatingConverter" /> 
      <Storyboard x:Key="slide"> 
       <DoubleAnimation From="0" To="{Binding Width, ElementName=canvas}" Duration="00:00:10" 
         Storyboard.TargetProperty="X" 
         Storyboard.TargetName="transferCurreny" 
         RepeatBehavior="Forever"/> 
      </Storyboard> 
     </StackPanel.Resources> 
     <StackPanel.RenderTransform> 
      <TranslateTransform x:Name="transferCurreny" X="0"/> 
     </StackPanel.RenderTransform> 
     <StackPanel.Triggers> 
      <EventTrigger RoutedEvent="StackPanel.Loaded"> 
       <BeginStoryboard Storyboard="{StaticResource slide}" /> 
      </EventTrigger> 
      <EventTrigger RoutedEvent="StackPanel.SizeChanged"> 
       <BeginStoryboard Storyboard="{StaticResource slide}" /> 
      </EventTrigger> 
     </StackPanel.Triggers> 
     <Canvas x:Name="canvas" Width="{Binding ActualWidth, ElementName=stack}"> 
      <TextBlock Text="StackOverflow" FontSize="25" x:Name="txtKron" Canvas.Left="0"/> 
      <TextBlock Text="{Binding Text, ElementName=txtKron}" FontSize="25" Canvas.Left="{Binding Width, ElementName=canvas, Converter={StaticResource NegatingConverter}}"/> 
     </Canvas> 
    </StackPanel> 
+0

안녕하세요 정말 대단합니다. 저는이 문제를 해결하기 위해 노력하고 있습니다. :) 그러나 이것에 관한 한 가지 문제가 있습니다. 첫 번째 블록 (실제로는 하나의 이미지)이 맨 위 = 0이지만 이미지가 거의 맨 위 = 50이면이 문제를 해결하지 못했습니다. 고맙습니다! – meymetkaplan

+0

여기에 문제가 있습니다 - 애니메이션이 시작되지 않습니다. Loaded 이벤트를 추가하여 코드에서 수정했습니다. Storyboard sb = (Storyboard) this.stack.FindResource ("slide"); stack.Dispatcher.BeginInvoke (DispatcherPriority.Loaded, 새 작업() => { sb.Begin(); })))); –

+0

이미지와 동일한 코드를 사용할 수 있습니다. thanks sa_ddam – Sagotharan

3

위의 코드는 연속 스크롤을 생성하지 않습니다. 다음은 연속적인 부드러운 스크롤을위한 코드입니다.

XAML :

<Window x:Class="Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Window1" Height="300" Width="300"> 
    <Grid> 
     <Canvas Margin="6,83,9,0" Name="ViewingBox" Background="YellowGreen" Height="35" VerticalAlignment="Top"> 
      <Label Canvas.Left="263" Canvas.Top="-2" Height="49" Name="BoxOne" FontSize="20">I need breakfast.</Label> 
      <Label Canvas.Left="263" Canvas.Top="-2" Height="49" HorizontalAlignment="Stretch" Name="BoxTwo" VerticalAlignment="Top" FontSize="20">You can have oranges and egg.</Label> 
     </Canvas> 
    </Grid> 
</Window> 

VB 코드 뒤에 :

Imports System.Windows.Media.Animation 

Public Enum Texts 
    BoxOne 
    BoxTwo 
End Enum 

Class Window1 
    Private dubAnim As New DoubleAnimation() 
    Private dubAnim2 As New DoubleAnimation() 
    Private NewsTimer As New Windows.Threading.DispatcherTimer() 
    Dim leadText As Texts = Texts.BoxOne 

    Private Sub Window1_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded 
     dubAnim.From = ViewingBox.ActualWidth 
     dubAnim.To = -BoxOne.ActualWidth 
     dubAnim.SpeedRatio = 0.05 
     AddHandler dubAnim.Completed, AddressOf dubAnim_Completed 
     Timeline.SetDesiredFrameRate(dubAnim, 320) 
     BoxOne.BeginAnimation(Canvas.LeftProperty, dubAnim) 

     dubAnim2.From = ViewingBox.ActualWidth 
     dubAnim2.To = -BoxTwo.ActualWidth 
     dubAnim2.SpeedRatio = 0.05 
     Timeline.SetDesiredFrameRate(dubAnim2, 320) 
     AddHandler dubAnim2.Completed, AddressOf dubAnim2_Completed 

     AddHandler NewsTimer.Tick, AddressOf NewsTimer_Tick 
     NewsTimer.Interval = New TimeSpan(0, 0, 0.9) 
     NewsTimer.Start() 
    End Sub 

    Private Sub NewsTimer_Tick(ByVal sender As Object, ByVal e As EventArgs) 
     Dim BoxOneLocation As Point = BoxOne.TranslatePoint(New Point(0, 0), ViewingBox) 
     Dim BoxTwoLocation As Point = BoxTwo.TranslatePoint(New Point(0, 0), ViewingBox) 

     If leadText = Texts.BoxOne Then 
      Dim loc As Double = BoxOneLocation.X + BoxOne.ActualWidth 
      If loc < ViewingBox.ActualWidth/1.5 Then 
       BoxTwo.BeginAnimation(Canvas.LeftProperty, dubAnim2) 
       NewsTimer.Stop() 
      End If 
     Else 
      Dim loc As Double = BoxTwoLocation.X + BoxTwo.ActualWidth 
      If loc < ViewingBox.ActualWidth/1.5 Then 
       BoxOne.BeginAnimation(Canvas.LeftProperty, dubAnim) 
       NewsTimer.Stop() 
      End If 
     End If 
    End Sub 

    Private Sub dubAnim_Completed(ByVal sender As Object, ByVal e As EventArgs) 
     leadText = Texts.BoxTwo 
     NewsTimer.Start() 
    End Sub 

    Private Sub dubAnim2_Completed(ByVal sender As Object, ByVal e As EventArgs) 
     leadText = Texts.BoxOne 
     NewsTimer.Start() 
    End Sub 
End Class 
+0

니스. 잘 작동합니다! –