This is a migrated thread and some comments may be shown as answers.

Support for "flick"?

5 Answers 72 Views
PanAndZoomImage
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Philip
Top achievements
Rank 2
Philip asked on 10 Aug 2012, 01:37 PM
I've installed the Telerik sample app on my phone and I'm particularly interested in using the PanAndZoom control.
When you zoom into the image, it doesn't seem to be possible to scroll, exactly. The behaviour seems to be that you swipe your finger and the image moves a bit but then stops. If you try to "flick", as you might do on a list, the image does not move a greater distance - it still only moves a smallish amount and then stops.
Is there a way for the control to provide a smoother scrolling behaviour? I want to make sure the control will meet my needs before purchasing it.
Thanks.
Philip

5 Answers, 1 is accepted

Sort by
0
Victor
Telerik team
answered on 10 Aug 2012, 01:52 PM
Hi Philip,

Thanks for writing.
Current PanAndZoomImage does not support the flick gesture however this is a great feature and we will probably implement it in a future release.

Please write again if you have other questions.

Regards,
Victor
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Bart
Top achievements
Rank 1
answered on 11 Jun 2014, 11:29 AM
It's been nearly two years since this request was made. I recently started using this control and I'd like to know if there's any update.
0
Tsvyatko
Telerik team
answered on 16 Jun 2014, 09:11 AM
Hello Bart,

Thank you for contacting us. With the current release we do not support this feature. However, in the light 
of windows universal application solution we are re-evaluating all customer feedback, so we will reconsider this feature as well.

Regards,
Tsvyatko
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Sven
Top achievements
Rank 1
answered on 21 Jun 2014, 01:09 PM
Hello Tsvyatko,

thanks for that info. I'd really like to see an integrated flick within the PanAndZoomImage.

@Bart and all others who are looking for a flick animation and can't wait until Telerik integrates one:
I've used the following code to get an acceptable flick within one of my apps. It's still not perfect but didn't received any complaints yet.

There might be some members you don't need/want, e.g. the ColorTheme. I'm using it to let the user customize the look of the app.
In addition there's an event called AlternateDoubleTap. It's kind of hackish. I'm subscribing to the Tap and DoubleTap event. Unfortunately both are fired on double tap. To work around I fire the AlternateDoubleTap first to indicate that it's not a single tap.

Please review the code below. Feel free to play around with the InertiaDeceleration property.

