您的位置:首页 > 其它

winrt 上的翻书特效组件 源码分享 转载请说明

2013-08-23 19:46 260 查看
[TemplatePart(Name = A_PARTNAME, Type = typeof(Border))]
[TemplatePart(Name = B_PARTNAME, Type = typeof(Border))]
[TemplatePart(Name = C_PARTNAME, Type = typeof(Border))]
[TemplatePart(Name = D_PARTNAME, Type = typeof(Border))]
[TemplatePart(Name = E_PARTNAME, Type = typeof(Border))]
[TemplatePart(Name = F_PARTNAME, Type = typeof(Border))]
[TemplatePart(Name = A_RECT_PARTNAME, Type = typeof(RectangleGeometry))]
[TemplatePart(Name = B_RECT_PARTNAME, Type = typeof(RectangleGeometry))]
[TemplatePart(Name = C_RECT_PARTNAME, Type = typeof(RectangleGeometry))]
[TemplatePart(Name = D_RECT_PARTNAME, Type = typeof(RectangleGeometry))]
[TemplatePart(Name = E_RECT_PARTNAME, Type = typeof(RectangleGeometry))]
[TemplatePart(Name = F_RECT_PARTNAME, Type = typeof(RectangleGeometry))]
[TemplatePart(Name = A_TRANS_PARTNAME, Type = typeof(CompositeTransform))]
[TemplatePart(Name = B_TRANS_PARTNAME, Type = typeof(CompositeTransform))]
[TemplatePart(Name = C_TRANS_PARTNAME, Type = typeof(CompositeTransform))]
[TemplatePart(Name = D_TRANS_PARTNAME, Type = typeof(CompositeTransform))]
[TemplatePart(Name = E_TRANS_PARTNAME, Type = typeof(CompositeTransform))]
[TemplatePart(Name = F_TRANS_PARTNAME, Type = typeof(CompositeTransform))]
[TemplatePart(Name = A_PRESENTER_PARTNAME, Type = typeof(ContentPresenter))]
[TemplatePart(Name = B_PRESENTER_PARTNAME, Type = typeof(ContentPresenter))]
[TemplatePart(Name = C_PRESENTER_PARTNAME, Type = typeof(ContentPresenter))]
[TemplatePart(Name = D_PRESENTER_PARTNAME, Type = typeof(ContentPresenter))]
[TemplatePart(Name = E_PRESENTER_PARTNAME, Type = typeof(ContentPresenter))]
[TemplatePart(Name = F_PRESENTER_PARTNAME, Type = typeof(ContentPresenter))]
[TemplatePart(Name = INNER_LEFT_TRANS_PARTNAME, Type = typeof(CompositeTransform))]
[TemplatePart(Name = OUTER_LEFT_TRANS_PARTNAME, Type = typeof(CompositeTransform))]
[TemplatePart(Name = INNER_RIGHT_TRANS_PARTNAME, Type = typeof(CompositeTransform))]
[TemplatePart(Name = OUTER_RIGHT_TRANS_PARTNAME, Type = typeof(CompositeTransform))]
[TemplatePart(Name = MARGIN_LEFT_TRANS_PARTNAME, Type = typeof(CompositeTransform))]
[TemplatePart(Name = MARGIN_RIGHT_TRANS_PARTNAME, Type = typeof(CompositeTransform))]
[TemplatePart(Name = ST_SHADOW_SPLIT_INNER_LEFT_PARTNAME, Type = typeof(StackPanel))]
[TemplatePart(Name = ST_SHADOW_SPLIT_OUTER_LEFT_PARTNAME, Type = typeof(StackPanel))]
[TemplatePart(Name = ST_SHADOW_SPLIT_INNER_RIGHT_PARTNAME, Type = typeof(StackPanel))]
[TemplatePart(Name = ST_SHADOW_SPLIT_OUTER_RIGHT_PARTNAME, Type = typeof(StackPanel))]
[TemplatePart(Name = ST_SHADOW_MARGIN_LEFT_PARTNAME, Type = typeof(StackPanel))]
[TemplatePart(Name = ST_SHADOW_MARGIN_RIGHT_PARTNAME, Type = typeof(StackPanel))]
[TemplatePart(Name = BOOK_CONTAINER_PARTNAME, Type = typeof(Image))]
[TemplatePart(Name = GRD_CONTENT_PARTNAME, Type = typeof(Grid))]
/// <summary>
/// 作者:王韧竹
/// 版本:1.1
/// 根据偏移量算法 计算是否为放大 或者翻页 保证两者不冲突。
/// 18/6/2013 23:06
/// windows8 翻书特效组件
/// </summary>
public sealed class FlipBookControl : ItemsControl
{
#region Member Variables
/// <summary>
/// 0 初始 翻页状态1 翻页状态2
/// </summary>
private int Status = 0;
/// <summary>
/// 是否翻下一页
/// true 下一页 false 上一页
/// </summary>
private bool isNext = false;
/// <summary>
/// 触发向左翻页动画
/// true 发生偏移  false 停止偏移
/// </summary>
private bool turnLeft = false;
/// <summary>
/// 触发向右翻页动画
/// true 发生偏移  false 停止偏移
/// </summary>
private bool turnRight = false;
/// <summary>
/// 触发向右翻页还原动画
/// true 发生偏移  false 停止偏移
/// </summary>
private bool rightRestore = false;
/// <summary>
/// 触发向左翻页还原动画
/// true 发生偏移  false 停止偏移
/// </summary>
private bool leftRestore = false;
/// <summary>
/// 是否多点操作中
/// true 是 false 否
/// </summary>
private bool isManipulating = false;
/// <summary>
/// 最近一次偏移量
/// </summary>
private double lastDeltaOffset = 0.0;
/// <summary>
/// 横向偏移量
/// </summary>
private double offsetWidth = 0.0;
/// <summary>
/// 竖向偏移量
/// </summary>
private double offsetHeight = 0.0;
/// <summary>
/// 是否加载
/// </summary>
private bool isLoaded = false;
/// <summary>
/// 是否初始化
/// </summary>
private bool isInit = false;

/// <summary>
/// 控制是否翻页
/// </summary>
private bool isFlip = true;

/// <summary>
/// 是否释放
/// </summary>
private bool isRelease = true;
Border nextPage;
Border prevPage;
Border leftPage;
Border rightPage;
Border leftTopPage;
Border rightTopPage;
CompositeTransform nextTrans;
CompositeTransform prevTrans;
Border A;
Border B;
Border C;
Border D;
Border E;
Border F;
ContentPresenter APresenter;
ContentPresenter BPresenter;
ContentPresenter CPresenter;
ContentPresenter DPresenter;
ContentPresenter EPresenter;
ContentPresenter FPresenter;
RectangleGeometry ARect;
RectangleGeometry BRect;
RectangleGeometry CRect;
RectangleGeometry DRect;
RectangleGeometry ERect;
RectangleGeometry FRect;
CompositeTransform transA;
CompositeTransform transB;
CompositeTransform transC;
CompositeTransform transD;
CompositeTransform transE;
CompositeTransform transF;
CompositeTransform innerLeftTrans;
CompositeTransform outerLeftTrans;
CompositeTransform innerRightTrans;
CompositeTransform outerRightTrans;
CompositeTransform marginLeftTrans;
CompositeTransform marginRightTrans;
StackPanel stShadowSplitOuterLeft;
StackPanel stShadowSplitInnerLeft;
StackPanel stShadowSplitOuterRight;
StackPanel stShadowSplitInnerRight;
StackPanel stShadowMarginLeft;
StackPanel stShadowMarginRight;
Grid grdContent;
Image bookContainer;
ImageBrush leftBrush;
ImageBrush rightBrush;
private TransformGroup _transformGroup;
private MatrixTransform _previousTransform;
private CompositeTransform _compositeTransform;
#endregion

#region Template Part
/// <summary>
/// 矩形
/// </summary>
const string A_PARTNAME = "A";
/// <summary>
/// 矩形遮掩
/// </summary>
const string A_RECT_PARTNAME = "ARect";
/// <summary>
/// 矩形偏移
/// </summary>
const string A_TRANS_PARTNAME = "transA";
const string A_PRESENTER_PARTNAME = "APresenter";
const string B_PARTNAME = "B";
const string B_RECT_PARTNAME = "BRect";
const string B_TRANS_PARTNAME = "transB";
const string B_PRESENTER_PARTNAME = "BPresenter";
const string C_PARTNAME = "C";
const string C_RECT_PARTNAME = "CRect";
const string C_TRANS_PARTNAME = "transC";
const string C_PRESENTER_PARTNAME = "CPresenter";
const string D_PARTNAME = "D";
const string D_RECT_PARTNAME = "DRect";
const string D_TRANS_PARTNAME = "transD";
const string D_PRESENTER_PARTNAME = "DPresenter";
const string E_PARTNAME = "E";
const string E_RECT_PARTNAME = "ERect";
const string E_TRANS_PARTNAME = "transE";
const string E_PRESENTER_PARTNAME = "EPresenter";
const string F_PARTNAME = "F";
const string F_RECT_PARTNAME = "FRect";
const string F_TRANS_PARTNAME = "transF";
const string F_PRESENTER_PARTNAME = "FPresenter";
const string ST_SHADOW_SPLIT_OUTER_RIGHT_PARTNAME = "stShadowSplitOuterRight";
const string ST_SHADOW_SPLIT_INNER_RIGHT_PARTNAME = "stShadowSplitInnerRight";
const string ST_SHADOW_SPLIT_OUTER_LEFT_PARTNAME = "stShadowSplitOuterLeft";
const string ST_SHADOW_SPLIT_INNER_LEFT_PARTNAME = "stShadowSplitInnerLeft";
const string ST_SHADOW_MARGIN_LEFT_PARTNAME = "stShadowMarginLeft";
const string ST_SHADOW_MARGIN_RIGHT_PARTNAME = "stShadowMarginRight";
const string OUTER_LEFT_TRANS_PARTNAME = "outerLeftTrans";
const string INNER_LEFT_TRANS_PARTNAME = "innerLeftTrans";
const string OUTER_RIGHT_TRANS_PARTNAME = "outerRightTrans";
const string INNER_RIGHT_TRANS_PARTNAME = "innerRightTrans";
const string MARGIN_LEFT_TRANS_PARTNAME = "marginLeftTrans";
const string MARGIN_RIGHT_TRANS_PARTNAME = "marginRightTrans";
/// <summary>
/// 书壳
/// </summary>
const string BOOK_CONTAINER_PARTNAME = "bookContainer";
const string GRD_CONTENT_PARTNAME = "grdContent";
#endregion

#region DependencyProperties
#region DelayLoad
public TimeSpan DelayLoad
{
get { return (TimeSpan)GetValue(DelayLoadProperty); }
set { SetValue(DelayLoadProperty, value); }
}

// Using a DependencyProperty as the backing store for DelayLoad.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty DelayLoadProperty =
DependencyProperty.Register("DelayLoad", typeof(TimeSpan), typeof(FlipBookControl), new PropertyMetadata(TimeSpan.FromSeconds(0)));
#endregion

#region BookBackgroundBrush
public ImageBrush BookBackgroundBrush
{
get { return (ImageBrush)GetValue(BookBackgroundBrushProperty); }
set { SetValue(BookBackgroundBrushProperty, value); }
}

// Using a DependencyProperty as the backing store for BookBackgroundBrush.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty BookBackgroundBrushProperty =
DependencyProperty.Register("BookBackgroundBrush", typeof(ImageBrush), typeof(FlipBookControl), new PropertyMetadata(null, OnBookBackgroundBrushChangedCallBack));

private static async void OnBookBackgroundBrushChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
{

var ctrl = (d as FlipBookControl);
if (ctrl.isLoaded)
await ctrl.GetCropBrush();
}
#endregion

#region Speed
/// <summary>
/// 动画速度 默认为30pixel
/// </summary>
public int Speed
{
get { return (int)GetValue(SpeedProperty); }
set { SetValue(SpeedProperty, value); }
}

// Using a DependencyProperty as the backing store for Speed.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty SpeedProperty =
DependencyProperty.Register("Speed", typeof(int), typeof(FlipBookControl), new PropertyMetadata(30));
#endregion

#region BookContainerSource
public ImageSource BookContainerSource
{
get { return (ImageSource)GetValue(BookContainerSourceProperty); }
set { SetValue(BookContainerSourceProperty, value); }
}

// Using a DependencyProperty as the backing store for BookContainerSource.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty BookContainerSourceProperty =
DependencyProperty.Register("BookContainerSource", typeof(ImageSource), typeof(FlipBookControl), new PropertyMetadata(null, OnBookContainerSourceChangedCallBack));

private static void OnBookContainerSourceChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctrl = (d as FlipBookControl);
if (null != ctrl.BookContainerSource && ctrl.bookContainer != null && ctrl.isLoaded)
ctrl.bookContainer.Source = ctrl.BookContainerSource;
}

