2017-07-20 9 views
1

Je suis en train de créer un lecteur eBook pour Windows Phone 8.1 dans Xamarin Native C#.Page tour animation dans Windows Phone 8.1 lecteur ebook

J'ai lu avec succès l'objet eBook et cherche maintenant à rendre ces données dans plusieurs vues Web selon les chapitres. Les vues Web défilent verticalement en fonction de la longueur du chapitre. Cependant, je veux aussi que les vues Web changent les chapitres sur les balayages gauches et droits, le plus important avec une animation flip de page de livre.

Quelque chose comme this sample project, mais pas dans Silverlight.

P.S. Cela fait seulement une semaine que j'ai commencé le développement des fenêtres, alors s'il vous plaît, supportez-moi. Je fais de mon mieux ici. Merci beaucoup :)

Répondre

0

Pageturn.cs (mise en œuvre de PageTurner7 Silverlight

using System; 
//using System.Windows.Ink; 
using System.Collections.Generic; 
using Windows.UI.Xaml.Documents; 
using System.Windows; 
using Windows.UI.Xaml.Input; 
using Windows.UI.Xaml; 
using Windows.UI.Xaml.Media; 
using Windows.UI.Xaml.Shapes; 
using Windows.UI.Xaml.Controls; 
using Windows.UI.Xaml.Media.Animation; 
using Windows.UI.Xaml.Markup; 
using Windows.Foundation; 

namespace epub_reader.WinPhone 
{ 
    public class PageTurn 
    { 
     public PageTurn() 
     { 
     } 

     private int _index = 0;   // Current spread index 
     private double _width;    // Width of each page 
     private double _height;   // Height of each page 
     private int _count = 0;   // Number of even/odd page pairs 
     private bool _turning = false;  // True if page turn in progress 
     private bool _animating = false; // True if animated turn completion in progress 
     private double _percent = 0.0;  // Percent turned (0 = 0%, 1 = 100%) 
     private double _startPos = -1;  // X coordinate of initial mouse click 
     private int _direction = 0;  // -1 = Turning left, 1 = Turning right 
     private double _step = 0.025;  // Step size for animations 
     private double _shadowWidth = 16; // Maximum shadow width 
     private double _shadowBreak = 5; // Number of degrees required for shadow to attain maximum width 
     private double _sensitivity = 1.0; // Higher number -> More mouse movement required for full turn 

     private FrameworkElement _owner = null;      // Owner of mouse capture 
     private List<Canvas> _evens = new List<Canvas>();   // Even pages 
     private List<Canvas> _odds = new List<Canvas>();    // Odd pages 
     private Polygon _shadow = null;        // Polygon object used to draw shadow 
     private Storyboard _timer = null;       // Storyboard timer for animations 
     private Canvas _canvas = null;        // Canvas containing pages 
     private Canvas _workingOdd = null;       // Working right page 
     private Canvas _workingEven = null;       // Working left page 

     private PathGeometry _oddClipRegion = null; 
     private LineSegment _oddClipRegionLineSegment1 = null; 
     private LineSegment _oddClipRegionLineSegment2 = null; 
     private PathGeometry _evenClipRegion = null; 
     private LineSegment _evenClipRegionLineSegment1 = null; 
     private LineSegment _evenClipRegionLineSegment2 = null; 
     private LineSegment _evenClipRegionLineSegment3 = null; 
     private TransformGroup _transformGroup = null; 
     private RotateTransform _rotateTransform = null; 
     private TranslateTransform _translateTransform = null; 

     // XAML definition for clip region used on right-hand pages 
     private const string _opg = 
      "<PathGeometry xmlns=\"http://schemas.microsoft.com/client/2007\">" + 
      "<PathFigure StartPoint=\"0,0\">" + 
      "<LineSegment />" + 
      "<LineSegment />" + 
      "</PathFigure>" + 
      "</PathGeometry>"; 

     // XAML definition for clip region used on left-hand pages 
     private const string _epg = 
      "<PathGeometry xmlns=\"http://schemas.microsoft.com/client/2007\">" + 
      "<PathFigure StartPoint=\"0,0\">" + 
      "<LineSegment Point=\"0,0\" />" + 
      "<LineSegment Point=\"0,0\" />" + 
      "<LineSegment Point=\"0,0\" />" + 
      "</PathFigure>" + 
      "</PathGeometry>"; 

     // XAML definition for transforms used on left-hand pages 
     private const string _tg = 
      "<TransformGroup xmlns=\"http://schemas.microsoft.com/client/2007\">" + 
      "<RotateTransform />" + 
      "<TranslateTransform />" + 
      "</TransformGroup>"; 

     // XAML definition for Storyboard timer 
     private const string _sb = "<Storyboard xmlns=\"http://schemas.microsoft.com/client/2007\" Duration=\"0:0:0.01\" />"; 

     // XAML definition for shadow polygon 
     private const string _poly = 
      "<Polygon xmlns=\"http://schemas.microsoft.com/client/2007\" Canvas.ZIndex=\"4\" Fill=\"Black\" Opacity=\"0.2\" Points=\"0,0 0,0 0,0 0,0\" Visibility=\"Collapsed\">" + 
      "<Polygon.Clip>" + 
      "<RectangleGeometry Rect=\"0,0,{0},{1}\" />" + 
      "</Polygon.Clip>" + 
      "</Polygon>"; 

     //////////////////////////////////////////////////////////////////////// 
     // Events 
     public event EventHandler PageTurned; 

     //////////////////////////////////////////////////////////////////////// 
     // Properties 

     public int CurrentSpreadIndex 
     { 
      get { return _index; } 
     } 

     public int SpreadCount 
     { 
      get { return _count; } 
     } 

     public double Sensitivity 
     { 
      get { return _sensitivity; } 
      set { _sensitivity = value; } 
     } 

     //////////////////////////////////////////////////////////////////////// 
     // Public methods 

     public void Initialize(Canvas canvas) 
     { 
      _canvas = canvas; 

      // Create a Storyboard for timing animations 
      _timer = (Storyboard)XamlReader.Load(_sb); 
      //_timer.Completed += new EventHandler(OnTimerTick); 
      _timer.Completed += OnTimerTick; 
      // Create a PathGeometry for clipping right-hand pages 
      _oddClipRegion = (PathGeometry)XamlReader.Load(_opg); 
      _oddClipRegionLineSegment1 = (LineSegment)_oddClipRegion.Figures[0].Segments[0]; 
      _oddClipRegionLineSegment2 = (LineSegment)_oddClipRegion.Figures[0].Segments[1]; 

      // Create a PathGeometry for clipping left-hand pages 
      string xaml = String.Format(_epg, _evens[0].Height); 
      _evenClipRegion = (PathGeometry)XamlReader.Load(xaml); 
      _evenClipRegionLineSegment1 = (LineSegment)_evenClipRegion.Figures[0].Segments[0]; 
      _evenClipRegionLineSegment2 = (LineSegment)_evenClipRegion.Figures[0].Segments[1]; 
      _evenClipRegionLineSegment3 = (LineSegment)_evenClipRegion.Figures[0].Segments[2]; 

      // Create a TransformGroup for transforming left-hand pages 
      _transformGroup = (TransformGroup)XamlReader.Load(_tg); 
      _rotateTransform = (RotateTransform)_transformGroup.Children[0]; 
      _translateTransform = (TranslateTransform)_transformGroup.Children[1]; 

      // Initialize internal variables 
      _count = _evens.Count; 
      _width = _evens[0].Width; 
      _height = _evens[0].Height; 

      // Create a Polygon to provide shadow during page turns 
      _shadow = (Polygon)XamlReader.Load(String.Format(_poly, _width * 2, _height)); 
      _canvas.Children.Add(_shadow); 

      // Initialize z-order 
      InitializeZOrder(); 
     } 

     private void OnTimerTick(object sender, object e) 
     { 
      _percent += _step; 

      if (_percent < 0.0) 
       _percent = 0.0; 
      else if (_percent > 1.0) 
       _percent = 1.0; 

      TurnTo(_percent); 

      if (_percent == 0.0) 
      { 
       if (_direction == 1) 
       { 
        _index--; 
        if (PageTurned != null) 
         PageTurned(this, EventArgs.Empty); 
       } 
       Reset(); 
      } 
      else if (_percent == 1.0) 
      { 
       if (_direction == -1) 
       { 
        _index++; 
        if (PageTurned != null) 
         PageTurned(this, EventArgs.Empty); 
       } 
       Reset(); 
      } 
      else 
       _timer.Begin(); 
     } 

     public void AddSpread(Canvas left, Canvas right) 
     { 
      left.PointerPressed += Left_PointerPressed; ; ; 
      //left.MouseLeftButtonDown += new MouseButtonEventHandler(OnBeginRightTurn); 
      left.PointerMoved += Left_PointerMoved; 
      //left.MouseMove += new MouseEventHandler(OnContinueRightTurn); 
      left.PointerReleased += Left_PointerReleased; ; 
      //left.MouseLeftButtonUp += new MouseButtonEventHandler(OnEndRightTurn); 
      _evens.Add(left); 

      right.PointerPressed += Right_PointerPressed; 
      right.PointerMoved += Right_PointerMoved; 
      right.PointerReleased += Right_PointerReleased; 
      _odds.Add(right); 
     } 

     private void Right_PointerPressed(object sender, PointerRoutedEventArgs e) 
     { 
      if (_animating) 
       return; // Do nothing if animation in progress 

      // Do nothing if trying to turn left but last 
      // page is displayed 
      if (_index == _count - 1) 
       return; 

      // Start a left turn 
      _turning = true; 
      _direction = -1; 
      _percent = 0.0; 
      _startPos = e.GetCurrentPoint((FrameworkElement)sender).Position.X; 
      _owner = (FrameworkElement)sender; 
      ((FrameworkElement)sender).CapturePointer(e.Pointer); 

      // Turn page to specified angle 
      TurnTo(_percent); 

      // Cache references to "working" pages 
      _workingOdd = _odds[_index]; 
      _workingEven = _evens[_index + 1]; 

      // Assign clipping regions and transforms to relevant canvases 
      RectangleGeometry rect = new RectangleGeometry(); 
      rect.Transform = _oddClipRegion.Transform; 
      rect.Rect = _oddClipRegion.Bounds; 
      _workingOdd.Clip = rect; 

      //_workingOdd.Clip = _oddClipRegion; 
      //_workingEven.Clip = _evenClipRegion; 
      RectangleGeometry rect2 = new RectangleGeometry(); 
      rect2.Rect = _evenClipRegion.Bounds; 
      rect2.Transform = _evenClipRegion.Transform; 
      _workingEven.Clip = rect2; 

      _workingEven.RenderTransform = _transformGroup; 

      // Set z-indexes for a left turn 
      _evens[_index + 1].SetValue(Canvas.ZIndexProperty, 2); 
      _odds[_index + 1].SetValue(Canvas.ZIndexProperty, 0); 
     } 

     private void Right_PointerMoved(object sender, PointerRoutedEventArgs e) 
     { 
      if (_animating) 
       return; // Do nothing if animation in progress 

      if (_turning) 
      { 
       // Compute change in X 
       double dx = _startPos - e.GetCurrentPoint((FrameworkElement)sender).Position.X; 

       // If mouse moved right, update _startPos so page 
       // begins turning with first move left 
       if (dx < 0) 
       { 
        _startPos = e.GetCurrentPoint((FrameworkElement)sender).Position.X; 
        return; 
       } 

       // Compute turn percentage based on change in X 
       double percent = dx/(_width * _sensitivity); 

       if (percent > 1.0) 
        percent = 1.0; 
       else if (percent < 0.0) 
        percent = 0.0; 

       // Exit now if no change 
       if (percent == _percent) 
        return; 

       // Update percent turned 
       _percent = percent; 

       // Turn page to specified angle 
       TurnTo(_percent); 
      } 
     } 

     private void Right_PointerReleased(object sender, PointerRoutedEventArgs e) 
     { 
      if (_animating) 
       return; // Do nothing if animation in progress 

      if (_turning) 
       CompleteTurn(); 
     } 

     private void Left_PointerPressed(object sender, PointerRoutedEventArgs e) 
     { 
      if (_animating) 
       return; // Do nothing if animation in progress 

      // Do nothing if trying to turn right but first 
      // page is displayed 
      if (_index == 0) 
       return; 

      // Start a right turn 
      _turning = true; 
      _direction = 1; 
      _percent = 1.0; 
      _startPos = e.GetCurrentPoint((FrameworkElement)sender).Position.X; 
      _owner = (FrameworkElement)sender; 
      ((FrameworkElement)sender).CapturePointer(e.Pointer); 

      // Turn page to specified angle 
      TurnTo(_percent); 

      // Cache references to "working" pages 
      _workingOdd = _odds[_index - 1]; 
      _workingEven = _evens[_index]; 

      // Assign clipping regions and transforms to relevant canvases 
      RectangleGeometry rect = new RectangleGeometry(); 
      rect.Transform = _oddClipRegion.Transform; 
      rect.Rect = _oddClipRegion.Bounds; 
      _workingOdd.Clip = rect; 

      //_workingOdd.Clip = _oddClipRegion; 
      //_workingEven.Clip = _evenClipRegion; 
      RectangleGeometry rect2 = new RectangleGeometry(); 
      rect2.Rect = _evenClipRegion.Bounds; 
      rect2.Transform = _evenClipRegion.Transform; 
      _workingEven.Clip = rect2; 
      _workingEven.RenderTransform = _transformGroup; 

      // Set z-indexes for a right turn 
      _evens[_index].SetValue(Canvas.ZIndexProperty, 3); 
      _evens[_index - 1].SetValue(Canvas.ZIndexProperty, 0); 
      _odds[_index - 1].SetValue(Canvas.ZIndexProperty, 2); 

     } 

     private void Left_PointerMoved(object sender, PointerRoutedEventArgs e) 
     { 
      if (_animating) 
       return; // Do nothing if animation in progress 

      if (_turning) 
      { 
       // Compute change in X 
       double dx = e.GetCurrentPoint((FrameworkElement)(((FrameworkElement)sender).Parent)).Position.X - _startPos; 

       // If mouse moved left, update _startPos so page 
       // begins turning with first move right 
       if (dx < 0) 
       { 
        _startPos = e.GetCurrentPoint((FrameworkElement)(((FrameworkElement)sender).Parent)).Position.X; 
        return; 
       } 

       // Compute turn percentage based on change in X 
       double percent = 1.0 - (dx/(_width * _sensitivity)); 

       if (percent > 1.0) 
        percent = 1.0; 
       else if (percent < 0.0) 
        percent = 0.0; 

       // Exit now if no change 
       if (percent == _percent) 
        return; 

       // Update percent turned 
       _percent = percent; 

       // Turn page to specified angle 
       TurnTo(this._percent); 
      } 
     } 

     private void Left_PointerReleased(object sender, PointerRoutedEventArgs e) 
     { 
      if (_animating) 
       return; // Do nothing if animation in progress 

      if (_turning) 
       CompleteTurn(); 
     } 

     public void GoToSpread(int index) 
     { 
      if (index != _index && index > 0 && index < _count) 
      { 
       _index = index; 
       InitializeZOrder(); 

       if (PageTurned != null) 
        PageTurned(this, EventArgs.Empty); 
      } 
     } 

     //////////////////////////////////////////////////////////////////////// 
     // Helper methods 

     private void TurnTo(double percent) 
     { 
      // Compute angle of rotation 
      double degrees = 45 - (percent * 45); 
      double radians = degrees * Math.PI/180; 

      // Compute x coordinates along bottom of canvas 
      double dx1 = _width - (percent * _width); 
      double dx2 = _width - dx1; 

      // Compute tangent of rotation angle 
      double tan = Math.Tan(radians); 

      // Configure clipping region for right-hand page 
      double p2y; 

      if (tan == 0) 
       p2y = _height; 
      else 
       p2y = _height + (dx1/tan); 

      double p3x = p2y * tan; 

      _oddClipRegionLineSegment1.Point = new Point(0, p2y); 
      _oddClipRegionLineSegment2.Point = new Point(p3x, 0); 

      // Configure clipping region for left-hand page 
      double p7x = dx2 - (_height * tan); 

      if (p7x >= 0.0) // 4-corner clipping region 
      { 
       _evenClipRegion.Figures[0].StartPoint = new Point(0, 0); 
       _evenClipRegionLineSegment1.Point = new Point(0, _height); 
       _evenClipRegionLineSegment2.Point = new Point(dx2, _height); 
       _evenClipRegionLineSegment3.Point = new Point(p7x, 0); 
      } 
      else // 3-corner clipping region 
      { 
       double y = _height - (dx2/tan); 
       _evenClipRegion.Figures[0].StartPoint = _evenClipRegionLineSegment3.Point = new Point(0, y); 
       _evenClipRegionLineSegment1.Point = new Point(0, _height); 
       _evenClipRegionLineSegment2.Point = new Point(dx2, _height); 
      } 

      // Apply clipping regions and transforms 
      _rotateTransform.CenterX = dx2; 
      _rotateTransform.CenterY = _height; 
      _rotateTransform.Angle = 2 * degrees; 

      _translateTransform.X = 2 * (_width - dx2); 

      // Configure shadow 
      if (percent == 0.0 || percent == 1.0) 
      { 
       _shadow.Visibility = Visibility.Collapsed; 
       return; 
      } 

      _shadow.Visibility = Visibility.Visible; 

      double min = this._shadowBreak; 
      double max = 45 - this._shadowBreak; 
      double width; 

      if (degrees > min && degrees < max) 
       width = _shadowWidth; 
      else 
      { 
       if (degrees <= min) 
        width = (degrees/_shadowBreak) * _shadowWidth; 
       else // degrees >= max 
        width = ((45 - degrees)/_shadowBreak) * _shadowWidth; 
      } 

      double x1 = _width + dx1 + (_height * tan); 
      double x2 = _width + dx1; 
      double y2 = _height; 
      double x3 = x2 + width; 
      double y3 = _height; 
      double x4 = x1 + width; 

      _shadow.Points[0] = new Point(x1, 0); 
      _shadow.Points[1] = new Point(x2, y2); 
      _shadow.Points[2] = new Point(x3, y3); 
      _shadow.Points[3] = new Point(x4, 0); 
     } 

     private void CompleteTurn() 
     { 
      if (_percent == 0.0) 
      { 
       if (_direction == 1) 
       { 
        _index--; 
        if (PageTurned != null) 
         PageTurned(this, EventArgs.Empty); 
       } 
       Reset(); 
       return; 
      } 

      if (_percent == 1.0) 
      { 
       if (_direction == -1) 
       { 
        _index++; 
        if (PageTurned != null) 
         PageTurned(this, EventArgs.Empty); 
       } 
       Reset(); 
       return; 
      } 

      if (_percent < 0.5) 
       _step = -Math.Abs(_step); 
      else 
       _step = Math.Abs(_step); 

      _animating = true; 
      _timer.Begin(); 
     } 

     private void Reset() 
     { 
      _turning = false; 
      _animating = false; 
      _direction = 0; 

      if (_owner != null) 
       _owner.ReleasePointerCaptures(); 
      _owner = null; 

      if (_workingOdd != null && _workingOdd.Clip != null) 
       _workingOdd.Clip = null; 
      if (_workingEven != null && _workingEven.Clip != null) 
       _workingEven.Clip = null; 
      if (_workingEven != null && _workingEven.RenderTransform != null) 
       _workingEven.RenderTransform = null; 

      _workingOdd = null; 
      _workingEven = null; 

      _shadow.Visibility = Visibility.Collapsed; 

      InitializeZOrder(); 
     } 

     private void InitializeZOrder() 
     { 
      for (int i = 0; i < _count; i++) 
      { 
       _evens[i].SetValue(Canvas.ZIndexProperty, (i == _index) ? 1 : -1); 
       _odds[i].SetValue(Canvas.ZIndexProperty, (i == _index) ? 1 : -1); 
      } 
     } 
    } 
} 
+0

Exactement ce dont j'avais besoin. Merci –

0

Vous pouvez essayer les CarouselView pour mettre en œuvre les fonctionnalités flip flop sous forme de Xamarin ici est par exemple - https://blog.xamarin.com/flip-through-items-with-xamarin-forms-carouselview/

Si vous essayez de mettre en œuvre Xamarin natif s'il vous plaît vérifier le lien ci-dessous pour IOS et Android.

IOS- https://github.com/jzeferino/Xamarin.iOS.iCarousel

Android- https://github.com/MobMaxime/xamarin-android-samples/tree/master/CarouselViewProject-master

+0

Tout d'abord, je suis à l'aide Xamarin autochtone. En second lieu, pour le téléphone Windows. :) –

+0

Je ne sais pas quelle est votre exigence et pourquoi utilisez-vous xamarin uniquement pour le développement d'applications Windows. Considérant que le studio visuel ayant également l'option de projet UWP pour développer l'application Windows Universal. –