001.namespace DirtySharp.Phone.NineGAG.Controls
002.{
003.  using System;
004.  using System.Windows;
005.  using System.Windows.Controls;
006.  using System.Windows.Input;
007.  using System.Windows.Media.Animation;
008.  using DirtySharp.Phone.NineGAG.Theming;
009.  using Telerik.Windows.Controls;
010.  using GestureEventArgs = System.Windows.Input.GestureEventArgs;
011. 
012.  public class PanAndZoomImage : Telerik.Windows.Controls.SlideView.PanAndZoomImage
013.  {
014.    #region Events
015. 
016.    public event EventHandler<GestureEventArgs> AlternateDoubleTap;
017. 
018.    protected virtual void RaiseAlternateDoubleTap( GestureEventArgs e )
019.    {
020.      var handler = AlternateDoubleTap;
021.      if ( handler != null ) handler( this, e );
022.    }
023. 
024.    #endregion
025. 
026. 
027.    #region Private Fields
028. 
029.    private Image _image;
030. 
031.    private readonly Storyboard _flick;
032. 
033.    private readonly Storyboard _panAndZoom;
034. 
035.    private readonly PointAnimation _flickAnimation;
036. 
037.    private readonly PointAnimation _panAnimation;
038. 
039.    private readonly DoubleAnimation _zoomAnimation;
040. 
041.    private static readonly ColorTheme Theme = new ColorTheme();
042. 
043.    private double _maxPanDown;
044. 
045.    private double _maxPanUp;
046. 
047.    #endregion
048. 
049. 
050.    #region Constructor
051. 
052.    public PanAndZoomImage()
053.    {
054.      // flick
055.      var easing = new CircleEase { EasingMode = EasingMode.EaseOut };
056.      _flickAnimation = new PointAnimation();
057.      _flickAnimation.EasingFunction = easing;
058.      _flickAnimation.Duration = new Duration( TimeSpan.FromMilliseconds( 1000 ) );
059. 
060.      Storyboard.SetTargetProperty( _flickAnimation, new PropertyPath( "Pan" ) );
061.      Storyboard.SetTarget( _flickAnimation, this );
062. 
063.      _flick = new Storyboard { AutoReverse = false };
064.      _flick.Children.Add( _flickAnimation );
065. 
066.      // pan and zoom, used for double tapping
067.      _panAnimation = new PointAnimation
068.      {
069.        Duration = new Duration( TimeSpan.FromMilliseconds( 150 ) ),
070.        EasingFunction = easing
071.      };
072. 
073.      _zoomAnimation = new DoubleAnimation
074.      {
075.        Duration = new Duration( TimeSpan.FromMilliseconds( 150 ) ),
076.        EasingFunction = easing,
077.        From = 1
078.      };
079. 
080.      Storyboard.SetTargetProperty( _panAnimation, new PropertyPath( "Pan" ) );
081.      Storyboard.SetTargetProperty( _zoomAnimation, new PropertyPath( "Zoom" ) );
082.      Storyboard.SetTarget( _panAnimation, this );
083.      Storyboard.SetTarget( _zoomAnimation, this );
084. 
085.      _panAndZoom = new Storyboard();
086.      _panAndZoom.Children.Add( _panAnimation );
087.      _panAndZoom.Children.Add( _zoomAnimation );
088. 
089.      Loaded += ( s, e ) => _image = ElementTreeHelper.FindVisualDescendant<Image>( this );
090.      ManipulationCompleted += DoFlick;
091.    }
092. 
093.    #endregion
094. 
095. 
096.    #region Dependency Properties
097. 
098.    public static readonly DependencyProperty InertiaDecelerationProperty = DependencyProperty.Register(
099.      "InertiaDeceleration", typeof (double), typeof (PanAndZoomImage), new PropertyMetadata( default( double ) ) );
100. 
101.    public double InertiaDeceleration
102.    {
103.      get { return (double) GetValue( InertiaDecelerationProperty ); }
104.      set { SetValue( InertiaDecelerationProperty, value ); }
105.    }
106. 
107.    #endregion
108. 
109. 
110.    #region Overrides of PanAndZoomImage
111. 
112.    public override void OnApplyTemplate()
113.    {
114.      base.OnApplyTemplate();
115. 
116.      var indicator = ElementTreeHelper.FindVisualDescendant<RadBusyIndicator>( this );
117.      if ( indicator != null )
118.      {
119.        indicator.Foreground = Theme.AccentBrush;
120.      }
121.    }
122. 
123.    protected override void OnDoubleTap( GestureEventArgs e )
124.    {
125.      RaiseAlternateDoubleTap( e );
126. 
127.      if ( Zoom > 1 )
128.      {
129.        Pan = new Point( 0, 0 );
130.        base.OnDoubleTap( e );
131.        return;
132.      }
133. 
134.      // decide whether to zoom horizontally or vertically
135.      var zoomX = RenderSize.Width / _image.RenderSize.Width;
136.      var zoomY = RenderSize.Height / _image.RenderSize.Height;
137.      var zoom = Math.Abs( Math.Round( zoomX, 0 ) - 1 ) < double.Epsilon
138.        ? (Math.Abs( zoomY - 1 ) < double.Epsilon ? zoomX : zoomY)
139.        : zoomX;
140.      if ( double.IsNaN( zoom ) || double.IsInfinity( zoom ) )
141.        return;
142. 
143.      // get pan range.
144.      double panRange = (zoom * RenderSize.Height) - RenderSize.Height;
145.      _maxPanUp = panRange / 2;
146.      _maxPanDown = -1 * _maxPanUp;
147. 
148.      // calculate final pan relative to the recent touch point.
149.      Point touch = e.GetPosition( _image );
150. 
151.      double halfHeight = RenderSize.Height / 2;
152.      bool isPanUp = touch.Y <= halfHeight;
153.      double touchY = touch.Y - (isPanUp ? 0 : halfHeight);
154.      double offset = touchY / halfHeight;
155.      double panY = isPanUp ? _maxPanUp - offset * _maxPanUp : offset * _maxPanDown;
156. 
157. 
158.      _panAnimation.From = new Point( 0, 0 );
159.      _panAnimation.To = new Point( 0, panY );
160.      _zoomAnimation.To = zoom;
161. 
162.      _panAndZoom.Begin();
163.    }
164. 
165.    #endregion
166. 
167. 
168.    #region Event Handler
169. 
170.    private void DoFlick( object sender, ManipulationCompletedEventArgs e )
171.    {
172.      if ( Math.Abs( Pan.Y - _maxPanUp ) < double.Epsilon ||
173.           Math.Abs( Pan.Y - _maxPanDown ) < double.Epsilon ) return;
174. 
175.      if ( Math.Abs( Zoom - 1 ) < double.Epsilon ) return;
176. 
177.      if ( Math.Abs( e.TotalManipulation.Scale.X ) > double.Epsilon ||
178.           Math.Abs( e.TotalManipulation.Scale.Y ) > double.Epsilon ) return;
179. 
180.      // stop flick on tap
181.      if ( e.IsTapGesture() )
182.      {
183.        _flickAnimation.To = Pan;
184.        _flick.SkipToFill();
185.        return;
186.      }
187. 
188.      if ( !e.IsInertial ) return;
189. 
190.      Point start = Pan;
191.      Size size = _image.RenderSize;
192.      double height = size.Height * Zoom;
193.      double width = size.Width * Zoom;
194.      Point velocity = e.FinalVelocities.LinearVelocity;
195.       
196.      double dx = velocity.X * Math.Min( InertiaDeceleration, Zoom );
197.      double dy = velocity.Y * Math.Min( InertiaDeceleration, Zoom );
198. 
199.      double sx = Math.Sign( dx );
200.      double sy = Math.Sign( dy );
201. 
202.      dx = sx * Math.Min( Math.Abs( dx ), width / 3 );
203.      dy = sy * Math.Min( Math.Abs( dy ), height / 3 );
204. 
205.      double endX = start.X + dx;
206.      double endY = start.Y + dy;
207.       
208.      _flickAnimation.From = start;
209.      _flickAnimation.To = new Point( endX, endY );
210.      _flick.Begin();
211.    }
212. 
213.    #endregion
214.  }
215.}