#endregion

#region PageIndex
public int PageIndex
{
get { return (int)GetValue(PageIndexProperty); }
set { SetValue(PageIndexProperty, value); }
}

// Using a DependencyProperty as the backing store for PageIndex.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty PageIndexProperty =
DependencyProperty.Register("PageIndex", typeof(int), typeof(FlipBookControl), new PropertyMetadata(0, OnPageIndexChangedCallBack));

private static void OnPageIndexChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctrl = (d as FlipBookControl);
if (ctrl.isLoaded)
{
var isNext = Convert.ToInt32(e.NewValue) > Convert.ToInt32(e.OldValue);
var presenters = ctrl.GetPresentersByPageIndex(isNext);
if (null != presenters)
ctrl.LoadPageContentByPageIndex(Convert.ToInt32(e.NewValue), isNext, presenters[0], presenters[1]);
}
}
#endregion

#region DisposeAction
public Action<object> DisposeAction
{
get { return (Action<object>)GetValue(DisposeActionProperty); }
set { SetValue(DisposeActionProperty, value); }
}

// Using a DependencyProperty as the backing store for DisposeAction.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty DisposeActionProperty =
DependencyProperty.Register("DisposeAction", typeof(Action<object>), typeof(FlipBookControl), new PropertyMetadata(null));
#endregion

#region RestoreItemAction
public Action<object> RestoreItemAction
{
get { return (Action<object>)GetValue(RestoreItemActionProperty); }
set { SetValue(RestoreItemActionProperty, value); }
}

// Using a DependencyProperty as the backing store for RestoreItemAction.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty RestoreItemActionProperty =
DependencyProperty.Register("RestoreItemAction", typeof(Action<object>), typeof(FlipBookControl), new PropertyMetadata(null));
#endregion

