Ste*_*ald 12 windows-8 windows-runtime winrt-xaml
今天,我开始移植创建翻页样品在这里为Windows Phone 7到的WinRT(XAML,C#),以帮助这个问题张贴在堆栈溢出.但在移植过程中,我遇到了页面的剪辑部分.在Windows手机示例中,他们使用路径几何裁剪来剪切页面.但在WinRT中似乎只有矩形几何支持剪切选项.
如何在WinRT中实现类似路径几何剪裁的功能?
您可以从此处下载示例Windows电话代码
请找到我试过的源代码,请下载
在那里请找到类PageTurn.cs,我在下面用代码注释了代码:
void left_PointerEntered(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
//_workingOdd.Clip = _oddClipRegion;
//_workingEven.Clip = _evenClipRegion;
}
Run Code Online (Sandbox Code Playgroud)
Hee*_*til 12
希望这对你有所帮助.
以下是XAML,可以准确了解您链接到的演示的外观:
路径计算

此搜索
<Grid Background="Black">
<Grid Height="145" Width="210" >
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Border Margin="-3" BorderThickness="3" BorderBrush="White" Grid.ColumnSpan="2"></Border>
<Image Grid.Column="0" Source="Images/1.jpg"></Image>
<Image Grid.Column="1" Source="Images/2.jpg" ></Image>
<Image Grid.Column="1" HorizontalAlignment="Left" Source="Images/8.jpg" >
<Image.Clip>
<RectangleGeometry Rect="0,0,49,150"></RectangleGeometry>
</Image.Clip>
</Image>
<Path Grid.ColumnSpan="2" Data="M 180,0 L 153,145 L 85 120 L 160,-12" >
<Path.Fill>
<ImageBrush ImageSource="Images/4.jpg"/>
</Path.Fill>
</Path>
<!--polyline used for path image border-->
<Polyline Points="180,0,160,-11,85,120,153,145" Margin="0,-2,0,0" Stroke="White" StrokeThickness="3" Grid.ColumnSpan="2"/>
</Grid>
</Grid>
Run Code Online (Sandbox Code Playgroud)
镜像2
<Grid Background="Black">
<Grid Width="290" Height="180" >
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Border Grid.Column="0" BorderThickness="2,0,0,0" BorderBrush="White">
<Image Stretch="Fill" Source="Images/4.jpg"></Image>
</Border>
<Image Grid.Column="1" Source="Images/3.jpg" ></Image>
<Path Grid.ColumnSpan="2" Data="M 200,0 L 170,180 L 82.5 160 L 130 0 " >
<Path.Fill>
<ImageBrush ImageSource="Images/6.jpg"/>
</Path.Fill>
</Path>
<!--polyline used for path image border-->
<Polyline Points="130,0,82.5,160,170,180" Stroke="White" StrokeThickness="2" Grid.ColumnSpan="2"/>
</Grid>
</Grid>
Run Code Online (Sandbox Code Playgroud)
产量

您可以通过将image1和image2网格放在视图框中来放大图像的大小,如下所示
<Viewbox Width="500" Height="350">
<Grid Width="290" Height="180"/>
</Viewbox>
Run Code Online (Sandbox Code Playgroud)
所以,让我们清楚事情的状态.
现在我们了解这个问题.我们还有其他选择吗?
如果你想剪辑图像,你很幸运.您可以创建任何形状的路径元素,并使用图像画笔绘制背景.这在技术上并不是剪裁,但你有相同的效果.
<Path Data="M540,394 C544.208,422.053 538.553,441.447 514,466 C490.615,489.385
485.625,493.625 448,456 C423.947,431.947 425.435,394.188 486,374 C457.465,374
452,353.019 452,312 C452,280.568 446.005,289.33 478,268 C514.938,243.374
496.654,264 536,264 C538.338,275.69 546,280.948 546,294 C540.421,280.052
545.708,255.719 564,242 C577.778,231.667 594.285,223.858 610,216 C617.244,212.378
619.853,219.804 626,228 C630.353,233.805 671.625,322.65 620,302 C660.196,302
680,306.666 680,374 C680,393.824 652.592,424.592 614,386 C614,403.28
621.284,411.789 614,430 C607.693,445.768 601.833,454 580,454 C550.466,454
548.934,443.082 534,414" HorizontalAlignment="Left" Height="269.872"
Margin="433.483,215.058,0,0" Stretch="Fill" Stroke="Black" UseLayoutRounding="False"
VerticalAlignment="Top" Width="247.517">
<Path.Fill>
<ImageBrush Stretch="None" ImageSource="Assets/SplashScreen.png"/>
</Path.Fill>
</Path>
Run Code Online (Sandbox Code Playgroud)
这会使这个:

但等等还有更多.ImageBrush本身可以转换.这意味着您可以在路径中移动图像的图像上执行翻译.此外,您还可以在图像上应用旋转.
首先,考虑像FlipBoard那样的动画.这为您提供了一个简单的页面翻转动画,看起来非常棒,而不需要复杂的剪辑.看看这个演示:http://blog.jerrynixon.com/2012/12/walkthough-use-xamls-3d-planeprojection.html
然后,你可能只是想复制那个Demo.没关系.下面的XAML将为您提供您想要的效果.它很容易动画:
<Grid>
<Rectangle Stroke="Black" Width="800" Height="400">
<Rectangle.Fill>
<ImageBrush Stretch="UniformToFill" ImageSource="Assets/car.jpg"/>
</Rectangle.Fill>
</Rectangle>
<Grid Width="800" Height="400">
<Grid.Clip>
<RectangleGeometry Rect="0,-400,800,800" />
</Grid.Clip>
<Grid Width="800" Height="400" RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<CompositeTransform ScaleX="-1" Rotation="30.957" TranslateX="527" TranslateY="108"/>
</Grid.RenderTransform>
<Grid.Background>
<ImageBrush Stretch="UniformToFill" ImageSource="Assets/car.jpg"/>
</Grid.Background>
<Rectangle Fill="Purple" Opacity=".5" />
</Grid>
</Grid>
</Grid>
Run Code Online (Sandbox Code Playgroud)
它看起来像这样:
这是XAML,可以准确了解您链接到的演示的外观:
<Grid Width="800" Height="200" Margin="283,283,283,285">
<Grid.Clip>
<RectangleGeometry Rect="-200,-200,1000,400" />
</Grid.Clip>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="400" />
<ColumnDefinition Width="400" />
</Grid.ColumnDefinitions>
<Path x:Name="Page2" Grid.Column="1" Data="M0.5,0.5 L495,-1 L399.5,199.5 L0.5,199.5 z" Stretch="Fill" Margin="0,-1.5,-95.5,0" UseLayoutRounding="False" RenderTransformOrigin="0.5,0.5" >
<Path.RenderTransform>
<CompositeTransform TranslateX="-200"/>
</Path.RenderTransform>
<Path.Fill>
<ImageBrush Stretch="UniformToFill" ImageSource="Assets/Car2.jpg"/>
</Path.Fill>
</Path>
<Path x:Name="Page4" Data="M94,2 L495,-1 L495,201 L0.5,199.5 z" Stretch="Fill" Margin="400,-3.5,-495.5,0.5" UseLayoutRounding="False" RenderTransformOrigin="0.5,0.5" >
<Path.Fill>
<ImageBrush Stretch="UniformToFill" ImageSource="Assets/Car4.jpg"/>
</Path.Fill>
<Path.RenderTransform>
<CompositeTransform TranslateX="200"/>
</Path.RenderTransform>
</Path>
<Image x:Name="Page1" Source="Assets/Car1.jpg" Grid.Column="0" Stretch="UniformToFill" />
<Grid x:Name="Page3" Grid.Column="1" RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<CompositeTransform TranslateX="-156" Rotation="25" TranslateY="-94" ScaleX="1.1" ScaleY="1.1"/>
</Grid.RenderTransform>
<Grid.Clip>
<RectangleGeometry Rect="0,0,400,200" />
</Grid.Clip>
<Border BorderThickness="5,5,5,0" BorderBrush="White">
<Border.RenderTransform>
<CompositeTransform TranslateX="175"/>
</Border.RenderTransform>
<Image x:Name="Page3Image" Source="Assets/Car3.jpg" Stretch="UniformToFill"/>
</Border>
</Grid>
</Grid>
Run Code Online (Sandbox Code Playgroud)
看起来像这样:

斯蒂芬,我不确定这需要做多少调整才能做好.我的猜测是......很多.好消息是:你可以在GPU上进行动画转换,这样大部分都应该加速.:)
// 杰瑞
我给出了一个更完整的答案有点晚了,但我受到启发并开始研究可重复使用的控件/页面转换.目前的原型与工作相当不错RenderTransforms,并Clip Transforms为独立好看的动画支持.

