我已经在SKCanvasView
上创建了楼层地图。在SKCanvasview
上绘制位图图像,并向画布视图添加了平移手势和捏合手势。滚动图像后,它不受限制并在画布上移动。缩放也不受限制。我试图限制平移和放大和缩小画布位图图像,但是它不起作用。
请在此问题上提供帮助,
预先感谢 这是代码。
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.IO;
using System.Net;
using ICSharpCode.SharpZipLib.Zip;
using Xamarin.Forms;
using PCLStorage;
using ICSharpCode.SharpZipLib.Core;
using System.Reflection;
using SkiaSharp;
using SkiaSharp.Views.Forms;
using Acr.UserDialogs;
using FileDownloadDemo.Extensions;
namespace FileDownloadDemo
{
public partial class DownloadingPage : ContentPage
{
private bool _isFirstTime = true;
private bool _isMapDrawing = false;
private double max_zoom_level = 10;
private double org_img_height = 4481;
private double org_img_width = 6033;
private int img_chunk_size = 200;
private List<ZoomFactors> zoomFactorList;
int zoom_level = 10;
double canvas_total_col, canvas_total_row;
double map_total_col, map_total_row;
int col_last, row_last;
//Zoom in out
private SKMatrix _m = SKMatrix.MakeIdentity();
private SKMatrix _startPanM = SKMatrix.MakeIdentity();
private SKMatrix _startPinchM = SKMatrix.MakeIdentity();
private Point _startPinchAnchor = Point.Zero;
private float _totalPinchScale = 1f;
private float _screenScale = App._screenScale;
private float scrollPosition_X = 0;
private float rotateAngle = 10;
bool isBeingpanning;
double x, y;
bool isRotatingCanvas;
// Changes
Point pinchTranslation;
SKMatrix canvasTranslation;
int row_start = 0, col_start = 0;
SKImage finalImage = null;
SKCanvas canvas;
SKSurface mainSurface = null;
double currentScale = 1;
double startScale = 1;
double xOffset = 0;
double yOffset = 0;
double originalWidth = 6033;
double originalHeight = 4481;
double ScreenWidth;
double ScreenHeight;
public DownloadingPage()
{
InitializeComponent();
InitializeComponent();
map_total_col = Math.Round(org_img_width * 0.1 * zoom_level / img_chunk_size);
map_total_row = Math.Round(org_img_height * 0.1 * zoom_level / img_chunk_size);
}
void Handle_PaintSurface(object sender, SkiaSharp.Views.Forms.SKPaintSurfaceEventArgs e)
{
drawMap(e);
}
private void drawMap(SKPaintSurfaceEventArgs e)
{
SKSurface surface = e.Surface;
canvas = surface.Canvas;
canvas.Clear(SKColors.BlanchedAlmond);
e.Surface.Canvas.SetMatrix(_m);
double canvas_width = e.Info.Width;
double canvas_height = e.Info.Height;
xOffset = _canvasV.TranslationX;
yOffset = _canvasV.TranslationY;
currentScale = _canvasV.Scale;
if (_isMapDrawing) return;
_isMapDrawing = true;
SKPaint thickLinePaint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.Blue,
StrokeWidth = 10,
StrokeCap = SKStrokeCap.Round,
};
if (_isFirstTime)
{
canvas_total_col = Math.Round(canvas_width / img_chunk_size);
canvas_total_row = Math.Round(canvas_height / img_chunk_size);
_isFirstTime = false;
}
col_last = (int)Math.Min(col_start + canvas_total_col, zoomFactorList[zoom_level - 1].no_of_cols);
row_last = (int)Math.Min(row_start + canvas_total_row, zoomFactorList[zoom_level - 1].no_of_rows);
if (finalImage == null)
finalImage = combineImage(0, 0, 2 * row_last, 2 * col_last);
using (var paint = new SKPaint())
{
SKSize imgSize = new SKSize(finalImage.Width, finalImage.Height);
canvas.DrawImage(finalImage, new SKPoint(0, 0), paint);
}
canvas.Save();
canvas.Restore();
_isMapDrawing = false;
}
private void Handle_PinchUpdated(object sender, PinchGestureUpdatedEventArgs puea)
{
Console.WriteLine(puea.Status + " (" + puea.ScaleOrigin.X + "," + puea.ScaleOrigin.Y + ") " + puea.Scale);
Point canvasAnchor = new Point(puea.ScaleOrigin.X * _canvasV.Width * _screenScale,
puea.ScaleOrigin.Y * _canvasV.Height * _screenScale);
switch (puea.Status)
{
case GestureStatus.Started:
_startPinchM = _m;
_startPinchAnchor = canvasAnchor;
_totalPinchScale = 1f;
break;
case GestureStatus.Running:
_totalPinchScale *= (float)puea.Scale;
Point pinchTranslation = canvasAnchor.Offset(-_startPinchAnchor.X, -_startPinchAnchor.Y);
SKMatrix canvasTranslation = SKMatrix.MakeTranslation((float)pinchTranslation.X, (float)pinchTranslation.Y);
SKMatrix canvasScaling = SKMatrix.MakeScale(_totalPinchScale, _totalPinchScale, (float)canvasAnchor.X, (float)canvasAnchor.Y);
SKMatrix canvasCombined = SKMatrix.MakeIdentity();
SKMatrix.Concat(ref canvasCombined, ref canvasScaling, ref canvasTranslation);
SKMatrix.Concat(ref _m, ref canvasCombined, ref _startPinchM);
_canvasV.InvalidateSurface();
break;
default:
_startPinchM = SKMatrix.MakeIdentity();
_startPinchAnchor = Point.Zero;
_totalPinchScale = 1f;
break;
}
}
private void Handle_PanUpdated(object sender, PanUpdatedEventArgs puea)
{
Console.WriteLine(puea.StatusType + " (" + puea.TotalX + "," + puea.TotalY + ")");
switch (puea.StatusType)
{
case GestureStatus.Started:
_startPanM = _m;
double xTrans = xOffset + puea.TotalX;
double yTrans = yOffset + puea.TotalY;
// do not allow verical scorlling unless the image size is bigger than the screen
_canvasV.TranslateTo(xTrans, yTrans, 0, Easing.Linear);
break;
case GestureStatus.Running:
float canvasTotalX = (float)puea.TotalX * _screenScale;
float canvasTotalY = (float)puea.TotalY * _screenScale;
SKMatrix canvasTranslation = SKMatrix.MakeTranslation(canvasTotalX, canvasTotalY);
SKMatrix.Concat(ref _m, ref canvasTranslation, ref _startPanM);
_canvasV.TranslationX = Math.Max(Math.Min(0, x + e.TotalX), -Math.Abs(org_img_width - App._screenWidth));
_canvasV.TranslationY = Math.Max(Math.Min(0, y + e.TotalY), -Math.Abs(org_img_height - App._screenHeight));
_canvasV.InvalidateSurface();
break;
default:
_startPanM = SKMatrix.MakeIdentity();
break;
}
}
}
}