#region CanScale
public bool CanScale
{
get { return (bool)GetValue(CanScaleProperty); }
set { SetValue(CanScaleProperty, value); }
}

// 能否进行放大缩小
public static readonly DependencyProperty CanScaleProperty =
DependencyProperty.Register("CanScale", typeof(bool), typeof(FlipBookControl), new PropertyMetadata(false));
#endregion
#endregion

#region Event
/// <summary>
/// 翻书结束事件
/// </summary>
private delegate void Fliped(object sender, FlipEventArgs args);

private event Fliped Fliping;
/// <summary>
/// 加载事件
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
public delegate void NeedLoadItems(object sender, FlipLoadArgs args);

public event NeedLoadItems NeedLoadingItem;
#endregion

#region Constructor
public FlipBookControl()
{
this.DefaultStyleKey = typeof(FlipBookControl);
this.Loaded += FlipBookControlLoaded;
this.Unloaded += FlipBookControlUnLoaded;
CompositionTarget.Rendering += RenderAnimation;
this.Fliping += FlipEnded;
}

/// <summary>
/// 初始化完毕开始载入数据
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void FlipBookControlLoaded(object sender, RoutedEventArgs e)
{
grdContent.ManipulationMode =
ManipulationModes.TranslateInertia |
ManipulationModes.TranslateX |
ManipulationModes.Scale |
ManipulationModes.ScaleInertia |
ManipulationModes.TranslateY;
grdContent.ManipulationDelta += FlipManipulationDelta;
grdContent.ManipulationCompleted += FlipManipulationCompleted;
grdContent.ManipulationStarting += FlipManipulationStarting;
grdContent.ManipulationInertiaStarting += FlipManipulationInertiaStarting;
A.PointerPressed += PointerPressed;
B.PointerPressed += PointerPressed;
C.PointerPressed += PointerPressed;
D.PointerPressed += PointerPressed;
E.PointerPressed += PointerPressed;
F.PointerPressed += PointerPressed;
offsetWidth = A.ActualWidth;
offsetHeight = A.ActualHeight;
await GetCropBrush();
bookContainer.Source = BookContainerSource;
RefreshPageByStatus();
InitPages();
isLoaded = true;
}

private void FlipBookControlUnLoaded(object sender, RoutedEventArgs e)
{
CompositionTarget.Rendering -= RenderAnimation;
grdContent.ManipulationDelta -= FlipManipulationDelta;
grdContent.ManipulationCompleted -= FlipManipulationCompleted;
grdContent.ManipulationStarting -= FlipManipulationStarting;
grdContent.ManipulationInertiaStarting -= FlipManipulationInertiaStarting;
this.Fliping -= FlipEnded;
A.PointerPressed -= PointerPressed;
B.PointerPressed -= PointerPressed;
C.PointerPressed -= PointerPressed;
D.PointerPressed -= PointerPressed;
E.PointerPressed -= PointerPressed;
F.PointerPressed -= PointerPressed;
}

public void InitPosition()
{
_compositeTransform = new CompositeTransform();
_previousTransform = new MatrixTransform() { Matrix = Matrix.Identity };
_transformGroup = new TransformGroup();
_transformGroup.Children.Add(_previousTransform);
_transformGroup.Children.Add(_compositeTransform);
this.RenderTransform = _transformGroup;
}

public async void InitPages()
{
if (!isInit && PageIndex == 0 && this.Items.Count > 0)
{
await Task.Delay(DelayLoad);
List<object> needLoadItems = new List<object>();
//第一次加载 载入4页
CPresenter.DataContext = this.Items[0];
needLoadItems.Add(Items[0]);
if (this.Items.Count > 1)
{
DPresenter.DataContext = this.Items[1];
needLoadItems.Add(Items[1]);
}
if (this.Items.Count > 2)
{
EPresenter.DataContext = this.Items[2];
needLoadItems.Add(Items[2]);
}
if (this.Items.Count > 3)
{
FPresenter.DataContext = this.Items[3];
needLoadItems.Add(Items[3]);
}
if (null != NeedLoadingItem)
NeedLoadingItem(this, new FlipLoadArgs(needLoadItems, false));
isInit = true;
}
else
{
Status = 0;
this.PageIndex = 0;
if (null != APresenter)
{
APresenter.DataContext = null;
BPresenter.DataContext = null;
CPresenter.DataContext = null;
DPresenter.DataContext = null;
EPresenter.DataContext = null;
FPresenter.DataContext = null;
}
}
InitPosition();
}
#endregion

#region EventMethod
#region OnApplyTemplate
protected override void OnApplyTemplate()
{
bookContainer = GetTemplateChild(BOOK_CONTAINER_PARTNAME) as Image;
A = GetTemplateChild(A_PARTNAME) as Border;
B = GetTemplateChild(B_PARTNAME) as Border;
C = GetTemplateChild(C_PARTNAME) as Border;
D = GetTemplateChild(D_PARTNAME) as Border;
E = GetTemplateChild(E_PARTNAME) as Border;
F = GetTemplateChild(F_PARTNAME) as Border;
APresenter = GetTemplateChild(A_PRESENTER_PARTNAME) as ContentPresenter;
BPresenter = GetTemplateChild(B_PRESENTER_PARTNAME) as ContentPresenter;
CPresenter = GetTemplateChild(C_PRESENTER_PARTNAME) as ContentPresenter;
DPresenter = GetTemplateChild(D_PRESENTER_PARTNAME) as ContentPresenter;
EPresenter = GetTemplateChild(E_PRESENTER_PARTNAME) as ContentPresenter;
FPresenter = GetTemplateChild(F_PRESENTER_PARTNAME) as ContentPresenter;
ARect = GetTemplateChild(A_RECT_PARTNAME) as RectangleGeometry;
BRect = GetTemplateChild(B_RECT_PARTNAME) as RectangleGeometry;
CRect = GetTemplateChild(C_RECT_PARTNAME) as RectangleGeometry;
DRect = GetTemplateChild(D_RECT_PARTNAME) as RectangleGeometry;
ERect = GetTemplateChild(E_RECT_PARTNAME) as RectangleGeometry;
FRect = GetTemplateChild(F_RECT_PARTNAME) as RectangleGeometry;
transA = GetTemplateChild(A_TRANS_PARTNAME) as CompositeTransform;
transB = GetTemplateChild(B_TRANS_PARTNAME) as CompositeTransform;
transC = GetTemplateChild(C_TRANS_PARTNAME) as CompositeTransform;
transD = GetTemplateChild(D_TRANS_PARTNAME) as CompositeTransform;
transE = GetTemplateChild(E_TRANS_PARTNAME) as CompositeTransform;
transF = GetTemplateChild(F_TRANS_PARTNAME) as CompositeTransform;
grdContent = GetTemplateChild(GRD_CONTENT_PARTNAME) as Grid;
innerLeftTrans = GetTemplateChild(INNER_LEFT_TRANS_PARTNAME) as CompositeTransform;
outerLeftTrans = GetTemplateChild(OUTER_LEFT_TRANS_PARTNAME) as CompositeTransform;
innerRightTrans = GetTemplateChild(INNER_RIGHT_TRANS_PARTNAME) as CompositeTransform;
outerRightTrans = GetTemplateChild(OUTER_RIGHT_TRANS_PARTNAME) as CompositeTransform;
marginLeftTrans = GetTemplateChild(MARGIN_LEFT_TRANS_PARTNAME) as CompositeTransform;
marginRightTrans = GetTemplateChild(MARGIN_RIGHT_TRANS_PARTNAME) as CompositeTransform;
stShadowSplitInnerLeft = GetTemplateChild(ST_SHADOW_SPLIT_INNER_LEFT_PARTNAME) as StackPanel;
stShadowSplitOuterLeft = GetTemplateChild(ST_SHADOW_SPLIT_OUTER_LEFT_PARTNAME) as StackPanel;
stShadowSplitInnerRight = GetTemplateChild(ST_SHADOW_SPLIT_INNER_RIGHT_PARTNAME) as StackPanel;
stShadowSplitOuterRight = GetTemplateChild(ST_SHADOW_SPLIT_OUTER_RIGHT_PARTNAME) as StackPanel;
stShadowMarginLeft = GetTemplateChild(ST_SHADOW_MARGIN_LEFT_PARTNAME) as StackPanel;
stShadowMarginRight = GetTemplateChild(ST_SHADOW_MARGIN_RIGHT_PARTNAME) as StackPanel;
base.OnApplyTemplate();
}
#endregion