And the according XAML:
01.<Style x:Key="PanAndZoomImageStyle" TargetType="controls:PanAndZoomImage">
02.    <Setter Property="UseOptimizedManipulationRouting" Value="False"/>
03.    <Setter Property="CacheMode" Value="BitmapCache"/>
04.    <Setter Property="Template">
05.        <Setter.Value>
06.            <ControlTemplate TargetType="controls:PanAndZoomImage">
07.                <Border Background="#00FFFFFF">
08.                    <Grid>
09.                        <Image x:Name="image"
10.                                CacheMode="{TemplateBinding CacheMode}"
11.                                HorizontalAlignment="{TemplateBinding ImageHorizontalAlignment}"
12.                                RenderTransformOrigin="0.5, 0.5"
13.                                Source="{TemplateBinding Source}"
14.                                Stretch="{TemplateBinding Stretch}"
15.                                VerticalAlignment="{TemplateBinding ImageVerticalAlignment}" />
16.                        <telerikPrimitives:RadBusyIndicator x:Name="busyIndicator"
17.                                                            Style="{TemplateBinding BusyIndicatorStyle}"
18.                                                            Foreground="{TemplateBinding Tag}" />
19.                    </Grid>
20.                </Border>
21.            </ControlTemplate>
22.        </Setter.Value>
23.    </Setter>
24.    <Setter Property="BusyIndicatorStyle">
25.        <Setter.Value>
26.            <Style TargetType="telerikPrimitives:RadBusyIndicator">
27.                <Setter Property="InitialDelay" Value="00:00:0.3"/>
28.                <Setter Property="AnimationStyle" Value="AnimationStyle7"/>
29.            </Style>
30.        </Setter.Value>
31.    </Setter>
32.</Style>


1.<controls:PanAndZoomImage x:Name="PanAndZoomImage"
2.                          ZoomMode="Free"
3.                          MaximumZoom="25"
4.                          InertiaDeceleration="5"
5.                          ImageHorizontalAlignment="Stretch"
6.                          Style="{StaticResource PanAndZoomImageStyle}"
7.                          Source="..." />

If you need a "live preview" have a look at 9GAG Plus.

Best regards,
Sven
0
Lance | Manager Technical Support
Telerik team
answered on 25 Jun 2014, 03:28 PM
Hi Sven,

Thank you for sharing with the Telerik developer community, it is appreciated. As Tsvyatko stated, we are seriously considering including this functionality into a future release.

If you have any further suggestions, please do not hesitate to add them to this new forum thread dedicated solely for feature and control suggestions for the upcoming UI for Universal Windows Apps controls. We evaluate every suggestion with zeal and use your feedback to make the Telerik controls better.

Thank you for contacting Support and thank you for choosing Telerik.

Regards,
Lance | Senior Support Specialist
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
Tags
PanAndZoomImage
Asked by
Philip
Top achievements
Rank 2
Answers by
Victor
Telerik team
Bart
Top achievements
Rank 1
Tsvyatko
Telerik team
Sven
Top achievements
Rank 1
Lance | Manager Technical Support
Telerik team
Share this question
or