I'm new to XAML and Windows 8. I would like to Animate an Image from off the screen to some X, Y value. I have successfully moved the image from its original position to a point using
var translate = new TranslateTransform();
translate.X = 400;
translate.Y = 400;
MyImage.RenderTransform = translate;
where MyImage is defined in the XAML.
However, I would like to use an linear easing animation so it slides from one point to another. I have seen the use of Storyboards in some examples but I'm not sure how to complete my task. Also, I want to set the point the image ends up at in code and not in XAML.
Any help would be appreciated.
<Page.Resources>
<Storyboard x:Name="Storyboard1">
<DoubleAnimationUsingKeyFrames x:Name="TranslateX" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="imageToAnimate">
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames x:Name="TranslateY" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="imageToAnimate">
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Page.Resources>
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Image x:Name="imageToAnimate" Source="/Assets/Logo.png" Width="150" Height="150" RenderTransformOrigin="0.5,0.5">
<Image.RenderTransform>
<CompositeTransform/>
</Image.RenderTransform></Image>
</Grid>
In code you can set the points to translate
EasingDoubleKeyFrame animateX1 = new EasingDoubleKeyFrame();
animateX1.KeyTime = new TimeSpan(0);
animateX1.Value = 1;
EasingDoubleKeyFrame animateX2 = new EasingDoubleKeyFrame();
animateX2.KeyTime = new TimeSpan(0, 0, 2);
animateX2.Value = 250;
EasingDoubleKeyFrame animateY1 = new EasingDoubleKeyFrame();
animateY1.KeyTime = new TimeSpan(0);
animateY1.Value = 1;
EasingDoubleKeyFrame animateY2 = new EasingDoubleKeyFrame();
animateY2.KeyTime = new TimeSpan(0, 0, 2);
animateY2.Value = 250;
TranslateX.KeyFrames.Add(animateX1);
TranslateX.KeyFrames.Add(animateX2);
TranslateY.KeyFrames.Add(animateY1);
TranslateY.KeyFrames.Add(animateY2);
Storyboard1.Begin();
Related
I have tried multiple things to rotate the Image, but it keeps ending up outside of the original bounds of the Grid (and even the Window!) that the unrotated Image takes up.
The XAML is straightforward
<Grid
x:Name="GridField">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
</Grid>
I can rotate the Image like this, but it goes out of bounds
var sourcePath = Path.GetFullPath(
Path.Combine(
Path.GetDirectoryName(Assembly.GetEntryAssembly().Location),
fileUrl
)
);
var file = await StorageFile.GetFileFromPathAsync(sourcePath);
using IRandomAccessStream fileStream = await file.OpenReadAsync();
BitmapImage bitmapImage = new();
bitmapImage.SetSource(fileStream);
var image = new Image();
image.Source = bitmapImage;
image.Rotation = 180;
Seeing this question
wpf rotate image around center
and this one
UWP - Rotating an Image while keeping it aligned to the grid, using XAML only
I tried this
var sourcePath = Path.GetFullPath(
Path.Combine(
Path.GetDirectoryName(Assembly.GetEntryAssembly().Location),
fileUrl
)
);
var file = await StorageFile.GetFileFromPathAsync(sourcePath);
using IRandomAccessStream fileStream = await file.OpenReadAsync();
BitmapImage bitmapImage = new();
bitmapImage.SetSource(fileStream);
var image = new Image();
image.Source = bitmapImage;
image.RenderTransformOrigin = new Point(0.5, 0.5);
image.Rotation = 180;
and I got a System.UnauthorizedAccessException.
I then tried to use a RotateTransform, but it makes the Image go out of bounds too!
var sourcePath = Path.GetFullPath(
Path.Combine(
Path.GetDirectoryName(Assembly.GetEntryAssembly().Location),
fileUrl
)
);
var file = await StorageFile.GetFileFromPathAsync(sourcePath);
using IRandomAccessStream fileStream = await file.OpenReadAsync();
BitmapImage bitmapImage = new();
bitmapImage.SetSource(fileStream);
var image = new Image();
image.Source = bitmapImage;
image.RenderTransformOrigin = new Point(0.5, 0.5);
RotateTransform rotateTransform = new RotateTransform()
{
CenterX = image.Width / 2,
CenterY = image.Height / 2,
Angle = 180
};
image.RenderTransform = rotateTransform;
How do I rotate around the center?
Well, no Exception here, and it works.
var sourcePath = Path.GetFullPath(
Path.Combine(
Path.GetDirectoryName(Assembly.GetEntryAssembly().Location),
fileUrl
)
);
var file = await StorageFile.GetFileFromPathAsync(sourcePath);
using IRandomAccessStream fileStream = await file.OpenReadAsync();
BitmapImage bitmapImage = new();
bitmapImage.SetSource(fileStream);
var image = new Image();
image.Source = bitmapImage;
image.RenderTransformOrigin = new Point(0.5, 0.5);
RotateTransform rotateTransform = new RotateTransform()
{
CenterX = image.Width / 2,
CenterY = image.Height / 2,
Angle = 180
};
image.RenderTransform = rotateTransform;
How can I set the size of the image inside of a list view. Currently I have several lists that have icons but I don't see any options for changing the aspect ratio or size of the image so it just gets blown up to the height of the list item.
all the images are from the Drawable folder
var cell = new DataTemplate(typeof(MenuTextCell));
cell.SetBinding(TextCell.TextProperty, "Title");
cell.SetBinding(ImageCell.ImageSourceProperty, "IconSource");
cell.SetValue(BackgroundColorProperty, Color.Transparent);
cell.SetValue(TextCell.TextColorProperty, Color.FromHex("262626"));
I am using a custom renderer
public class MenuTextCellRenderer : ImageCellRenderer
{
protected override View GetCellCore (Cell item, View convertView, ViewGroup parent, Context context)
{
var cell = (LinearLayout)base.GetCellCore (item, convertView, parent, context);
cell.SetPadding(20, 10, 0, 10);
cell.DividerPadding = 50;
var div = new ShapeDrawable();
div.SetIntrinsicHeight(1);
div.Paint.Set(new Paint { Color = Color.FromHex("b7b7b7").ToAndroid() });
if (parent is ListView)
{
((ListView)parent).Divider = div;
((ListView)parent).DividerHeight = 1;
}
var icon = (ImageView)cell.GetChildAt(0);
var label = (TextView)((LinearLayout)cell.GetChildAt(1)).GetChildAt(0);
label.SetTextColor(Color.FromHex("262626").ToAndroid());
label.TextSize = Font.SystemFontOfSize(NamedSize.Large).ToScaledPixel();
label.TextAlignment = TextAlignment.Center;
label.Text = label.Text.ToUpper();
var secondaryLabel = (TextView)((LinearLayout)cell.GetChildAt(1)).GetChildAt(1);
secondaryLabel.SetTextColor(Color.FromHex("262626").ToAndroid());
secondaryLabel.TextSize = Font.SystemFontOfSize(NamedSize.Large).ToScaledPixel();
label.TextAlignment = TextAlignment.Center;
return cell;
}
You are now dealing with an Android ImageView.
You have your reference via var icon = (ImageView)cell.GetChildAt(0).
You can now customize it via methods such as .setScaleType() for aspect ratio related, and use .layout() to change the position / size.
Try something like this on your ListView.ItemTemplate, instead of using the imagecell. You can also write your custom cell.
<DataTemplate>
<ViewCell>
<StackLayout VerticalOptions="FillAndExpand" Orientation="Horizontal" Padding="10">
<Image Aspect="AspectFill" HeightRequest ="20" WidthRequest="20" Source="{Binding IconSource}" />
<Label Text="{Binding Title}" YAlign="Center" Font="Medium" />
</StackLayout>
</ViewCell>
I have put an image in the scrollview and canvas as xaml below:
<ScrollViewer x:Name="scroll" HorizontalAlignment="Center" VerticalAlignment="Center" Width="340" Height="480">
<Canvas x:Name="canvas" HorizontalAlignment="Center" VerticalAlignment="Center" Width="340" Height="480" Background="Blue">
<Image x:Name="photo" Stretch="Fill" HorizontalAlignment="Center" VerticalAlignment="Center" ManipulationMode="All" Width="340" Height="480">
<Image.RenderTransform>
<CompositeTransform/>
</Image.RenderTransform>
</Image>
</Canvas>
</ScrollViewer>
After that, I created a button to load and crop the image:
private async void btnCrop_Click(object sender, RoutedEventArgs e)
{
FileOpenPicker fileOpenPicker = new FileOpenPicker();
fileOpenPicker.ViewMode = PickerViewMode.Thumbnail;
fileOpenPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
fileOpenPicker.FileTypeFilter.Add(".jpg");
fileOpenPicker.FileTypeFilter.Add(".jpeg");
fileOpenPicker.FileTypeFilter.Add(".png");
fileOpenPicker.FileTypeFilter.Add(".bmp");
file = await fileOpenPicker.PickSingleFileAsync();
if (file != null)
{
var fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(fileStream);
BitmapTransform transform = new BitmapTransform();
BitmapBounds bounds = new BitmapBounds();
bounds.X = bounds.Y = 0;
bounds.Height = bounds.Width = 150;
transform.Bounds = bounds;
PixelDataProvider pix = await decoder.GetPixelDataAsync(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, transform, ExifOrientationMode.RespectExifOrientation, ColorManagementMode.ColorManageToSRgb);
byte[] pixels = pix.DetachPixelData();
WriteableBitmap cropBmp = new WriteableBitmap(340, 480);
Stream pixStream = cropBmp.PixelBuffer.AsStream();
pixStream.Write(pixels, 0, 150 * 150 * 4);
photo.Source = cropBmp;
}
}
The image has been crop and displayed successful. But when I zoom my image, I just want crop the image within the canvas instead of hard code. The code above is hard code the BitmapBounds width and height. How do I solve it? Thanks
Please help me how to move the image as automatically to specific x y position by using of animation class in windows phone 7, i have tried by Point animation class but this is not working for image control but working for object, so please tell me what kind of animation class should i use for moving image in windows phone 7
and my code is
XAML
</PointAnimation>
</Storyboard>
</Canvas.Resources>
<Image Source="qq.jpg" Width="200" Height="100" x:Name="MyImage" Canvas.Left="10" Canvas.Top="10" />
</Canvas>
</Grid>
c#
private void canvas1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Point mypoint = new Point();
mypoint.X = 10;
mypoint.Y = 200;
MyPointAnimation.To = mypoint;
myStoryboard.Begin();
}
you can do something like that :
<Image x:Name="myImage"
Canvas.Left="10"
Canvas.Top="10"
Width="200"
Height="100"
Source="/Assets/qq.jpg">
<Image.RenderTransform>
<TranslateTransform />
</Image.RenderTransform>
</Image>
and then in code behind :
TranslateTransform trans = myImage.RenderTransform as TranslateTransform;
DoubleAnimation anima1 = new DoubleAnimation();
anima1.To = 150;
Storyboard.SetTarget(anima1, trans);
Storyboard.SetTargetProperty(anima1, new
PropertyPath(TranslateTransform.XProperty));
// Create storyboard, add animation, and fire it up!
Storyboard storyboard = new Storyboard();
storyboard.Children.Add(anima1);
storyboard.Begin();
I'm loading a Textbox and a Button into a horizontal StackPanel programmatically. The size of the button (which only contains an Image) is fixed, but I can't get the textbox to fill the available width of its parent. This is what the code looks like:
StackPanel parent = new StackPanel() {
Orientation = Orientation.Horizontal,
HorizontalAlignment = HorizontalAlignment.Stretch,
VerticalAlignment = VerticalAlignment.Top,
};
TextBox textbox = new TextBox() {
HorizontalAlignment = HorizontalAlignment.Stretch,
VerticalAlignment = VerticalAlignment.Top,
//MinWidth = 375,
};
Button btn = new Button() {
Content = new Image() {
MaxHeight = 40,
MaxWidth = 40,
MinHeight = 40,
MinWidth = 40,
Margin = new Thickness( 0 ),
Source = new BitmapImage(
new Uri( "btnimage.png", UriKind.Relative ) ),
},
HorizontalAlignment = HorizontalAlignment.Right,
BorderBrush = new SolidColorBrush( Colors.Transparent ),
Margin = new Thickness( 0 ),
};
btn.Click += ( ( s, e ) => OnBtnClicked( s, e, textbox ) );
parent.Children.Add( textbox );
parent.Children.Add( btn );
If I uncomment the MinWidth setting for the textbox it is displayed as I want it to, but I'd like to not have to specify a width explicitly. I tried adding a binding as follows but that doesn't work at all (the textbox just disappears!)
Binding widthBinding = new Binding() {
Source = parent.ActualWidth,
};
passwdBox.SetBinding( TextBox.WidthProperty, widthBinding );
Thanks for your help in advance!
Instead of using StackPanel (which always tries to keep elements as small as it can such that they all fit), use a Grid. Then you could do something like this:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/> <!-- Note "*" means to use the rest of the space -->
<ColumnDefinition Width="40"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0"/>
<Button Grid.Column="1">
<Button.Content>
<Image .../>
</Button.Content>
</Button>
</Grid>
You can convert this to code instead of XAML if you prefer, XAML's just easier to type here on-the-fly.
The right answer is don't do it. See my answer at this question and the same idea applies to Silverlight on Windows Phone.
In your example, you should be using a DockPanel.
<toolkit:DockPanel>
<Button toolkit:DockPanel.Dock="Right" />
<TextBox /> <!-- fill is implied -->
</toolkit:DockPanel>