#region PointerPressed
/// <summary>
/// 确定翻页方向
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void PointerPressed(object sender, PointerRoutedEventArgs e)
{
if (!isManipulating)
{
if (sender.Equals(leftPage))
isNext = false;
else if (sender.Equals(rightPage))
isNext = true;
else
RefreshPageByStatus();
Debug.WriteLine("按下:" + isNext);
Debug.WriteLine("点击的壳:" + (sender as Border).Name + " 左页壳:" + (sender as Border).Name);
}
}
#endregion

#region OnPointerReleased
protected override void OnPointerReleased(PointerRoutedEventArgs e)
{
base.OnPointerReleased(e);
}
#endregion

#region FlipEnded
/// <summary>
/// 翻页完毕
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
private async void FlipEnded(object sender, FlipEventArgs args)
{
Debug.WriteLine("翻页完毕:" + args.isNext);
if (args.isNext) PageIndex += 2;
else PageIndex -= 2;
await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, () =>
RefreshPageByStatus());
}
#endregion

#region Manipulation  多点触控操作翻书特效
#region FlipManipulationStarting
private void FlipManipulationStarting(object sender, ManipulationStartingRoutedEventArgs e)
{
isManipulating = true;
e.Handled = true;
if (isNext)
{
if (PageIndex >= this.Items.Count - 2)
{
isFlip = false;
isManipulating = false;
}
}
else
{
if (this.PageIndex == 0)
{
isFlip = false;
isManipulating = false;
}
}
}
#endregion

#region FlipManipulationInertiaStarting
private void FlipManipulationInertiaStarting(object sender, ManipulationInertiaStartingRoutedEventArgs e)
{
e.TranslationBehavior.DesiredDeceleration = 5 * 96.0 / (1000.0 * 1000.0);
e.ExpansionBehavior.DesiredDeceleration = 100 * 96 / 1000.0 * 1000.0;
}
#endregion

#region FlipManipulationCompleted
private async void FlipManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
isManipulating = false;
if (isFlip)
{
IsHitVisible(false);
var leftTopOffset = leftTopPage.Clip.Rect.X;
var rightTopOffset = rightTopPage.Clip.Rect.X;
await Task.Run(() =>
{
if (isNext)
{
if (lastDeltaOffset < 0)
{
Status = Status < 2 ? Status + 1 : 0;
turnRight = true;
}
else if (rightTopOffset != 0.0)
rightRestore = true;
else IsHitVisible(true);
Debug.WriteLine("下一页:" + turnRight);
}
else
{
if (lastDeltaOffset > 0)
{
Status = Status > 0 ? Status - 1 : 2;
turnLeft = true;
}
else if (leftTopOffset != 0.0)
leftRestore = true;
else IsHitVisible(true);
Debug.WriteLine("上一页" + turnLeft);
}
});

Debug.WriteLine("翻页状态:" + Status);
}
isFlip = true;
CanScale = false;
}
#endregion

#region FlipManipulationDelta
private void FlipManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
var scale = e.Delta.Scale;
var translateX = e.Delta.Translation.X;
var translateY = e.Delta.Translation.Y;
var nTtranX = nextTrans.TranslateX;
var nTtranY = nextTrans.TranslateY;
var ctranlateX = e.Cumulative.Translation.X;
var ctranlateY = e.Cumulative.Translation.Y;
CanScale = Task.Run(() =>
{
if (scale != 1.0 || (Math.Abs(ctranlateX * 1.15) < Math.Abs(ctranlateY))) return true;
else return false;
}).Result;
if (isManipulating && !CanScale)
{
if (isNext)
{
#region 下一页
var rightTopNect = rightTopPage.Clip.Rect;
var nextRect = nextPage.Clip.Rect;
var nextTransOffset = nTtranX + translateX * 2;

SetShadowOperacity(Math.Abs(nextTransOffset), offsetWidth, false);
var nextRectXOffset = nextRect.X - e.Delta.Translation.X;
lastDeltaOffset = e.Delta.Translation.X;
if (nextRectXOffset < 0 && nextRectXOffset > -offsetWidth)
{
outerRightTrans.TranslateX += e.Delta.Translation.X;
innerRightTrans.TranslateX += e.Delta.Translation.X;
marginRightTrans.TranslateX += e.Delta.Translation.X * 2;

nextTrans.TranslateX = nextTransOffset;
if (nextRectXOffset < 0)
nextRect.X = nextRectXOffset;
rightTopNect.X += e.Delta.Translation.X;
nextPage.Clip.Rect = nextRect;
rightTopPage.Clip.Rect = rightTopNect;
}
else
{
e.Complete();
if (nextTransOffset < 0)
{
nextTrans.TranslateX = -offsetWidth;
nextRect.X = 0;
rightTopNect.X = 0;
nextPage.Clip.Rect = nextRect;
rightTopPage.Clip.Rect = rightTopNect;
}
else
{
nextTrans.TranslateX = offsetWidth;
nextRect.X = -offsetWidth;
rightTopNect.X = offsetWidth;
nextPage.Clip.Rect = nextRect;
rightTopPage.Clip.Rect = rightTopNect;
}
}
#endregion
}
else
{
#region 上一页
var leftTopNect = leftTopPage.Clip.Rect;
var prevRect = prevPage.Clip.Rect;
var prevTransOffset = prevTrans.TranslateX + e.Delta.Translation.X * 2;
var prevRectXOffset = prevRect.X - e.Delta.Translation.X;
SetShadowOperacity(Math.Abs(prevTransOffset), offsetWidth, true);
lastDeltaOffset = e.Delta.Translation.X;
if (prevRectXOffset > 0 && prevRectXOffset < offsetWidth)
{
innerLeftTrans.TranslateX += translateX;
outerLeftTrans.TranslateX += translateX;
marginLeftTrans.TranslateX += translateX * 2;

prevTrans.TranslateX = prevTransOffset;
if (prevRectXOffset > 0)
prevRect.X = prevRectXOffset;
leftTopNect.X += e.Delta.Translation.X;
prevPage.Clip.Rect = prevRect;
leftTopPage.Clip.Rect = leftTopNect;
}
else
{
e.Complete();
if (prevTransOffset < 0)
{
prevTrans.TranslateX = -offsetWidth;
prevRect.X = offsetWidth;
leftTopNect.X = -offsetWidth;
prevPage.Clip.Rect = prevRect;
leftTopPage.Clip.Rect = leftTopNect;

}
else
{
prevTrans.TranslateX = offsetWidth;
prevRect.X = 0;
leftTopNect.X = 0;
prevPage.Clip.Rect = prevRect;
leftTopPage.Clip.Rect = leftTopNect;
}
}
#endregion
}
}
if (CanScale)
{
_previousTransform.Matrix = _transformGroup.Value;
Point center = _previousTransform.TransformPoint(new Point(e.Position.X, e.Position.Y));
_compositeTransform.CenterX = center.X;
_compositeTransform.CenterY = center.Y;
_compositeTransform.ScaleX = e.Delta.Scale;
_compositeTransform.ScaleY = e.Delta.Scale;
_compositeTransform.TranslateX = e.Delta.Translation.X;
_compositeTransform.TranslateY = e.Delta.Translation.Y;
}
}
#endregion
#endregion

