This question is locked. New answers and comments are not allowed.
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
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
0
Hi Philip,
Victor
the Telerik team
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.
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
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
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.
And the according XAML:
If you need a "live preview" have a look at 9GAG Plus.
Best regards,
Sven
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
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
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.