Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 134 additions & 0 deletions Uno.Gallery/Helpers/Canvas/SampleSKCanvasElement.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
#if HAS_UNO_SKIA
using SkiaSharp;
using Uno.WinUI.Graphics2DSK;
using Windows.Foundation;

namespace Uno.Gallery.Helpers.Canvas;

public class SampleSKCanvasElement : SKCanvasElement
{
public static int SampleCount => 3;

public static DependencyProperty SampleProperty { get; } = DependencyProperty.Register(
nameof(Sample),
typeof(int),
typeof(SampleSKCanvasElement),
new PropertyMetadata(0, (o, args) => ((SampleSKCanvasElement)o).SampleChanged((int)args.NewValue)));

public int Sample
{
get => (int)GetValue(SampleProperty);
set => SetValue(SampleProperty, value);
}

private void SampleChanged(int newIndex)
{
Sample = Math.Min(Math.Max(0, newIndex), SampleCount - 1);
Invalidate();
}

protected override void RenderOverride(SKCanvas canvas, Size area)
{
var minDim = Math.Min(area.Width, area.Height);
// draw horizontally centered
var x = (area.Width - minDim) / 2;
var y = (area.Height - minDim) / 2;
canvas.Translate((float)x, (float)y);
// rescale to fit the given area, assuming each drawing is 260x260
canvas.Scale((float)(minDim / 260), (float)(minDim / 260));

switch (Sample)
{
case 0:
SkiaDrawing0(canvas);
break;
case 1:
SkiaDrawing1(canvas);
break;
case 2:
SkiaDrawing2(canvas);
break;
}
}

// https://fiddle.skia.org/c/@shapes
private void SkiaDrawing0(SKCanvas canvas)
{
var paint = new SKPaint();
paint.Style = SKPaintStyle.Fill;
paint.IsAntialias = true;
paint.StrokeWidth = 4;
paint.Color = new SKColor(0xff4285F4);

var rect = SKRect.Create(10, 10, 100, 160);
canvas.DrawRect(rect, paint);

var oval = new SKPath();
oval.AddRoundRect(rect, 20, 20);
oval.Offset(new SKPoint(40, 80));
paint.Color = new SKColor(0xffDB4437);
canvas.DrawPath(oval, paint);

paint.Color = new SKColor(0xff0F9D58);
canvas.DrawCircle(180, 50, 25, paint);

rect.Offset(80, 50);
paint.Color = new SKColor(0xffF4B400);
paint.Style = SKPaintStyle.Stroke;
canvas.DrawRoundRect(rect, 10, 10, paint);
}

// https://fiddle.skia.org/c/@bezier_curves
private void SkiaDrawing1(SKCanvas canvas)
{
var paint = new SKPaint();
paint.Style = SKPaintStyle.Stroke;
paint.StrokeWidth = 8;
paint.Color = new SKColor(0xff4285F4);
paint.IsAntialias = true;
paint.StrokeCap = SKStrokeCap.Round;

var path = new SKPath();
path.MoveTo(10, 10);
path.QuadTo(256, 64, 128, 128);
path.QuadTo(10, 192, 250, 250);
canvas.DrawPath(path, paint);
}

// https://fiddle.skia.org/c/@shader
private void SkiaDrawing2(SKCanvas canvas)
{
var paint = new SKPaint();
using var pathEffect = SKPathEffect.CreateDiscrete(10.0f, 4.0f);
paint.PathEffect = pathEffect;
SKPoint[] points =
{
new SKPoint(0.0f, 0.0f),
new SKPoint(256.0f, 256.0f)
};
SKColor[] colors =
{
new SKColor(66, 133, 244),
new SKColor(15, 157, 88)
};
paint.Shader = SKShader.CreateLinearGradient(points[0], points[1], colors, SKShaderTileMode.Clamp);
paint.IsAntialias = true;
var path = Star();
canvas.DrawPath(path, paint);

SKPath Star()
{
const float R = 60.0f, C = 128.0f;
var path = new SKPath();
path.MoveTo(C + R, C);
for (var i = 1; i < 15; ++i)
{
var a = 0.44879895f * i;
var r = R + R * (i % 2);
path.LineTo((float)(C + r * Math.Cos(a)), (float)(C + r * Math.Sin(a)));
}
return path;
}
}
}
#endif
49 changes: 49 additions & 0 deletions Uno.Gallery/Views/SamplePages/SKCanvasElementPage.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<Page x:Class="Uno.Gallery.Views.SamplePages.SKCanvasElementPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Uno.Gallery"
xmlns:samples="using:Uno.Gallery.Views.Samples"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:smtx="using:ShowMeTheXAML"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<local:SamplePageLayout IsDesignAgnostic="True">
<local:SamplePageLayout.DesignAgnosticTemplate>
<DataTemplate>
<smtx:XamlDisplay UniqueKey="SKCanvasElementPage_Basic"
smtx:XamlDisplayExtensions.Header="Basic SKCanvasElement">
<Grid>
<Grid RowSpacing="20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Button HorizontalAlignment="Center"
Click="NextSample_Click">
Next sample
</Button>
<Grid Height="140"
Grid.Row="1"
x:Name="SKContainer" />
</Grid>
Comment on lines +19 to +31
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<Grid RowSpacing="20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Button HorizontalAlignment="Center"
Click="NextSample_Click">
Next sample
</Button>
<Grid Height="140"
Grid.Row="1"
x:Name="SKContainer" />
</Grid>
<Grid RowDefinitions="Auto,*" RowSpacing="20">
<Button Content="Next sample" Click="NextSample_Click" HorizontalAlignment="Center" />
<Grid Grid.Row="1" x:Name="SKContainer" Height="140"/>
</Grid>