#region RenderAnimation 绘制翻页动画
private void RenderAnimation(object sender, object e)
{
if (turnLeft)
{
rightRestore = false;
turnRight = false;
var prevRect = prevPage.Clip.Rect;
var leftTopRect = leftTopPage.Clip.Rect;
var prevOffset = prevRect.X - Speed / 2;
if (prevOffset > 0)
{
prevRect.X = prevOffset;
prevTrans.TranslateX += Speed;
leftTopRect.X += Speed / 2;
innerLeftTrans.TranslateX += Speed / 2;
outerLeftTrans.TranslateX += Speed / 2;
marginLeftTrans.TranslateX += Speed;
SetShadowOperacity(Math.Abs(prevTrans.TranslateX), offsetWidth, true);
}
else
{
prevRect.X = 0;
leftTopRect.X = 0;
turnLeft = false;
prevTrans.TranslateX = offsetWidth;
Fliping(sender, new FlipEventArgs(false));

}
prevPage.Clip.Rect = prevRect;
leftTopPage.Clip.Rect = leftTopRect;
IsHitVisible(true);
}
else if (leftRestore)
{
turnLeft = false;
turnRight = false;
rightRestore = false;
var prevRect = prevPage.Clip.Rect;
var leftTopRect = leftTopPage.Clip.Rect;
var prevOffset = prevRect.X + Speed / 2;
if (prevOffset < offsetWidth)
{
prevRect.X = prevOffset;
prevTrans.TranslateX -= Speed;
leftTopRect.X -= Speed / 2;
innerLeftTrans.TranslateX -= Speed / 2;
outerLeftTrans.TranslateX -= Speed / 2;
marginLeftTrans.TranslateX -= Speed;
SetShadowOperacity(Math.Abs(prevTrans.TranslateX), offsetWidth, true);
}
else
{
prevRect.X = offsetWidth;
leftTopRect.X = -offsetWidth;
prevTrans.TranslateX = -offsetWidth;
innerLeftTrans.TranslateX = 0;
outerLeftTrans.TranslateX = 0;
marginLeftTrans.TranslateX = 0;
leftRestore = false;

}
prevPage.Clip.Rect = prevRect;
leftTopPage.Clip.Rect = leftTopRect;
IsHitVisible(true);
}
else if (turnRight)
{

rightRestore = false;
turnLeft = false;
var nextRect = nextPage.Clip.Rect;
var rightTopRect = rightTopPage.Clip.Rect;
var nextOffset = nextRect.X + Speed / 2;
if (nextOffset < 0)
{
nextRect.X = nextOffset;
nextTrans.TranslateX -= Speed;
rightTopRect.X -= Speed / 2;
innerRightTrans.TranslateX -= Speed / 2;
outerRightTrans.TranslateX -= Speed / 2;
marginRightTrans.TranslateX -= Speed;
SetShadowOperacity(Math.Abs(nextTrans.TranslateX), offsetWidth, false);
}
else
{
nextRect.X = 0;
nextTrans.TranslateX = -offsetWidth;
turnRight = false;
rightTopRect.X = 0;
Fliping(sender, new FlipEventArgs(true));
}
nextPage.Clip.Rect = nextRect;
rightTopPage.Clip.Rect = rightTopRect;
IsHitVisible(true);
}
else if (rightRestore)
{

turnRight = false;
turnLeft = false;
leftRestore = false;
var nextRect = nextPage.Clip.Rect;
var rightTopRect = rightTopPage.Clip.Rect;
var nextOffset = nextRect.X - Speed / 2;
if (nextRect.X - Speed / 2 > -offsetWidth)
{
nextRect.X = nextOffset;
nextTrans.TranslateX += Speed;
rightTopRect.X += Speed / 2;
innerRightTrans.TranslateX += Speed / 2;
outerRightTrans.TranslateX += Speed / 2;
marginRightTrans.TranslateX += Speed;
SetShadowOperacity(Math.Abs(nextTrans.TranslateX), offsetWidth, false);
}
else
{
nextRect.X = -offsetWidth;
rightTopRect.X = offsetWidth;
nextTrans.TranslateX = offsetWidth;
innerRightTrans.TranslateX = 0;
outerRightTrans.TranslateX = 0;
marginRightTrans.TranslateX = 0;
rightRestore = false;
}
rightTopPage.Clip.Rect = rightTopRect;
nextPage.Clip.Rect = nextRect;
IsHitVisible(true);
}
}
#endregion
#endregion

#region Method
#region LoadPageContentByPageIndex
private void LoadPageContentByPageIndex(int PageIndex, bool isNextOrPrev, ContentPresenter firstPresenter, ContentPresenter secondPresenter)
{
List<object> needLoadItems = new List<object>();
if (isNextOrPrev)
{
//加载下一页模板
if (PageIndex + 2 < this.Items.Count)
{
firstPresenter.Content = null;
firstPresenter.DataContext = null;
object item = null;
if (this.Items.Count > PageIndex + 2)
{
item = this.Items[PageIndex + 2];
needLoadItems.Add(item);
firstPresenter.DataContext = item;
}
}
else firstPresenter.DataContext = null;
if (PageIndex + 3 < this.Items.Count)
{
object item = null;
secondPresenter.Content = null;
secondPresenter.DataContext = null;
if (this.Items.Count > PageIndex + 3)
{
item = this.Items[PageIndex + 3];
needLoadItems.Add(item);
secondPresenter.DataContext = item;
}
}
else secondPresenter.DataContext = null;
if (null != NeedLoadingItem)
NeedLoadingItem(this, new FlipLoadArgs(needLoadItems, true));
RecycleData(true, needLoadItems);
}
else
{
if (PageIndex - 2 >= 0 && Items.Count > PageIndex - 2)
{
needLoadItems.Add(this.Items[PageIndex - 2]);
secondPresenter.Content = null;
secondPresenter.DataContext = null;
secondPresenter.DataContext = this.Items[PageIndex - 2];
}
if (PageIndex - 1 >= 0 && Items.Count > PageIndex - 1)
{
firstPresenter.Content = null;
firstPresenter.DataContext = null;
firstPresenter.DataContext = this.Items[PageIndex - 1];
needLoadItems.Add(this.Items[PageIndex - 1]);
}
//加载上一页模板
if (null != NeedLoadingItem)
NeedLoadingItem(this, new FlipLoadArgs(needLoadItems, false));
RecycleData(false, needLoadItems);
}
}
#endregion

#region RecycleData
private async void RecycleData(bool isNext, List<object> needItems)
{
await Task.Run(async () =>
{
foreach (var o in needItems)
{
await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
if (null != this.RestoreItemAction)
this.RestoreItemAction.Invoke(o);
});
}
if (isNext)
{
var index = -1;
try
{
index = this.Items.IndexOf(needItems[0]);

}
catch
{
index = -1;
}
if (index != -1 && index - 8 > 0)
{
for (int i = index - 8; i < index - 6; i++)
await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Low, () =>
{
if (null != this.DisposeAction)
DisposeAction.Invoke(this.Items[i]);
});
}
}
else
{
var index = -1;
try
{
index = this.Items.IndexOf(needItems.Last());

}
catch (Exception ex)
{
index = -1;
}
if (index != -1 && this.Items.Count > index + 7)
{
for (int i = index + 5; i < index + 7; i++)
await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Low, () =>
{
if (null != this.DisposeAction)
DisposeAction.Invoke(this.Items[i]);
});
}
}
});
}
#endregion

#region OnItemsChanged
/// <summary>
/// 刷新数据
/// </summary>
/// <param name="e"></param>
protected override void OnItemsChanged(object e)
{
isInit = false;
InitPages();
base.OnItemsChanged(e);
}
#endregion

#region GetPresentersByPageIndex
private List<ContentPresenter> GetPresentersByPageIndex(bool isNext)
{
List<ContentPresenter> presenters = new List<ContentPresenter>();
if (isNext)
{
presenters.Add(leftTopPage.Child as ContentPresenter);
presenters.Add(prevPage.Child as ContentPresenter);
}
else
{
presenters.Add(rightTopPage.Child as ContentPresenter);
presenters.Add(nextPage.Child as ContentPresenter);
}
Debug.WriteLine("presenter0Name:" + presenters[0].Name);
Debug.WriteLine("presenter1Name:" + presenters[1].Name);
return presenters;
}
#endregion

#region Crop
/// <summary>
/// 图形切割
/// </summary>
/// <param name="source"></param>
/// <param name="x1"></param>
/// <param name="y1"></param>
/// <param name="x2"></param>
/// <param name="y2"></param>
/// <returns></returns>
public WriteableBitmap Crop(WriteableBitmap source, int x1, int y1, int x2, int y2)
{
if (x1 >= x2 ||
y1 >= y2 ||
x1 < 0 ||
y1 < 0 ||
x2 < 0 ||
y2 < 0 ||
x1 > source.PixelWidth ||
y1 > source.PixelHeight ||
x2 > source.PixelWidth ||
y2 > source.PixelHeight)
{
throw new ArgumentException();
}

//var buffer = source.PixelBuffer.GetPixels();
var cw = x2 - x1;
var ch = y2 - y1;
var target = new WriteableBitmap(cw, ch);

var croppedBytes =
new byte[4 * cw * ch];
var inputStream = source.PixelBuffer.AsStream();
inputStream.Seek(4 * (source.PixelWidth * y1 + x1), SeekOrigin.Current);
for (int i = 0; i < ch; i++)
{
inputStream.Read(croppedBytes, 4 * cw * i, 4 * cw);
inputStream.Seek(4 * (source.PixelWidth - cw), SeekOrigin.Current);
}

var outputStream = target.PixelBuffer.AsStream();
outputStream.Seek(0, SeekOrigin.Begin);
outputStream.Write(croppedBytes, 0, croppedBytes.Length);
target.Invalidate();

return target;
}
#endregion

#region IsHitVisible
/// <summary>
/// 禁止点击
/// </summary>
/// <param name="o"></param>
private async void IsHitVisible(bool o)
{
await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Low, () =>
{
this.grdContent.IsHitTestVisible = o;
this.leftPage.IsHitTestVisible = o;
this.rightPage.IsHitTestVisible = o;
this.nextPage.IsHitTestVisible = o;
this.prevPage.IsHitTestVisible = o;
this.leftTopPage.IsHitTestVisible = o;
this.rightTopPage.IsHitTestVisible = o;
});
}
#endregion

#region RefreshPageByStatus
/// <summary>
/// 翻页成功后刷新控件状态
/// </summary>
private void RefreshPageByStatus()
{

switch (Status)
{
case 0:
Canvas.SetZIndex(A, 2);
Canvas.SetZIndex(B, 2);
Canvas.SetZIndex(C, 0);
Canvas.SetZIndex(D, 0);
Canvas.SetZIndex(E, 2);
Canvas.SetZIndex(F, 2);
Grid.SetColumn(A, 1);
Grid.SetColumn(B, 1);
Grid.SetColumn(C, 1);
Grid.SetColumn(D, 2);
Grid.SetColumn(E, 2);
Grid.SetColumn(F, 2);
transA.TranslateX = 0;
transB.TranslateX = -offsetWidth;
transC.TranslateX = 0;
transD.TranslateX = 0;
transE.TranslateX = offsetWidth;
transF.TranslateX = 0;
ARect.Rect = new Rect(-this.A.ActualWidth, 0, this.A.ActualWidth, this.A.ActualHeight);
CRect.Rect = new Rect(0, 0, this.C.ActualWidth, this.C.ActualHeight);
DRect.Rect = new Rect(0, 0, this.D.ActualWidth, this.D.ActualHeight);
FRect.Rect = new Rect(this.F.ActualWidth, 0, this.F.ActualWidth, this.F.ActualHeight);
BRect.Rect = new Rect(this.B.ActualWidth, 0, this.B.ActualWidth, this.B.ActualHeight);
ERect.Rect = new Rect(-this.E.ActualWidth, 0, this.E.ActualWidth, this.E.ActualHeight);
nextPage = E;
prevPage = B;
leftPage = C;
rightPage = D;
leftTopPage = A;
rightTopPage = F;
nextTrans = transE;
prevTrans = transB;
//A.PointerPressed -= this.PointerPressed;
//B.PointerPressed -= this.PointerPressed;
//C.PointerPressed += this.PointerPressed;
//D.PointerPressed += this.PointerPressed;
break;
case 1:
Canvas.SetZIndex(A, 2);
Canvas.SetZIndex(B, 2);
Canvas.SetZIndex(C, 2);
Canvas.SetZIndex(D, 2);
Canvas.SetZIndex(E, 0);
Canvas.SetZIndex(F, 0);
Grid.SetColumn(A, 2);
Grid.SetColumn(B, 2);
Grid.SetColumn(C, 1);
Grid.SetColumn(D, 1);
Grid.SetColumn(E, 1);
Grid.SetColumn(F, 2);
transA.TranslateX = offsetWidth;
transB.TranslateX = 0;
transC.TranslateX = 0;
transD.TranslateX = -offsetWidth;
transE.TranslateX = 0;
transF.TranslateX = 0;
ARect.Rect = new Rect(-this.A.ActualWidth, 0, this.A.ActualWidth, this.A.ActualHeight);
CRect.Rect = new Rect(-this.C.ActualWidth, 0, this.C.ActualWidth, this.C.ActualHeight);
DRect.Rect = new Rect(this.D.ActualWidth, 0, this.D.ActualWidth, this.D.ActualHeight);
FRect.Rect = new Rect(0, 0, this.F.ActualWidth, this.F.ActualHeight);
BRect.Rect = new Rect(this.B.ActualWidth, 0, this.B.ActualWidth, this.B.ActualHeight);
ERect.Rect = new Rect(0, 0, this.E.ActualWidth, this.E.ActualHeight);
nextPage = A;
prevPage = D;
leftPage = E;
rightPage = F;
leftTopPage = C;
rightTopPage = B;
nextTrans = transA;
prevTrans = transD;
//C.PointerPressed -= this.PointerPressed;
//D.PointerPressed -= this.PointerPressed;
//E.PointerPressed += this.PointerPressed;
//F.PointerPressed += this.PointerPressed;
break;
case 2:
Canvas.SetZIndex(A, 0);
Canvas.SetZIndex(B, 0);
Canvas.SetZIndex(C, 2);
Canvas.SetZIndex(D, 2);
Canvas.SetZIndex(E, 2);
Canvas.SetZIndex(F, 2);
Grid.SetColumn(A, 1);
Grid.SetColumn(B, 2);
Grid.SetColumn(C, 2);
Grid.SetColumn(D, 2);
Grid.SetColumn(E, 1);
Grid.SetColumn(F, 1);
transA.TranslateX = 0;
transB.TranslateX = 0;
transC.TranslateX = offsetWidth;
transD.TranslateX = 0;
transE.TranslateX = 0;
transF.TranslateX = -offsetWidth;
ARect.Rect = new Rect(0, 0, this.A.ActualWidth, this.A.ActualHeight);
CRect.Rect = new Rect(-this.C.ActualWidth, 0, this.C.ActualWidth, this.C.ActualHeight);
DRect.Rect = new Rect(this.D.ActualWidth, 0, this.D.ActualWidth, this.D.ActualHeight);
FRect.Rect = new Rect(this.F.ActualWidth, 0, this.F.ActualWidth, this.F.ActualHeight);
BRect.Rect = new Rect(0, 0, this.B.ActualWidth, this.B.ActualHeight);
ERect.Rect = new Rect(-this.E.ActualWidth, 0, this.E.ActualWidth, this.E.ActualHeight);
nextPage = C;
prevPage = F;
leftPage = A;
rightPage = B;
leftTopPage = E;
rightTopPage = D;
nextTrans = transC;
prevTrans = transF;
//E.PointerPressed -= this.PointerPressed;
//F.PointerPressed -= this.PointerPressed;
//A.PointerPressed += this.PointerPressed;
//B.PointerPressed += this.PointerPressed;
break;
default:
break;
}
stShadowSplitInnerLeft.Opacity = 0;
stShadowSplitInnerRight.Opacity = 0;
stShadowSplitOuterLeft.Opacity = 0;
stShadowSplitOuterRight.Opacity = 0;
outerRightTrans.TranslateX = 0;
innerRightTrans.TranslateX = 0;
outerLeftTrans.TranslateX = 0;
innerLeftTrans.TranslateX = 0;
marginLeftTrans.TranslateX = 0;
marginRightTrans.TranslateX = 0;
leftTopPage.Background = leftBrush;
prevPage.Background = rightBrush;
leftPage.Background = leftBrush;
rightPage.Background = rightBrush;
nextPage.Background = leftBrush;
rightTopPage.Background = rightBrush;
}
#endregion

