2015-08-10 18 views
5

voglio usare questa animazione sugli errori, come quella mostrata here:Agitare animazione (versione 3D)

come realizzare che in WPF? Ho sentito che questa dovrebbe essere una combinazione (composizione?) Di molteplici trasformazioni, ma quali e esattamente come?

Ecco un antipasto (MCVE o chiamarlo "il mio tentativo"), che è brutto e non è nemmeno vicino a quello che voglio:

<Grid> 
    <Border x:Name="border" 
      Width="200" 
      Height="200" 
      BorderBrush="Black" 
      BorderThickness="1" 
      CornerRadius="4" 
      Background="LightBlue" 
      RenderTransformOrigin="0.5,0"> 
     <Border.RenderTransform> 
      <TransformGroup> 
       <ScaleTransform /> 
       <SkewTransform /> 
       <RotateTransform /> 
       <TranslateTransform /> 
      </TransformGroup> 
     </Border.RenderTransform> 
     <Border.Effect> 
      <DropShadowEffect BlurRadius="20" /> 
     </Border.Effect> 
     <Button VerticalAlignment="Bottom" 
       HorizontalAlignment="Center" 
       Margin="0,0,0,10" 
       Padding="5" 
       Content="Click"> 
      <Button.Triggers> 
       <EventTrigger RoutedEvent="Button.Click"> 
        <BeginStoryboard> 
         <Storyboard FillBehavior="Stop"> 
          <DoubleAnimation Storyboard.TargetName="border" 
              Storyboard.TargetProperty="RenderTransform.Children[1].(SkewTransform.AngleX)" 
              To="5" Duration="0:0:0.1"/> 
          <DoubleAnimation Storyboard.TargetName="border" 
              Storyboard.TargetProperty="RenderTransform.Children[1].(SkewTransform.AngleX)" 
              To="-5" 
              BeginTime="0:0:0.1" 
              Duration="0:0:0.2" /> 
          <DoubleAnimation Storyboard.TargetName="border" 
              Storyboard.TargetProperty="RenderTransform.Children[1].(SkewTransform.AngleX)" 
              To="5" 
              BeginTime="0:0:0.3" 
              Duration="0:0:0.2" /> 
          <DoubleAnimation Storyboard.TargetName="border" 
              Storyboard.TargetProperty="RenderTransform.Children[1].(SkewTransform.AngleX)" 
              BeginTime="0:0:0.5" 
              Duration="0:0:0.1" /> 
         </Storyboard> 
        </BeginStoryboard> 
       </EventTrigger> 
      </Button.Triggers> 
     </Button> 
    </Border> 
</Grid> 

Ci sono molti messaggi 2d shake intorno (click, click), ma ho bisogno dell'animazione che dice "hai torto" e non quello che dice "balliamo".

risposta

2

Ecco l'animazione che descrivi. Ho utilizzato uno Viewport3D con un Viewport2DVisual3D per ospitare i controlli.

3DShake

È possibile utilizzare questo per costruire si possiede il controllo scossa personalizzato riutilizzabile.

Non è possibile replicare questa esatta animazione utilizzando semplice 2D RenderTransforms.

