我想创建一种功能,可以在另一个背景图像上点击并添加固定图像,并且背景图像应该能够缩放和平移,这是此的XAML代码,此处缩小缩放不起作用,但是点击事件有效工作正常
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:POC"
xmlns:ui="clr-namespace:Vapolia.Lib.Ui;assembly=XamarinFormsGesture"
x:Class="POC.MainPage"
Title="Main Page">
<ScrollView AbsoluteLayout.LayoutFlags="All">
<local:PinchAndPanContainer>
<local:PinchAndPanContainer.Content >
<AbsoluteLayout x:Name="AbsoluteLayoutForImage">
<Image x:Name="FloorPlanImage"
Source="Capture2.png"
HeightRequest="400"
IsEnabled="True"
InputTransparent="True"
ui:Gesture.TapCommand2="{Binding TapCommand2}"/>//This Property
</AbsoluteLayout>
</local:PinchAndPanContainer.Content>
</local:PinchAndPanContainer>
</ScrollView>
在cs文件中,此tap命令使用Point中的坐标在绝对布局内添加一个引脚图像。
public Command<Point> TapCommand2 => new Command<Point>(point =>
{
AddPin(point);
});
现在,如果我们只是从上面的代码中移除ui:Gesture.TapCommand2="{Binding TapCommand2}"
,则平移和平移效果很好。
对于Tap事件,我使用了Vapolia.XamarinFormsGesture NuGet包,对于平放使用了xamarin形式的Gesture Recognizer 谁能帮忙
答案 0 :(得分:1)
最近我做了类似的功能,最终创建了如下的CustomControl:
注意:如果您不使用FFImage,请在我的课程中使用FFImageLoadings CachedImage,只需将其替换为默认的xamarin表单图像即可。
它具有以下功能:PanSwipe,Zoom和DoubleTap进行缩放。
using System;
using Xamarin.Forms;
using FFImageLoading.Forms;
public class ZoomableImage : CachedImage //In case not using ff image replace this with the Image control
{
private const double MIN_SCALE = 1;
private const double MAX_SCALE = 4;
private const double OVERSHOOT = 0.15;
private double StartScale, LastScale;
private double StartX, StartY;
public ZoomableImage()
{
var pinch = new PinchGestureRecognizer();
pinch.PinchUpdated += OnPinchUpdated;
GestureRecognizers.Add(pinch);
var pan = new PanGestureRecognizer();
pan.PanUpdated += OnPanUpdated;
GestureRecognizers.Add(pan);
var tap = new TapGestureRecognizer { NumberOfTapsRequired = 2 };
tap.Tapped += OnTapped;
GestureRecognizers.Add(tap);
Scale = MIN_SCALE;
TranslationX = TranslationY = 0;
AnchorX = AnchorY = 0;
}
protected override SizeRequest OnMeasure(double widthConstraint, double heightConstraint)
{
Scale = MIN_SCALE;
TranslationX = TranslationY = 0;
AnchorX = AnchorY = 0;
return base.OnMeasure(widthConstraint, heightConstraint);
}
private void OnTapped(object sender, EventArgs e)
{
if (Scale > MIN_SCALE)
{
this.ScaleTo(MIN_SCALE, 250, Easing.CubicInOut);
this.TranslateTo(0, 0, 250, Easing.CubicInOut);
}
else
{
AnchorX = AnchorY = 0.5; //TODO tapped position
this.ScaleTo(MAX_SCALE, 250, Easing.CubicInOut);
}
}
private void OnPanUpdated(object sender, PanUpdatedEventArgs e)
{
switch (e.StatusType)
{
case GestureStatus.Started:
StartX = (1 - AnchorX) * Width;
StartY = (1 - AnchorY) * Height;
break;
case GestureStatus.Running:
AnchorX = Clamp(1 - (StartX + e.TotalX) / Width, 0, 1);
AnchorY = Clamp(1 - (StartY + e.TotalY) / Height, 0, 1);
break;
}
}
private void OnPinchUpdated(object sender, PinchGestureUpdatedEventArgs e)
{
switch (e.Status)
{
case GestureStatus.Started:
LastScale = e.Scale;
StartScale = Scale;
AnchorX = e.ScaleOrigin.X;
AnchorY = e.ScaleOrigin.Y;
break;
case GestureStatus.Running:
if (e.Scale < 0 || Math.Abs(LastScale - e.Scale) > (LastScale * 1.3) - LastScale)
{ return; }
LastScale = e.Scale;
var current = Scale + (e.Scale - 1) * StartScale;
Scale = Clamp(current, MIN_SCALE * (1 - OVERSHOOT), MAX_SCALE * (1 + OVERSHOOT));
break;
case GestureStatus.Completed:
if (Scale > MAX_SCALE)
this.ScaleTo(MAX_SCALE, 250, Easing.SpringOut);
else if (Scale < MIN_SCALE)
this.ScaleTo(MIN_SCALE, 250, Easing.SpringOut);
break;
}
}
private T Clamp<T>(T value, T minimum, T maximum) where T: IComparable
{
if (value.CompareTo(minimum) < 0)
return minimum;
else if (value.CompareTo(maximum) > 0)
return maximum;
else
return value;
}
}
祝你好运, 如有查询,请还原。