我将研究WinRT XAML Toolkit的可重用控件,但同时您可以检查以下代码:
XAML
<Page
x:Class="FlipControls.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:FlipControls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid
x:Name="ManipulationGrid"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
ManipulationMode="TranslateX,TranslateY,TranslateInertia"
ManipulationStarted="ManipulationGrid_OnManipulationStarted"
ManipulationDelta="ManipulationGrid_OnManipulationDelta"
ManipulationCompleted="ManipulationGrid_OnManipulationCompleted">
<Grid
x:Name="Page1">
<Grid.Clip>
<RectangleGeometry
Rect="0,0,80000,80000">
<RectangleGeometry.Transform>
<TransformGroup>
<TranslateTransform
x:Name="Page1ClipTranslateTransform" />
<RotateTransform
x:Name="Page1ClipRotateTransform" />
</TransformGroup>
</RectangleGeometry.Transform>
</RectangleGeometry>
</Grid.Clip>
<Grid
x:Name="Page1ContentGrid">
<Image
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Stretch="UniformToFill"
Source="http://bigbackground.com/wp-content/uploads/2013/07/tropical-beach-screensaver.jpg" />
</Grid>
</Grid>
<Grid
x:Name="Page2"
Opacity="0">
<Grid.Clip>
<RectangleGeometry
Rect="0,0,80000,80000">
<RectangleGeometry.Transform>
<TransformGroup>
<TranslateTransform
x:Name="Page2ClipTranslateTransform" />
<RotateTransform
x:Name="Page2ClipRotateTransform" />
</TransformGroup>
</RectangleGeometry.Transform>
</RectangleGeometry>
</Grid.Clip>
<Grid
x:Name="Page2ContentGrid">
<Image
x:Name="Page2SampleContentImage"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Stretch="UniformToFill"
Source="http://www.photography-match.com/views/images/gallery/Tropical_Lagoon.jpg" />
</Grid>
</Grid>
<Grid
x:Name="TransitionGridContainer">
<Grid
x:Name="TransitionGrid"
Opacity="0">
<Grid.RenderTransform>
<CompositeTransform
x:Name="TransitionGridContainerTransform" />
</Grid.RenderTransform>
<Grid.Clip>
<RectangleGeometry
Rect="0,0,80000,80000">
<RectangleGeometry.Transform>
<TransformGroup>
<TranslateTransform
x:Name="TransitionGridClipTranslateTransform" />
<RotateTransform
x:Name="TransitionGridClipRotateTransform" />
</TransformGroup>
</RectangleGeometry.Transform>
</RectangleGeometry>
</Grid.Clip>
<Image
x:Name="TransitionImage"
Stretch="None" />
</Grid>
</Grid>
</Grid>
</Page>
Run Code Online (Sandbox Code Playgroud)
C#
using System;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media.Animation;
using Windows.UI.Xaml.Media.Imaging;
namespace FlipControls
{
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
PreloadTransitionGridContentAsync();
}
private async Task PreloadTransitionGridContentAsync()
{
#region Waiting for page 2 content to load
var bi = Page2SampleContentImage.Source as BitmapImage;
if (bi.PixelWidth == 0)
{
bi.ImageFailed += (s, e) => new MessageDialog("Need a different sample image.").ShowAsync();
bi.ImageOpened += (s, e) => PreloadTransitionGridContentAsync();
return;
}
if (Page2ContentGrid.ActualWidth == 0)
{
SizeChangedEventHandler sizeChangedEventHandler = null;
sizeChangedEventHandler = (s, e) =>
{
PreloadTransitionGridContentAsync();
Page2ContentGrid.SizeChanged -= sizeChangedEventHandler;
};
Page2ContentGrid.SizeChanged += sizeChangedEventHandler;
return;
}
#endregion
var rtb = new RenderTargetBitmap();
await rtb.RenderAsync(Page2ContentGrid);
TransitionImage.Source = rtb;
await Task.Delay(40000);
}
private bool isCancellationRequested;
private enum FlipDirections
{
Left,
Right
}
private FlipDirections flipDirection;
private Point manipulationStartPosition;
private double rotationCenterX;
private double rotationCenterY;
private void ManipulationGrid_OnManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e)
{
if (TransitionImage.Source == null)
{
CancelManipulation(e);
return;
}
manipulationStartPosition = e.Position;
if (Page1.Opacity == 1)
{
flipDirection = FlipDirections.Left;
Page2ClipTranslateTransform.X = ManipulationGrid.ActualWidth;
Page2.Opacity = 1;
TransitionGridClipTranslateTransform.X = -80000;
TransitionGridContainerTransform.TranslateX = ManipulationGrid.ActualWidth;
TransitionGrid.Opacity = .975;
}
else
{
if (manipulationStartPosition.X >= this.ManipulationGrid.ActualWidth / 2)
{
// Can't flip left since there is no page after the current one
CancelManipulation(e);
return;
}
flipDirection = FlipDirections.Right;
Page1.Opacity = 1;
}
}
private void ManipulationGrid_OnManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
if (this.isCancellationRequested)
{
return;
}
if (flipDirection == FlipDirections.Left)
{
var w = this.ManipulationGrid.ActualWidth;
var h = this.ManipulationGrid.ActualHeight;
var cx = Math.Min(0, Math.Max(e.Position.X - w, -w));
var cy = e.Cumulative.Translation.Y;
var angle = (Math.Atan2(cx + manipulationStartPosition.Y - w, -cy) * 180 / Math.PI + +90) % 360;
this.rotationCenterX = w + cx / 2;
if (cy < 0)
{
this.rotationCenterY = h;
}
else
{
this.rotationCenterY = 0;
}
Page2ClipTranslateTransform.X = w + cx / 2;
Page2ClipTranslateTransform.Y = -40000 + h / 2;
Page2ClipRotateTransform.CenterX = this.rotationCenterX;
Page2ClipRotateTransform.CenterY = this.rotationCenterY;
Page2ClipRotateTransform.Angle = angle;
TransitionGridClipTranslateTransform.X = -80000 - (cx / 2);
TransitionGridClipTranslateTransform.Y = -40000 + h / 2;
TransitionGridClipRotateTransform.CenterX = -cx / 2;
TransitionGridClipRotateTransform.CenterY = this.rotationCenterY;
TransitionGridClipRotateTransform.Angle = -angle;
TransitionGridContainerTransform.TranslateX = w + cx;
TransitionGridContainerTransform.CenterX = -cx / 2;
TransitionGridContainerTransform.CenterY = this.rotationCenterY;
TransitionGridContainerTransform.Rotation = 2 * angle;
}
}
private void ManipulationGrid_OnManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
if (this.isCancellationRequested)
{
this.isCancellationRequested = false;
return;
}
var w = this.ManipulationGrid.ActualWidth;
var h = this.ManipulationGrid.ActualHeight;
var sb = new Storyboard();
AddAnimation(sb, Page2ClipTranslateTransform, "X", w / 2);
AddAnimation(sb, Page2ClipRotateTransform, "CenterX", w / 2);
AddAnimation(sb, Page2ClipRotateTransform, "Angle", 0);
AddAnimation(sb, TransitionGridClipTranslateTransform, "X", -80000 + (w / 2));
AddAnimation(sb, TransitionGridClipRotateTransform, "CenterX", w / 2);
AddAnimation(sb, TransitionGridClipRotateTransform, "Angle", 0);
AddAnimation(sb, TransitionGridContainerTransform, "TranslateX", 0);
AddAnimation(sb, TransitionGridContainerTransform, "CenterX", w / 2);
AddAnimation(sb, TransitionGridContainerTransform, "Rotation", 0);
sb.Begin();
}
private static void AddAnimation(Storyboard sb, DependencyObject dob, string path, double to)
{
var da = new DoubleAnimation();
Storyboard.SetTarget(da, dob);
Storyboard.SetTargetProperty(da, path);
da.To = to;
da.Duration = TimeSpan.FromSeconds(.2);
sb.Children.Add(da);
}
private void CancelManipulation(ManipulationStartedRoutedEventArgs e)
{
this.isCancellationRequested = true;
e.Complete();
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2639 次 |
| 最近记录: |