<Grid> 
    <Viewport3D> 
     <Viewport3D.Camera> 
      <PerspectiveCamera Position="0, 0, 4"/> 
     </Viewport3D.Camera> 
     <Viewport2DVisual3D x:Name="DVisual3D"> 
      <Viewport2DVisual3D.Transform> 
       <RotateTransform3D> 
        <RotateTransform3D.Rotation> 
         <AxisAngleRotation3D Angle="0" Axis="0, 1, 0" /> 
        </RotateTransform3D.Rotation> 
       </RotateTransform3D> 
      </Viewport2DVisual3D.Transform> 
      <Viewport2DVisual3D.Geometry> 
       <MeshGeometry3D Positions="-1,1,0 -1,-1,0 1,-1,0 1,1,0" 
         TextureCoordinates="0,0 0,1 1,1 1,0" TriangleIndices="0 1 2 0 2 3"/> 
      </Viewport2DVisual3D.Geometry> 
      <Viewport2DVisual3D.Visual> 
       <Border x:Name="border" 
         Width="200" 
         Height="200" 
         BorderBrush="Black" 
         BorderThickness="1" 
         CornerRadius="4" 
         Background="LightBlue"> 
        <Border.Effect> 
         <DropShadowEffect BlurRadius="20" /> 
        </Border.Effect> 
        <Button VerticalAlignment="Bottom" 
          HorizontalAlignment="Center" 
          Margin="0,0,0,10" 
          Padding="5" 
          Content="Click"> 
         <Button.Triggers> 
          <EventTrigger RoutedEvent="Button.Click"> 
           <BeginStoryboard> 
            <Storyboard FillBehavior="Stop"> 
             <DoubleAnimation Storyboard.TargetName="DVisual3D" 
             Storyboard.TargetProperty="Transform.(RotateTransform3D.Rotation).(AxisAngleRotation3D.Angle)" 
             To="10" Duration="0:0:0.07"/> 
             <DoubleAnimation Storyboard.TargetName="DVisual3D" 
             Storyboard.TargetProperty="Transform.(RotateTransform3D.Rotation).(AxisAngleRotation3D.Angle)" 
             To="-10" 
             BeginTime="0:0:0.07" 
             Duration="0:0:0.14" /> 
             <DoubleAnimation Storyboard.TargetName="DVisual3D" 
             Storyboard.TargetProperty="Transform.(RotateTransform3D.Rotation).(AxisAngleRotation3D.Angle)" 
             To="10" 
             BeginTime="0:0:0.21" 
             Duration="0:0:0.14" /> 
             <DoubleAnimation Storyboard.TargetName="DVisual3D" 


        Storyboard.TargetProperty="Transform.(RotateTransform3D.Rotation).(AxisAngleRotation3D.Angle)" 
            BeginTime="0:0:0.35" 
            Duration="0:0:0.07" /> 
          </Storyboard> 
         </BeginStoryboard> 
         </EventTrigger> 
         </Button.Triggers> 
       </Button> 
      </Border> 
     </Viewport2DVisual3D.Visual> 
     <Viewport2DVisual3D.Material> 
      <DiffuseMaterial Viewport2DVisual3D.IsVisualHostMaterial="True" Brush="White"/> 
     </Viewport2DVisual3D.Material> 
    </Viewport2DVisual3D> 
    <ModelVisual3D> 
     <ModelVisual3D.Content> 
      <DirectionalLight Color="#FFFFFFFF" Direction="0,0,-1"/> 
     </ModelVisual3D.Content> 
    </ModelVisual3D> 
</Viewport3D> 

+0

Sembra fantastico, grazie. Non sono sicuro se ciò si adatta (è necessario controllare gli svantaggi dell'utilizzo di 'ViewPort3D'), ma l'animazione sembra simile a quella desiderata. – Sinatr

3

Finora il miglior effetto può essere ottenuto in questo modo:

<Grid> 
    <Border Width="200" 
      Height="200" 
      BorderBrush="Black" 
      BorderThickness="1" 
      CornerRadius="4" 
      Background="LightBlue" 
      RenderTransformOrigin="0.5,0"> 
     <Border.RenderTransform> 
      <RotateTransform x:Name="transform" /> 
     </Border.RenderTransform> 
     <Border.Effect> 
      <DropShadowEffect BlurRadius="20" /> 
     </Border.Effect> 
     <Button VerticalAlignment="Bottom" 
       HorizontalAlignment="Center" 
       Margin="0,0,0,10" 
       Padding="5" 
       Content="Click"> 
      <Button.Triggers> 
       <EventTrigger RoutedEvent="Button.Click"> 
        <BeginStoryboard> 
         <Storyboard FillBehavior="Stop"> 
          <DoubleAnimation Storyboard.TargetName="transform" 
              Storyboard.TargetProperty="Angle" 
              From="5" 
              Duration="0:0:0.5"> 
           <DoubleAnimation.EasingFunction> 
            <ElasticEase EasingMode="EaseOut" 
               Oscillations="2" 
               Springiness="1" /> 
           </DoubleAnimation.EasingFunction> 
          </DoubleAnimation> 
         </Storyboard> 
        </BeginStoryboard> 
       </EventTrigger> 
      </Button.Triggers> 
     </Button> 
    </Border> 
</Grid> 

Questo dono che immergere sente "qualcosa non va". Sono soddisfatto finché non appare una risposta migliore.