[C#/MAUI/.NET6] PinchGestureRecognizer 클래스 : PinchUpdated 업데이트를 사용해 핀치 처리하기 (기능 개선)
C#/MAUI 2022. 6. 18. 12:42728x90
반응형
728x170
▶ DoubleExtension.cs
namespace TestProject;
/// <summary>
/// 배정도 실수 확장
/// </summary>
public static class DoubleExtension
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Public
#region 고정하기 - Clamp(sourceValue, minimumValue, maxiumValue)
/// <summary>
/// 고정하기
/// </summary>
/// <param name="sourceValue">소스 값</param>
/// <param name="minimumValue">최소 값</param>
/// <param name="maxiumValue">최대 값</param>
/// <returns>고정 값</returns>
public static double Clamp(this double sourceValue, double minimumValue, double maxiumValue)
{
return Math.Min (maxiumValue, Math.Max (sourceValue, minimumValue));
}
#endregion
}
728x90
▶ PinchContentView.cs
namespace TestProject;
/// <summary>
/// 핀치 컨텐트 뷰
/// </summary>
public class PinchContentView : Frame
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 현재 스케일
/// </summary>
private double currentScale = 1;
/// <summary>
/// 시작 스케일
/// </summary>
private double startScale = 1;
/// <summary>
/// 오프셋 X
/// </summary>
private double officeX = 0;
/// <summary>
/// 오프셋 Y
/// </summary>
private double officeY = 0;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - PinchContentView()
/// <summary>
/// 생성자
/// </summary>
public PinchContentView()
{
Padding = new Thickness(0);
IsClippedToBounds = true;
PinchGestureRecognizer recognizer = new PinchGestureRecognizer();
recognizer.PinchUpdated += recognizer_PinchUpdated;
GestureRecognizers.Add(recognizer);
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 인식기 핀치 업데이트시 처리하기 - recognizer_PinchUpdated(sender, e)
/// <summary>
/// 인식기 핀치 업데이트시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void recognizer_PinchUpdated(object sender, PinchGestureUpdatedEventArgs e)
{
if(e.Status == GestureStatus.Started)
{
this.startScale = Content.Scale;
Content.AnchorX = 0;
Content.AnchorY = 0;
}
else if(e.Status == GestureStatus.Running)
{
this.currentScale += (e.Scale - 1) * this.startScale;
this.currentScale = Math.Max(1, this.currentScale);
double renderedX = Content.X + this.officeX;
double deltaX = renderedX / Width;
double deltaWidth = Width / (Content.Width * this.startScale);
double originX = (e.ScaleOrigin.X - deltaX) * deltaWidth;
double renderedY = Content.Y + this.officeY;
double deltaY = renderedY / Height;
double deltaHeight = Height / (Content.Height * this.startScale);
double originY = (e.ScaleOrigin.Y - deltaY) * deltaHeight;
double targetX = this.officeX - (originX * Content.Width ) * (this.currentScale - this.startScale);
double targetY = this.officeY - (originY * Content.Height) * (this.currentScale - this.startScale);
Content.TranslationX = targetX.Clamp(-Content.Width * (this.currentScale - 1), 0);
Content.TranslationY = targetY.Clamp(-Content.Height * (this.currentScale - 1), 0);
Content.Scale = this.currentScale;
}
else if(e.Status == GestureStatus.Completed)
{
this.officeX = Content.TranslationX;
this.officeY = Content.TranslationY;
}
}
#endregion
}
300x250
▶ MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage x:Class="TestProject.MainPage"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TestProject">
<local:PinchContentView
HorizontalOptions="Center"
VerticalOptions="Center"
WidthRequest="300"
HeightRequest="300">
<Image Source="source.png"
WidthRequest="300"
HeightRequest="300"
Aspect="Fill" />
</local:PinchContentView>
</ContentPage>
728x90
반응형
그리드형(광고전용)
댓글을 달아 주세요