#region GetCropBookBrush
private async Task GetCropBrush()
{
if (null != this.BookBackgroundBrush)
{
var orginSource = this.BookBackgroundBrush.ImageSource as BitmapImage;
if (!orginSource.UriSource.AbsolutePath.Equals(string.Empty))
{
var uri = new Uri("ms-appx://" + orginSource.UriSource.AbsolutePath);
try
{
var file = await StorageFile.GetFileFromApplicationUriAsync(uri);
WriteableBitmap leftSource = new WriteableBitmap(Convert.ToInt32(offsetWidth * 2), Convert.ToInt32(offsetHeight));
await LoadAsync(leftSource, file);
WriteableBitmap rightSource = new WriteableBitmap(Convert.ToInt32(offsetWidth * 2), Convert.ToInt32(offsetHeight));
await LoadAsync(rightSource, file);
leftBrush = new ImageBrush();
rightBrush = new ImageBrush();
rightBrush.Stretch = Stretch.Fill;
leftBrush.Stretch = Stretch.Fill;
leftSource = Crop(leftSource, 0, 0, Convert.ToInt32(offsetWidth), Convert.ToInt32(offsetHeight));
leftBrush.ImageSource = leftSource;
rightSource = Crop(rightSource, Convert.ToInt32(offsetWidth), 0, Convert.ToInt32(offsetWidth * 2), Convert.ToInt32(offsetHeight));
rightBrush.ImageSource = rightSource;
}
catch
{
}
}
}
}
#endregion

#region LoadWriteableBitmap
public async Task<WriteableBitmap> LoadAsync(
WriteableBitmap writeableBitmap,
StorageFile storageFile)
{
using (var stream = await storageFile.OpenReadAsync())
{
await writeableBitmap.SetSourceAsync(
stream);
}
return writeableBitmap;
}

#endregion

#region SetShadowOperacity
private async void SetShadowOperacity(double pos, double pageWidth, bool direction)
{
var opacity = await Task.Run(() =>
{
double num = (pageWidth - pos) / 2.0;
double num2 = Math.Abs((double)((pageWidth / 2.0) - num));
return (1.0 * (1.0 - (num2 / (pageWidth / 2.0))));
});
if (direction)
{
this.stShadowSplitOuterLeft.Opacity = opacity;
this.stShadowSplitInnerLeft.Opacity = opacity;
this.stShadowMarginLeft.Opacity = opacity;
}
else
{
this.stShadowSplitOuterRight.Opacity = opacity;
this.stShadowSplitInnerRight.Opacity = opacity;
this.stShadowMarginRight.Opacity = opacity;
}
}
#endregion
#endregion
}

/// <summary>
/// 抛出需要加载的项数据
/// </summary>
public class FlipLoadArgs : EventArgs
{
public readonly List<object> needItems;
public readonly bool isNext;

public FlipLoadArgs(List<object> _needItems, bool _isNext)
{
this.needItems = _needItems;
this.isNext = _isNext;
}
}

public class FlipEventArgs : EventArgs
{
public readonly bool isNext;

public FlipEventArgs(bool _isNext)
{
this.isNext = _isNext;
}
}
}

<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WinRTXamlToolkit.Controls">

<Style TargetType="local:FlipBookControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:FlipBookControl">
<Grid
x:Name="grdContent"
Background="{TemplateBinding Background}">
<Grid.RowDefinitions>
<RowDefinition Height="30*"/>
<RowDefinition Height="750*"/>
<RowDefinition Height="30*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50*"/>
<ColumnDefinition Width="600*"/>
<ColumnDefinition Width="600*"/>
<ColumnDefinition Width="50*"/>
</Grid.ColumnDefinitions>
<Image
x:Name="bookContainer"
Stretch="Fill"
Canvas.ZIndex="2"
Grid.ColumnSpan="4"
IsHitTestVisible="False"
Grid.RowSpan="3"/>
<Border
Grid.Row="1"
Grid.Column="1"
BorderThickness="0"
x:Name="C">
<Border.Clip>
<RectangleGeometry x:Name="CRect">
</RectangleGeometry>
</Border.Clip>
<Border.RenderTransform>
<CompositeTransform x:Name="transC"></CompositeTransform>
</Border.RenderTransform>
<ContentPresenter x:Name="CPresenter" Style="{TemplateBinding ItemContainerStyle}"
ContentTemplate="{TemplateBinding ItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"></ContentPresenter>
</Border>
<Border Grid.Row="1" Grid.Column="1" BorderThickness="0"
x:Name="D">
<Border.Clip>
<RectangleGeometry x:Name="DRect">
</RectangleGeometry>
</Border.Clip>
<Border.RenderTransform>
<CompositeTransform x:Name="transD"></CompositeTransform>
</Border.RenderTransform>
<ContentPresenter x:Name="DPresenter" Style="{TemplateBinding ItemContainerStyle}"
ContentTemplate="{TemplateBinding ItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"></ContentPresenter>
</Border>
<Border Grid.Row="1" Grid.Column="1" BorderThickness="0"
x:Name="E">
<Border.Clip>
<RectangleGeometry x:Name="ERect">
</RectangleGeometry>
</Border.Clip>
<Border.RenderTransform>
<CompositeTransform x:Name="transE"/>
</Border.RenderTransform>
<ContentPresenter x:Name="EPresenter" Style="{TemplateBinding ItemContainerStyle}"
ContentTemplate="{TemplateBinding ItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"></ContentPresenter>
</Border>
<Border Grid.Row="1" Grid.Column="1" BorderThickness="0"
x:Name="F">
<Border.Clip>
<RectangleGeometry x:Name="FRect">
</RectangleGeometry>
</Border.Clip>
<Border.RenderTransform>
<CompositeTransform x:Name="transF"></CompositeTransform>
</Border.RenderTransform>
<ContentPresenter x:Name="FPresenter" Style="{TemplateBinding ItemContainerStyle}"
ContentTemplate="{TemplateBinding ItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"></ContentPresenter>
</Border>
<Border Grid.Row="1" Grid.Column="1" BorderThickness="0"
x:Name="A">
<Border.Clip>
<RectangleGeometry x:Name="ARect">
</RectangleGeometry>
</Border.Clip>
<Border.RenderTransform>
<CompositeTransform x:Name="transA"></CompositeTransform>
</Border.RenderTransform>
<ContentPresenter x:Name="APresenter" Style="{TemplateBinding ItemContainerStyle}"
ContentTemplate="{TemplateBinding ItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"></ContentPresenter>
</Border>
<Border Grid.Row="1" Grid.Column="1"  BorderThickness="0"
x:Name="B">
<Border.Clip>
<RectangleGeometry x:Name="BRect">
</RectangleGeometry>
</Border.Clip>
<Border.RenderTransform>
<CompositeTransform x:Name="transB"/>
</Border.RenderTransform>
<ContentPresenter x:Name="BPresenter" Style="{TemplateBinding ItemContainerStyle}"
ContentTemplate="{TemplateBinding ItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"></ContentPresenter>
</Border>
<StackPanel  Canvas.ZIndex="3"
x:Name="stShadowSplitOuterLeft"
Width="43"
Opacity="0"
Grid.Row="1"
Grid.Column="1"
HorizontalAlignment="Left" Margin="-43,0,0,0" RenderTransformOrigin="0.5,0.5">
<StackPanel.RenderTransform>
<CompositeTransform x:Name="outerLeftTrans" TranslateX="0"/>
</StackPanel.RenderTransform>
<StackPanel.Background>
<LinearGradientBrush EndPoint="0,0" StartPoint="1,0">
<GradientStop Color="#99000000"/>
<GradientStop Color="Transparent" Offset="1"/>
</LinearGradientBrush>
</StackPanel.Background>
</StackPanel>
<StackPanel Canvas.ZIndex="3"
x:Name="stShadowSplitInnerLeft"
Width="51"
Opacity="0"
Grid.Row="1"
Grid.Column="1"
HorizontalAlignment="Left" RenderTransformOrigin="0.5,0.5">
<StackPanel.RenderTransform>
<CompositeTransform x:Name="innerLeftTrans" TranslateX="0"/>
</StackPanel.RenderTransform>
<StackPanel.Background>
<LinearGradientBrush EndPoint="1,1" StartPoint="0,1">
<GradientStop Color="#99000000"/>
<GradientStop Color="#01FFFFFF" Offset="1"/>
</LinearGradientBrush>
</StackPanel.Background>
</StackPanel>
<StackPanel Canvas.ZIndex="3"
x:Name="stShadowSplitOuterRight"
Width="43"
Opacity="0"
Grid.Row="1"
Grid.Column="2"
HorizontalAlignment="Right" Margin="0,0,-43,0" RenderTransformOrigin="0.5,0.5">
<StackPanel.RenderTransform>
<CompositeTransform x:Name="outerRightTrans" TranslateX="0"/>
</StackPanel.RenderTransform>
<StackPanel.Background>
<LinearGradientBrush EndPoint="1,1" StartPoint="0,1">
<GradientStop Color="#99000000"/>
<GradientStop Color="Transparent" Offset="1"/>
</LinearGradientBrush>
</StackPanel.Background>
</StackPanel>
<StackPanel  Canvas.ZIndex="3"
x:Name="stShadowSplitInnerRight"
Width="51"
Opacity="0"
Grid.Row="1"
Grid.Column="2"
HorizontalAlignment="Right" RenderTransformOrigin="0.5,0.5">
<StackPanel.RenderTransform>
<CompositeTransform x:Name="innerRightTrans" TranslateX="0"/>
</StackPanel.RenderTransform>
<StackPanel.Background>
<LinearGradientBrush EndPoint="0,0" StartPoint="1,0">
<GradientStop Color="#99000000"/>
<GradientStop Color="#01FFFFFF" Offset="1"/>
</LinearGradientBrush>
</StackPanel.Background>
</StackPanel>
<StackPanel x:Name="stShadowMarginLeft" Width="30" HorizontalAlignment="Left"
Opacity="0" Grid.Row="1" Grid.Column="1" Canvas.ZIndex="3">
<StackPanel.RenderTransform>
<CompositeTransform x:Name="marginLeftTrans" TranslateX="0"/>
</StackPanel.RenderTransform>
<StackPanel.Background>
<LinearGradientBrush EndPoint="1,1" StartPoint="0,1">
<GradientStop Color="#99000000"/>
<GradientStop Color="Transparent" Offset="1"/>
</LinearGradientBrush>
</StackPanel.Background>
</StackPanel>
<StackPanel x:Name="stShadowMarginRight" Width="30" HorizontalAlignment="Right"
Opacity="0" Grid.Row="1" Grid.Column="2" Canvas.ZIndex="3">
<StackPanel.RenderTransform>
<CompositeTransform x:Name="marginRightTrans" TranslateX="0"/>
</StackPanel.RenderTransform>
<StackPanel.Background>
<LinearGradientBrush EndPoint="0,0" StartPoint="1,0">
<GradientStop Color="#99000000"/>
<GradientStop Color="Transparent" Offset="1"/>
</LinearGradientBrush>
</StackPanel.Background>
</StackPanel>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>


Sample: 使用方法

<local:FlipBookControl x:Name="fbc" Speed="10"
ItemTemplate="{StaticResource BookTemplate}">
<local:FlipBookControl.Background>
<ImageBrush ImageSource="ms-appx:///Assets/bookbox-hori.png"/>
</local:FlipBookControl.Background>
<local:FlipBookControl.BookBackgroundBrush>
<ImageBrush ImageSource="ms-appx:///Assets/bg-7.jpg"/>
</local:FlipBookControl.BookBackgroundBrush>
</local:FlipBookControl>

支持ItemsSource 数据源 以及ItemTemplate Binding

DisposeAction 和RestoreItem 2个依赖项 请在使用前填写。用于释放图片流 以及恢复 源

欢迎讨论,分享经验,以及更优的方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: