Drag, drop and resize images on Canvas

前端 未结 1 1300
故里飘歌
故里飘歌 2021-01-16 18:49

I want to create a drag and drop interface in my Universal Windows App. Users will be able to drag and drop images from a ListView (or similar) to a Canva

1条回答
  •  执笔经年
    2021-01-16 19:12

    This is what I eventually went with:

    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Input;
    using Windows.UI.Xaml.Media;
    
    namespace KindEnGezin.Windows.Views.MenuItems
    {
        public sealed partial class DrawView : Page
        {
            public DrawView()
            {
                InitializeComponent();
            }
    
            private void Image_OnManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e)
            {
                ((Image)sender).Opacity = 0.4;
            }
    
            private void Image_OnManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
            {
                var image = (Image)sender;
                var transform = (CompositeTransform)image.RenderTransform;
    
                // LEFT-RIGHT bounds
                if (e.Delta.Translation.X < 0) // Going left
                {
                    if (DrawingArea.ActualWidth / 2 + (transform.TranslateX + e.Delta.Translation.X) - image.ActualWidth / 2 > 0)
                    {
                        // Staying inside, apply translation
                        transform.TranslateX += e.Delta.Translation.X;
                    }
                    else
                    {
                        // Trying to go outside, because scale sucks to work with, move image back inside
                        transform.TranslateX = image.ActualWidth / 2 - DrawingArea.ActualWidth / 2;
                    }
                }
                else // Going right
                {
                    if (DrawingArea.ActualWidth / 2 - (transform.TranslateX + e.Delta.Translation.X) +
                        image.ActualWidth * (0.5 - transform.ScaleX) > 0)
                    {
                        // Staying inside, apply translation
                        transform.TranslateX += e.Delta.Translation.X;
                    }
                    else
                    {
                        // Trying to go outside, because scale sucks to work with, move image back inside
                        transform.TranslateX = image.ActualWidth * (0.5 - transform.ScaleX) + DrawingArea.ActualWidth / 2;
                    }
                }
    
                // UP-DOWN bounds
                if (e.Delta.Translation.Y < 0) // Going up
                {
                    if (DrawingArea.ActualHeight / 2 + (transform.TranslateY + e.Delta.Translation.Y) - image.ActualHeight / 2 > 0)
                    {
                        // Staying inside, apply translation
                        transform.TranslateY += e.Delta.Translation.Y;
                    }
                    else
                    {
                        // Trying to go outside, because scale sucks to work with, move image back inside
                        transform.TranslateY = image.ActualHeight / 2 - DrawingArea.ActualHeight / 2;
                    }
                }
                else // Going down
                {
                    if (DrawingArea.ActualHeight / 2 - (transform.TranslateY + e.Delta.Translation.Y) +
                        image.ActualHeight * (0.5 - transform.ScaleY) > 0)
                    {
                        // Staying inside, apply translation
                        transform.TranslateY += e.Delta.Translation.Y;
                    }
                    else
                    {
                        // Trying to go outside, because scale sucks to work with, move image back inside
                        transform.TranslateY = image.ActualHeight * (0.5 - transform.ScaleY) + DrawingArea.ActualHeight / 2;
                    }
                }
    
            }
    
            // Only allow scaling when both dimensions are smaller than the drawingarea
            if (image.ActualHeight*(transform.ScaleY*e.Delta.Scale) < DrawingArea.ActualHeight &&
                image.ActualWidth*(transform.ScaleX*e.Delta.Scale) < DrawingArea.ActualWidth)
            {
                transform.ScaleX *= e.Delta.Scale;
                transform.ScaleY *= e.Delta.Scale;
            }
    
            private void Image_OnManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
            {
                ((Image)sender).Opacity = 1;
            }
        }
    }
    

    and the XAML:

    
        
            
                
            
        
    
    

    This is only using one static name, for the Grid that contains these images. Doing this allows one to add images dynamically to the Grid.

    I have been messing around with trying to block scaling the image when it goes outside of the bounds, but I had a lot of trouble trying to implement it, so I just move it to the boundary when I detect it's trying to move outside of the bounds.

    0 讨论(0)
提交回复
热议问题