Я пытаюсь изучить некоторые WPF, и я надеялся, что смогу реализовать простую игру. В этой игре есть несколько предметов на Canvas
. Для целей данного вопроса, скажем, есть только один, и что это Ellipse
:Как добиться плавного анимированного эффекта при перетаскивании объекта в WPF
<Canvas Name="canvas">
<Ellipse Name="ellipse" Width="100" Height="100" Stroke="Black" StrokeThickness="3" Fill="GreenYellow"/>
</Canvas>
Пользователь должен иметь возможность перетащить эти элементы вокруг произвольно.
Так я осуществил следующий код и он, кажется, работает:
public MainWindow()
{
InitializeComponent();
Canvas.SetLeft(ellipse, 0);
Canvas.SetTop(ellipse, 0);
ellipse.MouseDown += new MouseButtonEventHandler(ellipse_MouseDown);
ellipse.MouseMove += new MouseEventHandler(ellipse_MouseMove);
ellipse.MouseUp += new MouseButtonEventHandler(ellipse_MouseUp);
}
void ellipse_MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.LeftButton != MouseButtonState.Pressed)
return;
ellipse.CaptureMouse();
ellipse.RenderTransform = new ScaleTransform(1.25, 1.25, ellipse.Width/2, ellipse.Height/2);
ellipse.Opacity = 0.75;
}
void ellipse_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton != MouseButtonState.Pressed || !ellipse.IsMouseCaptured)
return;
var pos = e.GetPosition(canvas);
Canvas.SetLeft(ellipse, pos.X - ellipse.Width * 0.5);
Canvas.SetTop(ellipse, pos.Y - ellipse.Height * 0.5);
}
void ellipse_MouseUp(object sender, MouseButtonEventArgs e)
{
if (!ellipse.IsMouseCaptured)
return;
ellipse.ReleaseMouseCapture();
ellipse.RenderTransform = null;
ellipse.Opacity = 1;
}
Теперь, если вы попытаетесь это сделать, то вы увидите, что движения очень неровные. Когда вы нажимаете мыши, эллипс растет мгновенно и мгновенно меняет свою прозрачность. Я хочу сгладить это так, что есть никаких внезапных прыжков.
Я пробовал очевидные вещи, используя DoubleAnimation
на Ellipse.OpacityProperty
, ScaleTransform.ScaleXProperty
и (особенно) Canvas.LeftProperty/TopProperty
. Тем не менее, я бегу на следующие проблемы:
Как только я начинаю анимацию на
Canvas.LeftProperty/TopProperty
, я никогда не смогу использоватьCanvas.SetLeft/Top
снова, так что эллипс не перемещается при его перетаскивании. Я не мог найти способ удалить анимацию из объекта.Если пользователь освобождает мышь, пока анимация все еще происходит, анимация «сжатия» на
ScaleTransform
начинается с полного размера до достижения «растущей» анимации, что вызывает внезапный скачок. Если вы нажмете мышью отчаянно, размер объекта скачет отчаянно, чего не следует.
Если вам нужно, вы можете look at my failed code, which doesn’t work.
Как вы правильно реализуете эти гладкие движения в WPF?
Пожалуйста, не публикуйте ответ, не опробовав его в первую очередь. Если есть какие-либо неожиданные прыжки, результат неудовлетворительный. Благодаря!
Большое спасибо, лучший ответ до сих пор ... однако вы избежали проблемы центрирования объекта с помощью вместо того, чтобы фактически решить его. Вопрос все еще стоит: как мне вернуть 'Canvas.SetLeft' в нормальную работу после анимации на' Canvas.LeftProperty'? Я подозреваю, что такая же проблема возникает с «scale.ScaleX» в вашем решении ... – Timwi
@Timwi: Зачем решать проблемы, когда их можно избежать? :) Получение Canvas.SetLeft обратно в нормальное состояние легко, но если вы сделаете это легко, тогда вы получите прыжок, когда вы сначала двигаете мышью. Я обновил свой ответ с идеей получить гладкое центрирование. – Quartermeister
@Timwi: 'scale.ScaleX' отлично, потому что я никогда не устанавливал его напрямую, я просто продолжаю менять анимацию. – Quartermeister