</Grid>

<!--
C# code
public class SampleSKCanvasElement : SKCanvasElement
{
protected override void RenderOverride(SKCanvas canvas, Size area)
{
// Custom rendering logic goes here
}
}
-->
Comment on lines +34 to +43
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idk if it is possible, maybe we can use CDATA here to avoid xamlstyler messing up the indendations?

</smtx:XamlDisplay>
</DataTemplate>
</local:SamplePageLayout.DesignAgnosticTemplate>
</local:SamplePageLayout>
</Grid>
</Page>
53 changes: 53 additions & 0 deletions Uno.Gallery/Views/SamplePages/SKCanvasElementPage.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
#if HAS_UNO_SKIA
using Uno.Gallery.Helpers.Canvas;
#endif

namespace Uno.Gallery.Views.SamplePages;

#if HAS_UNO_SKIA
[SamplePage(SampleCategory.UIComponents, "SKCanvasElement", Description = "Represents a 2D graphics canvas.", DocumentationLink = "https://platform.uno/docs/articles/controls/SKCanvasElement.html")]
Comment thread
MartinZikmund marked this conversation as resolved.
#endif
public sealed partial class SKCanvasElementPage : Page
{
#if HAS_UNO_SKIA
public int MaxSampleIndex => SampleSKCanvasElement.SampleCount - 1;

private SampleSKCanvasElement _canvasElement;
#endif

public SKCanvasElementPage()
{
this.InitializeComponent();

this.Loaded += SKCanvasElementPage_Loaded;
}

private void SKCanvasElementPage_Loaded(object sender, RoutedEventArgs e)
{
#if HAS_UNO_SKIA
var container = (Grid)FindName("SKContainer");
container.Children.Add(_canvasElement = new SampleSKCanvasElement());
#endif
}

private void NextSample_Click(object sender, RoutedEventArgs e)
{
#if HAS_UNO_SKIA
_canvasElement.Sample = (_canvasElement.Sample + 1) % SampleSKCanvasElement.SampleCount;
#endif
}
}
Loading