SkiaSharp에서 손가락 그림판
손가락을 사용하여 캔버스에 페인트합니다.
개체를 SKPath
지속적으로 업데이트하고 표시할 수 있습니다. 이 기능을 사용하면 손가락 그리기 프로그램과 같은 대화형 그리기에 경로를 사용할 수 있습니다.
터치 지원 Xamarin.Forms 은 화면에서 개별 손가락을 추적하는 것을 허용하지 않으므로 Xamarin.Forms 터치 추적 효과가 개발되어 추가 터치 지원을 제공합니다. 이 효과는 효과에서 이벤트 호출 문서에 설명되어 있습니다. 샘플 프로그램에는 손가락 그리기 프로그램을 포함하여 SkiaSharp를 사용하는 두 페이지가 포함되어 있습니다.
샘플 솔루션에는 이 터치 추적 이벤트가 포함됩니다. .NET Standard 라이브러리 프로젝트에는 클래스, TouchActionType
열거형, TouchActionEventHandler
대리자 및 클래스가 TouchActionEventArgs
포함됩니다TouchEffect
. 각 플랫폼 프로젝트에는 해당 플랫폼에 대한 클래스가 포함 TouchEffect
되며 iOS 프로젝트에는 클래스도 포함됩니다 TouchRecognizer
.
SkiaSharpFormsDemos의 핑거 그림판 페이지는 손가락 그리기의 간소화된 구현입니다. 색이나 스트로크 너비를 선택할 수 없으며 캔버스를 지울 방법이 없으며 아트워크를 저장할 수 없습니다.
Finger그림판Page.xaml 파일은 단일 셀 Grid
에 넣고 다음Grid
을 연결합니다TouchEffect
.SKCanvasView
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:skia="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms"
xmlns:tt="clr-namespace:TouchTracking"
x:Class="SkiaSharpFormsDemos.Paths.FingerPaintPage"
Title="Finger Paint">
<Grid BackgroundColor="White">
<skia:SKCanvasView x:Name="canvasView"
PaintSurface="OnCanvasViewPaintSurface" />
<Grid.Effects>
<tt:TouchEffect Capture="True"
TouchAction="OnTouchEffectAction" />
</Grid.Effects>
</Grid>
</ContentPage>
직접 연결해도 TouchEffect
SKCanvasView
모든 플랫폼에서 작동하지는 않습니다.
Finger그림판Page.xaml.cs 코드 숨김 파일은 개체를 저장하기 SKPath
위한 두 개의 컬렉션과 SKPaint
이러한 경로를 렌더링하기 위한 개체를 정의합니다.
public partial class FingerPaintPage : ContentPage
{
Dictionary<long, SKPath> inProgressPaths = new Dictionary<long, SKPath>();
List<SKPath> completedPaths = new List<SKPath>();
SKPaint paint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.Blue,
StrokeWidth = 10,
StrokeCap = SKStrokeCap.Round,
StrokeJoin = SKStrokeJoin.Round
};
public FingerPaintPage()
{
InitializeComponent();
}
...
}
이름에서 설명한 대로 사전은 inProgressPaths
하나 이상의 손가락으로 현재 그려지는 경로를 저장합니다. 사전 키는 터치 이벤트와 함께 제공되는 터치 ID입니다. completedPaths
필드는 경로를 그리는 손가락이 화면에서 들어올릴 때 완료된 경로의 컬렉션입니다.
TouchAction
처리기는 이러한 두 컬렉션을 관리합니다. 손가락이 화면을 처음 터치하면 새 SKPath
손가락이 추가 inProgressPaths
됩니다. 손가락이 이동하면 경로에 추가 지점이 추가됩니다. 손가락을 놓으면 경로가 컬렉션으로 completedPaths
전송됩니다. 여러 손가락으로 동시에 그릴 수 있습니다. 경로 또는 컬렉션 SKCanvasView
중 하나로 변경될 때마다 무효화됩니다.
public partial class FingerPaintPage : ContentPage
{
...
void OnTouchEffectAction(object sender, TouchActionEventArgs args)
{
switch (args.Type)
{
case TouchActionType.Pressed:
if (!inProgressPaths.ContainsKey(args.Id))
{
SKPath path = new SKPath();
path.MoveTo(ConvertToPixel(args.Location));
inProgressPaths.Add(args.Id, path);
canvasView.InvalidateSurface();
}
break;
case TouchActionType.Moved:
if (inProgressPaths.ContainsKey(args.Id))
{
SKPath path = inProgressPaths[args.Id];
path.LineTo(ConvertToPixel(args.Location));
canvasView.InvalidateSurface();
}
break;
case TouchActionType.Released:
if (inProgressPaths.ContainsKey(args.Id))
{
completedPaths.Add(inProgressPaths[args.Id]);
inProgressPaths.Remove(args.Id);
canvasView.InvalidateSurface();
}
break;
case TouchActionType.Cancelled:
if (inProgressPaths.ContainsKey(args.Id))
{
inProgressPaths.Remove(args.Id);
canvasView.InvalidateSurface();
}
break;
}
}
...
SKPoint ConvertToPixel(Point pt)
{
return new SKPoint((float)(canvasView.CanvasSize.Width * pt.X / canvasView.Width),
(float)(canvasView.CanvasSize.Height * pt.Y / canvasView.Height));
}
}
터치 추적 이벤트와 함께 제공되는 포인트는 좌표이며 Xamarin.Forms , 픽셀인 SkiaSharp 좌표로 변환해야 합니다. 이것이 메서드의 목적입니다 ConvertToPixel
.
PaintSurface
그런 다음, 처리기는 두 경로 컬렉션을 모두 렌더링합니다. 이전에 완료된 경로는 진행 중인 경로 아래에 표시됩니다.
public partial class FingerPaintPage : ContentPage
{
...
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKCanvas canvas = args.Surface.Canvas;
canvas.Clear();
foreach (SKPath path in completedPaths)
{
canvas.DrawPath(path, paint);
}
foreach (SKPath path in inProgressPaths.Values)
{
canvas.DrawPath(path, paint);
}
}
...
}
손가락 그림은 재능에 의해서만 제한됩니다.
이제 파라메트릭 수식을 사용하여 선을 그리고 곡선을 정의하는 방법을 살펴보았습니다. SkiaSharp 곡선 및 경로에 대한 이후 섹션에서는 지원하는 다양한 유형의 곡선에 대해 SKPath
설명합니다. 그러나 유용한 필수 조건은 SkiaSharp 변환을 탐색하는 것입니다.