如何限制SKCanvasView的平移和缩放?

时间:2018-06-28 10:07:32

标签: xamarin canvas xamarin.forms skiasharp

我已经在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;
        }


    }

}

}

enter image description here

0 个答案:

没有答案