2016-11-14 7 views
0

Как сделать анимацию в холсте большими размерами, когда пользователь щелкает по краю холста? В настоящее время, если размеры слишком велики, и если пользователь нажимает рядом с краем холста, эллипс будет расти за пределами холста, чтобы накрыть кнопки. Мне нужна анимация, чтобы оставаться внутри холста, чтобы он выглядел как кусочек пиццы.EllipseGeometry Shrink & Fade Without Exceeding Canvas Bounds in C# WPF

Должно выглядеть так: Size 50 where user clicks near top left of canvas

В настоящее время выглядит следующим образом: Size 50 where user clicks near top left of canvas

Xaml:

<Window.Resources> 
    <Storyboard x:Key="anim"> 
     <DoubleAnimation 
      Storyboard.TargetName="myCircle" 
      Storyboard.TargetProperty="RadiusX" 
      AutoReverse="True"/> 
     <DoubleAnimation 
      Storyboard.TargetName="myCircle" 
      Storyboard.TargetProperty="RadiusY" 
      AutoReverse="True"/> 
     <DoubleAnimation 
      Storyboard.TargetName="path" 
      Storyboard.TargetProperty="Opacity" 
      AutoReverse="True"/> 
    </Storyboard> 
</Window.Resources> 

<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="23"/> 
     <RowDefinition Height="*"/> 
    </Grid.RowDefinitions> 

    <DockPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="0" Margin="0,0,0,1"> 
     <Menu DockPanel.Dock="Top" Height="23"> 
      <MenuItem Header="Main" RenderTransformOrigin="-1.896,0.643" HorizontalAlignment="Left" Width="39" Height="23"> 
       <MenuItem Header="Exit, Esc" Click="MenuItem_Click_Exit"/> 
      </MenuItem> 
     </Menu> 
    </DockPanel> 

    <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="1" Name="pane"> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="150"/> 
      <ColumnDefinition Width="*"/> 
     </Grid.ColumnDefinitions> 

     <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Column="0" Name="pane2"> 
      <Grid.RowDefinitions> 
       <RowDefinition Height="35"/> 
       <RowDefinition Height="35"/> 
       <RowDefinition Height="35"/> 
       <RowDefinition Height="*"/> 
      </Grid.RowDefinitions> 

      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="100"/> 
       <ColumnDefinition Width="50"/> 
      </Grid.ColumnDefinitions> 

      <Label Content="Size" Grid.Row="0" Grid.Column="0" Height="25" VerticalAlignment="Stretch"/> 
      <Label Content="Fill Color" Grid.Row="1" Grid.Column="0" Height="25" VerticalAlignment="Stretch"/> 
      <Label Content="Stroke Thickness" Grid.Row="2" Grid.Column="0" Height="25" VerticalAlignment="Stretch"/> 
      <Label Content="Stroke Color" Grid.Row="3" Grid.Column="0" VerticalAlignment="Top" Height="25"/> 

      <Slider x:Name="Slider_Size" Grid.Row="0" Grid.Column="1" Height="20" Width="45" 
        Minimum="5" Maximum="50" 
        AutoToolTipPlacement="BottomRight" 
        TickFrequency="1" 
        IsSnapToTickEnabled="True" 
        PreviewMouseUp="Slider_Size_PreviewMouseUp"/> 
      <Label Name="tempSize" Content="{Binding Path=Value, ElementName=Slider_Size}" Margin="0,25,0,131" Grid.Row="3" Visibility="Hidden"/> 
      <ComboBox Name="ComboBox_FillColor" Grid.Row="1" Grid.Column="1" Height="20" Width="45" SelectionChanged="ComboBox_FillColor_Selected"/> 
      <TextBox Name="textBox" Grid.Row="2" Grid.Column="1" Height="20" Width="45" TextChanged="textBox_TextChanged"/> 
      <ComboBox Name="ComboBox_StrokeColor" Grid.Row="3" Grid.Column="1" VerticalAlignment="Top" Height="20" Width="45" SelectionChanged="ComboBox_StrokeColor_Selected"/> 
     </Grid> 

     <Border Name ="border" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" BorderBrush="Black" Grid.Column="1" BorderThickness="2"> 
      <Canvas Name="canvas" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" MouseDown="Canvas_MouseDown"> 
       <Path x:Name="path"> 
        <Path.Data> 
         <EllipseGeometry x:Name="myCircle"/> 
        </Path.Data> 
       </Path> 
       <Canvas.Background> 
        <SolidColorBrush Color="White" Opacity="0"/> 
       </Canvas.Background> 
      </Canvas> 
     </Border> 
    </Grid> 
</Grid> 

C#:

public partial class MainWindow : Window 
{ 
    private int size; 
    private SolidColorBrush fillColor; 
    private SolidColorBrush strokeColor; 
    private List<SolidColorBrush> colors; 
    private int fillIndex; 
    private int strokeIndex; 
    private int strokeThickness = 1; 
    private int fillColorDefault; 
    private int strokeColorDefault; 
    private Point? _start = null; 
    public MainWindow() 
    { 
     InitializeComponent(); 
     addColors(); 
     textBox.Text = strokeThickness.ToString(); 
     parse(); 
    } 
    private void MenuItem_Click_Exit(object sender, RoutedEventArgs e) { Environment.Exit(1); } 

    private void Window_KeyUp_ESC(object sender, KeyEventArgs e) 
    { 
     if (Key.Escape == e.Key) 
      MenuItem_Click_Exit(sender, e); 
    } 
    private void addColors() 
    { 
     colors = typeof(Brushes).GetProperties().Select(p => p.GetValue(null, null) as SolidColorBrush).ToList(); 

     int count = 0; 
     foreach (SolidColorBrush color in colors) 
     { 
      ComboBox_FillColor.Items.Add(new Rectangle() { Height = 12, Width = 17.5, Fill = color }); 
      ComboBox_StrokeColor.Items.Add(new Rectangle() { Height = 12, Width = 17.5, Fill = color }); 

      if (color.Color == Colors.Red) 
      { 
       fillIndex = count; 
       fillColor = colors[fillIndex]; 
       ComboBox_FillColor.SelectedIndex = count; 
       fillColorDefault = count; 
      } 

      if (color.Color == Colors.Black) 
      { 
       strokeIndex = count; 
       strokeColor = colors[strokeIndex]; 
       ComboBox_StrokeColor.SelectedIndex = count; 
       strokeColorDefault = count; 
      } 

      count++; 
     } 
    } 
    private void ComboBox_FillColor_Selected(object sender, RoutedEventArgs e) { fillIndex = ComboBox_FillColor.SelectedIndex; fillColor = colors[fillIndex]; } 

    private void ComboBox_StrokeColor_Selected(object sender, RoutedEventArgs e) { strokeIndex = ComboBox_StrokeColor.SelectedIndex; strokeColor = colors[strokeIndex]; } 

    private void Canvas_MouseDown(object sender, MouseButtonEventArgs e) 
    { 
     path.Stroke = strokeColor; 
     path.StrokeThickness = strokeThickness; 
     path.Fill = fillColor; 
     path.HorizontalAlignment = HorizontalAlignment.Stretch; 
     path.VerticalAlignment = VerticalAlignment.Stretch; 
     path.Stretch = Stretch.None; 
     path.SetValue(Grid.ColumnProperty, 1); 

     _start = Mouse.GetPosition((UIElement)sender); 
     myCircle.Center = (Point)_start; 

     var sb = FindResource("anim") as Storyboard; 

     var x = sb.Children.First() as DoubleAnimation; 
     x.To = 2 * size; 
     x.Duration = new Duration(TimeSpan.FromSeconds(0.5)); 

     var y = sb.Children.ElementAt(1) as DoubleAnimation; 
     y.To = 2 * size; 
     y.Duration = new Duration(TimeSpan.FromSeconds(0.5)); 

     var z = sb.Children.Last() as DoubleAnimation; 
     z.From = 0.0; 
     z.To = 1.0; 
     z.Duration = new Duration(TimeSpan.FromSeconds(0.5)); 

     sb.Begin(path); 
    } 
    private void textBox_TextChanged(object sender, TextChangedEventArgs e) 
    { 
     //regex where any string of chars besides numbers 
     Regex pattern = new Regex(@"^([^0-9]*)$", RegexOptions.Compiled); 


     Match result = pattern.Match(textBox.Text); 
     if (textBox.Text.ToString() == string.Empty) 
      return; 
     else if (result.Success) 
     { 
      MessageBox.Show("Invalid character entered. Integer numbers only. Stroke Thickness will be reseted to a default of 1."); 
      strokeThickness = 1; 
      textBox.Text = strokeThickness.ToString(); 
      textBox.SelectAll(); 
     } 
     else 
     { 
      int x; 
      if (int.TryParse(textBox.Text, out x)) 
       strokeThickness = int.Parse(textBox.Text); 
     } 
    } 
    private void Slider_Size_PreviewMouseUp(object sender, MouseButtonEventArgs e) 
    { 
     parse(); 
    } 
    private void parse() 
    { 
     int x; 
     if (int.TryParse(tempSize.Content.ToString(), out x)) 
      size = x; 
    } 
} 

}

ответ

2

Так что вам не нужен эллипс, чтобы оставаться в пределах Canvas, но вы хотите отжать части, оставив их, не так ли? Просто установите ClipToBounds (из холста) на true (можно сделать в Xaml).

+0

Да. Ваше решение сработало, спасибо другу. –