х
This commit is contained in:
parent
70ed01f058
commit
5dbd13040f
3 changed files with 79 additions and 23 deletions
|
|
@ -3,19 +3,21 @@
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||||
x:Class="NotesDataAnalyst.GraphPage"
|
x:Class="NotesDataAnalyst.GraphPage"
|
||||||
Title="GraphPage">
|
Title="GraphPage">
|
||||||
|
|
||||||
<ContentPage.Content>
|
<ContentPage.Content>
|
||||||
<Grid RowDefinitions="*,Auto" Padding="10">
|
<Grid Padding="10" RowDefinitions="*,Auto">
|
||||||
<!-- Канва для рисования занимает верхнюю часть экрана -->
|
<!-- Канва для рисования в отдельном ContentView -->
|
||||||
|
<ContentView Grid.Row="0">
|
||||||
<AbsoluteLayout Grid.Row="0">
|
<ContentView.GestureRecognizers>
|
||||||
|
<PanGestureRecognizer PanUpdated="OnPanUpdated"/>
|
||||||
|
<PinchGestureRecognizer PinchUpdated="OnPinchUpdated"/>
|
||||||
|
</ContentView.GestureRecognizers>
|
||||||
|
<AbsoluteLayout>
|
||||||
<GraphicsView x:Name="canvasView"
|
<GraphicsView x:Name="canvasView"
|
||||||
HeightRequest="8000"
|
HeightRequest="8000"
|
||||||
WidthRequest="8000"
|
WidthRequest="8000"/>
|
||||||
/>
|
|
||||||
|
|
||||||
</AbsoluteLayout>
|
</AbsoluteLayout>
|
||||||
|
</ContentView>
|
||||||
|
<ContentView Grid.Row="1">
|
||||||
<!-- Панель с кнопками внизу -->
|
<!-- Панель с кнопками внизу -->
|
||||||
<ScrollView Grid.Row="1" Orientation="Horizontal" HorizontalScrollBarVisibility="Always" VerticalScrollBarVisibility="Never">
|
<ScrollView Grid.Row="1" Orientation="Horizontal" HorizontalScrollBarVisibility="Always" VerticalScrollBarVisibility="Never">
|
||||||
<StackLayout Orientation="Horizontal" Spacing="1" Padding="20">
|
<StackLayout Orientation="Horizontal" Spacing="1" Padding="20">
|
||||||
|
|
@ -25,14 +27,14 @@
|
||||||
<Button Text="Редактировать текст" Clicked="OnEditTextClicked" />
|
<Button Text="Редактировать текст" Clicked="OnEditTextClicked" />
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
</ContentView>
|
||||||
<!-- Поле для редактирования текста -->
|
<!-- Поле для редактирования текста -->
|
||||||
<Entry x:Name="textEditor"
|
<Entry x:Name="textEditor"
|
||||||
IsVisible="False"
|
IsVisible="False"
|
||||||
BackgroundColor="White"
|
BackgroundColor="White"
|
||||||
TextColor="Black"
|
TextColor="Black"
|
||||||
FontSize="18"
|
FontSize="18"
|
||||||
Completed="OnTextEditorCompleted" />
|
Grid.Row="1" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</ContentPage.Content>
|
</ContentPage.Content>
|
||||||
</ContentPage>
|
</ContentPage>
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,15 @@ namespace NotesDataAnalyst
|
||||||
private bool _isNodeBeingMoved = false;
|
private bool _isNodeBeingMoved = false;
|
||||||
private const double SmoothFactor = 0.85; // Коэффициент сглаживания
|
private const double SmoothFactor = 0.85; // Коэффициент сглаживания
|
||||||
private Point _lastTranslation;
|
private Point _lastTranslation;
|
||||||
|
// Переменная для хранения центральной точки жеста (между двумя пальцами при старте масштабирования)
|
||||||
|
private Point _gestureCenter;
|
||||||
|
|
||||||
|
private Point _canvasTranslation = new Point(0, 0);
|
||||||
|
|
||||||
|
double currentScale = 1;
|
||||||
|
double startScale = 1;
|
||||||
|
double xOffset = 0;
|
||||||
|
double yOffset = 0;
|
||||||
|
|
||||||
public GraphPage()
|
public GraphPage()
|
||||||
{
|
{
|
||||||
|
|
@ -110,24 +119,57 @@ namespace NotesDataAnalyst
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private void OnPinchUpdated(object sender, PinchGestureUpdatedEventArgs e)
|
void OnPinchUpdated(object sender, PinchGestureUpdatedEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.Status == GestureStatus.Started)
|
if (e.Status == GestureStatus.Started)
|
||||||
{
|
{
|
||||||
// Сохраняем начальный масштаб
|
// Store the current scale factor applied to the wrapped user interface element,
|
||||||
_initialScale = _scale;
|
// and zero the components for the center point of the translate transform.
|
||||||
|
startScale = Content.Scale;
|
||||||
|
Content.AnchorX = 0;
|
||||||
|
Content.AnchorY = 0;
|
||||||
}
|
}
|
||||||
else if (e.Status == GestureStatus.Running)
|
if (e.Status == GestureStatus.Running)
|
||||||
{
|
{
|
||||||
// Вычисляем новый масштаб
|
// Calculate the scale factor to be applied.
|
||||||
_scale = Math.Max(0.5, Math.Min(_initialScale * e.Scale, 3.0));
|
currentScale += (e.Scale - 1) * startScale;
|
||||||
|
currentScale = Math.Max(1, currentScale);
|
||||||
|
|
||||||
// Применяем масштаб к канве
|
// The ScaleOrigin is in relative coordinates to the wrapped user interface element,
|
||||||
canvasView.Scale = _scale;
|
// so get the X pixel coordinate.
|
||||||
|
double renderedX = Content.X + xOffset;
|
||||||
|
double deltaX = renderedX / Width;
|
||||||
|
double deltaWidth = Width / (Content.Width * startScale);
|
||||||
|
double originX = (e.ScaleOrigin.X - deltaX) * deltaWidth;
|
||||||
|
|
||||||
|
// The ScaleOrigin is in relative coordinates to the wrapped user interface element,
|
||||||
|
// so get the Y pixel coordinate.
|
||||||
|
double renderedY = Content.Y + yOffset;
|
||||||
|
double deltaY = renderedY / Height;
|
||||||
|
double deltaHeight = Height / (Content.Height * startScale);
|
||||||
|
double originY = (e.ScaleOrigin.Y - deltaY) * deltaHeight;
|
||||||
|
|
||||||
|
// Calculate the transformed element pixel coordinates.
|
||||||
|
double targetX = xOffset - (originX * Content.Width) * (currentScale - startScale);
|
||||||
|
double targetY = yOffset - (originY * Content.Height) * (currentScale - startScale);
|
||||||
|
|
||||||
|
// Apply translation based on the change in origin.
|
||||||
|
Content.TranslationX = Math.Clamp(targetX, -Content.Width * (currentScale - 1), 0);
|
||||||
|
Content.TranslationY = Math.Clamp(targetY, -Content.Height * (currentScale - 1), 0);
|
||||||
|
|
||||||
|
// Apply scale factor
|
||||||
|
Content.Scale = currentScale;
|
||||||
|
}
|
||||||
|
if (e.Status == GestureStatus.Completed)
|
||||||
|
{
|
||||||
|
// Store the translation delta's of the wrapped user interface element.
|
||||||
|
xOffset = Content.TranslationX;
|
||||||
|
yOffset = Content.TranslationY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private async void OnEditTextClicked(object sender, EventArgs e)
|
private async void OnEditTextClicked(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
// Проверяем, выбрана ли нода
|
// Проверяем, выбрана ли нода
|
||||||
|
|
|
||||||
12
PinchToZoomContainer.cs
Normal file
12
PinchToZoomContainer.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace NotesDataAnalyst
|
||||||
|
{
|
||||||
|
internal class PinchToZoomContainer
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue