Im trying to create a simple pan and zoom app using silverlight 4, but Im having trouble updating the TranslateTransform and ScaleTransform properties after I run an animation on them.
I have tried to set the FillBehaviour to Stop, with no success.
Here is the code that I have:
<Canvas x:Name="LayoutRoot" Background="White" Width="800" Height="600">
<Canvas x:Name="PanningCanvas" Height="600" Width="800">
<Canvas.RenderTransform>
<TransformGroup>
<ScaleTransform x:Name="CanvasScale"/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform x:Name="CanvasTransform"/>
</TransformGroup>
</Canvas.RenderTransform>
<Rectangle x:Name="MovingRect" Fill="#FF834040" Height="209" Canvas.Left="219" Stroke="#FF500505" Canvas.Top="220" Width="329" StrokeThickness="2"/>
</Canvas>
<Button Content="Animate" Width="107" Canvas.Left="38" Canvas.Top="46" ClickMode="Press" Click="Button_Click"/>
</Canvas>
And here is the C# behind it all (slightly abbreviated)
public partial class MainPage : UserControl
{
private ManipulationProcessor2D manipulationProcessor;
public MainPage()
{
InitializeComponent();
this.manipulationProcessor = new ManipulationProcessor2D(Manipulations2D.Translate | Manipulations2D.Scale);
this.manipulationProcessor.Delta += OnManipulationDelta;
Touch.FrameReported += OnCapturedTouchReported;
}
private void OnManipulationDelta(object sender, Manipulation2DDeltaEventArgs e)
{
float zoomVal = e.Delta.ScaleX;
Point pinchPoint = new Point(e.OriginX, e.OriginY);
float xTranslation = e.Delta.TranslationX;
float yTranslation = e.Delta.TranslationY;
if (zoomVal != 1.0)
{
Zoom(zoomVal, PanningCanvas.RenderTransform.Inverse.Transform(pinchPoint), pinchPoint, xTranslation, yTranslation, true);
}
else if (xTranslation != 0 || yTranslation != 0)
{
Translate(xTranslation, yTranslation);
}
}
public void Zoom(double zoom, Point pinchPosition, Point physicalPosition, float xTranslation, float yTranslation, bool isFinger)
{
if (isFinger)
{
CanvasScale.ScaleX = CanvasScale.ScaleX * zoom;
CanvasScale.ScaleY = CanvasScale.ScaleY * zoom;
CanvasTransform.X = -1 * (pinchPosition.X * CanvasScale.ScaleX - physicalPosition.X);
CanvasTransform.Y = -1 * (pinchPosition.Y * CanvasScale.ScaleY - physicalPosition.Y);
开发者_开发问答 }
else
{
CanvasScale.ScaleX = CanvasScale.ScaleX + zoom;
CanvasScale.ScaleY = CanvasScale.ScaleY + zoom;
}
}
private void Translate(float xTranslation, float yTranslation)
{
CanvasTransform.X += xTranslation;
CanvasTransform.Y += yTranslation;
}
private void OnCapturedTouchReported(object sender, TouchFrameEventArgs e)
{
//..removed..//
// process manipulations
this.manipulationProcessor.ProcessManipulators(DateTime.UtcNow.Ticks,manipulators);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
AnimatePosition(new Point(400, 300), 1);
AnimateScale(1.2, 1);
}
private Storyboard translateStoryboard = new Storyboard();
private Storyboard scaleStoryboard = new Storyboard();
public void AnimatePosition(Point destinationPoint, double lengthOfAnimation)
{
Point offset = new Point(destinationPoint.X, destinationPoint.Y);
var translationAnimationX = new DoubleAnimation() { SpeedRatio = 1, Duration = new Duration(TimeSpan.FromSeconds(lengthOfAnimation)), To = offset.X };
translateStoryboard.Children.Add(translationAnimationX);
Storyboard.SetTargetProperty(translationAnimationX, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)"));
var translationAnimationY = new DoubleAnimation() { SpeedRatio = 1, Duration = new Duration(TimeSpan.FromSeconds(lengthOfAnimation)), To = offset.Y };
translateStoryboard.Children.Add(translationAnimationY);
Storyboard.SetTargetProperty(translationAnimationY, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)"));
Storyboard.SetTarget(translateStoryboard, PanningCanvas);
translateStoryboard.Begin();
}
public void AnimateScale( double scale, double lengthOfAnimation)
{
var scaleAnimationX = new DoubleAnimation() { SpeedRatio = 1, Duration = new Duration(TimeSpan.FromSeconds(lengthOfAnimation)), To = scale };
scaleStoryboard.Children.Add(scaleAnimationX);
Storyboard.SetTargetProperty(scaleAnimationX, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"));
var scaleAnimationY = new DoubleAnimation() { SpeedRatio = 1, Duration = new Duration(TimeSpan.FromSeconds(lengthOfAnimation)), To = scale };
scaleStoryboard.Children.Add(scaleAnimationY);
Storyboard.SetTargetProperty(scaleAnimationY, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"));
Storyboard.SetTarget(scaleStoryboard, PanningCanvas);
scaleStoryboard.Begin();
}
}
The issue is that after I click the button, I cannot translate or zoom anymore...
please help!
Mark
Ok, so I got it working, but I dont know why.
Changing the animation to work like this:
Storyboard translateStoryboard = new Storyboard();
Point offset = new Point(destinationPoint.X, destinationPoint.Y);
var translationAnimationX = new DoubleAnimation() { SpeedRatio = 1, Duration = new Duration(TimeSpan.FromSeconds(lengthOfAnimation)), To = offset.X };
var translationAnimationY = new DoubleAnimation() { SpeedRatio = 1, Duration = new Duration(TimeSpan.FromSeconds(lengthOfAnimation)), To = offset.Y };
Storyboard.SetTargetProperty(translationAnimationX, new PropertyPath("X"));
Storyboard.SetTargetProperty(translationAnimationY, new PropertyPath("Y"));
Storyboard.SetTargetName(translationAnimationX, "CanvasTransform");
Storyboard.SetTargetName(translationAnimationY, "CanvasTransform");
translateStoryboard.Children.Add(translationAnimationX);
translateStoryboard.Children.Add(translationAnimationY);
translateStoryboard.Begin();
Did the trick, but I dont know why...
Can someone please explain it to me?
精彩评论