Skip to content

Commit

Permalink
Support ASP.NET Blazor Web Assembly Components (#1811)
Browse files Browse the repository at this point in the history
  • Loading branch information
mattleibow committed Oct 11, 2021
1 parent 7533b54 commit ce7778c
Show file tree
Hide file tree
Showing 94 changed files with 2,997 additions and 104 deletions.
4 changes: 3 additions & 1 deletion VERSIONS.txt
Expand Up @@ -26,8 +26,9 @@ Microsoft.WindowsAppSDK release 1.0.0-experimental1
Microsoft.WindowsAppSDK.Foundation release 1.0.0-experimental1
Microsoft.WindowsAppSDK.WinUI release 1.0.0-experimental1
Microsoft.WindowsAppSDK.InteractiveExperiences release 1.0.0-experimental1
Microsoft.Maui.Graphics release 6.0.100-preview.7.358
Microsoft.Maui.Graphics release 6.0.100-rc.1.413
Microsoft.Windows.SDK.NET.Ref release 10.0.18362.15
Microsoft.AspNetCore.Components.Web release 6.0.0-rc.1.21452.15

# additional references used by the tooling
OpenTK.GLControl reference 1.1.2349.61993
Expand Down Expand Up @@ -81,6 +82,7 @@ SkiaSharp.Views.WinUI nuget 2.88.0
SkiaSharp.Views.Maui.Core nuget 2.88.0
SkiaSharp.Views.Maui.Controls nuget 2.88.0
SkiaSharp.Views.Maui.Controls.Compatibility nuget 2.88.0
SkiaSharp.Views.Blazor nuget 2.88.0
SkiaSharp.HarfBuzz nuget 2.88.0
SkiaSharp.Vulkan.SharpVk nuget 2.88.0
HarfBuzzSharp nuget 2.8.2
Expand Down
3 changes: 3 additions & 0 deletions build.cake
Expand Up @@ -92,6 +92,7 @@ var TRACKED_NUGETS = new Dictionary<string, Version> {
{ "SkiaSharp.Views.Maui.Core", new Version (1, 57, 0) },
{ "SkiaSharp.Views.Maui.Controls", new Version (1, 57, 0) },
{ "SkiaSharp.Views.Maui.Controls.Compatibility", new Version (1, 57, 0) },
{ "SkiaSharp.Views.Blazor", new Version (1, 57, 0) },
{ "HarfBuzzSharp", new Version (1, 0, 0) },
{ "HarfBuzzSharp.NativeAssets.Android", new Version (1, 0, 0) },
{ "HarfBuzzSharp.NativeAssets.iOS", new Version (1, 0, 0) },
Expand All @@ -112,6 +113,8 @@ var PREVIEW_ONLY_NUGETS = new List<string> {
"SkiaSharp.Views.Maui.Core",
"SkiaSharp.Views.Maui.Controls",
"SkiaSharp.Views.Maui.Controls.Compatibility",
"SkiaSharp.Views.WinUI",
"SkiaSharp.Views.Blazor",
};

Information("Source Control:");
Expand Down
55 changes: 55 additions & 0 deletions nuget/SkiaSharp.Views.Blazor.nuspec
@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<package>
<metadata>

<!-- package -->
<id>SkiaSharp.Views.Blazor</id>
<title>SkiaSharp for ASP.NET Blazor</title>
<version>1.0.0</version>
<description>
SkiaSharp for ASP.NET Blazor is a set of views that can be used to draw on the screen.
</description>
<summary>
SkiaSharp for ASP.NET Blazor is a set of views that can be used to draw on the screen.
</summary>
<releaseNotes>
Please visit https://go.microsoft.com/fwlink/?linkid=868517 to view the release notes.
</releaseNotes>
<projectUrl>https://go.microsoft.com/fwlink/?linkid=868515</projectUrl>
<iconUrl>https://go.microsoft.com/fwlink/?linkid=2130524</iconUrl>
<tags>ui asp.net graphics blazor cross-platform skiasharp</tags>

<!-- legal -->
<licenseUrl>https://go.microsoft.com/fwlink/?linkid=868514</licenseUrl>
<authors>Microsoft</authors>
<owners>Microsoft</owners>
<requireLicenseAcceptance>true</requireLicenseAcceptance>
<copyright>© Microsoft Corporation. All rights reserved.</copyright>

<dependencies>
<group targetFramework="net6.0">
<dependency id="SkiaSharp" version="1.0.0" />
<dependency id="SkiaSharp.NativeAssets.WebAssembly" version="1.0.0" />
<dependency id="Microsoft.AspNetCore.Components.Web" version="1.0.0" />
</group>
</dependencies>

</metadata>
<files>

<!-- SkiaSharp.Views.UWP.dll -->
<file src="lib/net6.0/SkiaSharp.Views.Blazor.dll" />
<file src="lib/net6.0/SkiaSharp.Views.Blazor.pdb" />

<!-- the build bits -->
<file src="build/net6.0/SkiaSharp.Views.Blazor.props" />
<file src="build/net6.0/SkiaSharp.Views.Blazor.props" target="buildTransitive/net6.0/SkiaSharp.Views.Blazor.props" />

<!-- the js/css files -->
<file src="staticwebassets\*" target="staticwebassets\" />

<!-- legal -->
<file src="LICENSE.txt" />

</files>
</package>
37 changes: 37 additions & 0 deletions samples/Basic/Blazor/WebAssembly/SkiaSharpSample.Windows.sln
@@ -0,0 +1,37 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31717.149
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharpSample", "SkiaSharpSample\SkiaSharpSample.csproj", "{DB5BC6AE-C110-4CA0-9E1E-0328E29989EB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.Views.Blazor", "..\..\..\..\source\SkiaSharp.Views.Blazor\SkiaSharp.Views.Blazor\SkiaSharp.Views.Blazor.csproj", "{7BDDB4FB-B8A4-42C3-AA6B-C97AF2877622}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp", "..\..\..\..\binding\SkiaSharp\SkiaSharp.csproj", "{8073311E-E158-4608-8479-512B711C0812}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{DB5BC6AE-C110-4CA0-9E1E-0328E29989EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DB5BC6AE-C110-4CA0-9E1E-0328E29989EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DB5BC6AE-C110-4CA0-9E1E-0328E29989EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DB5BC6AE-C110-4CA0-9E1E-0328E29989EB}.Release|Any CPU.Build.0 = Release|Any CPU
{7BDDB4FB-B8A4-42C3-AA6B-C97AF2877622}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7BDDB4FB-B8A4-42C3-AA6B-C97AF2877622}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7BDDB4FB-B8A4-42C3-AA6B-C97AF2877622}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7BDDB4FB-B8A4-42C3-AA6B-C97AF2877622}.Release|Any CPU.Build.0 = Release|Any CPU
{8073311E-E158-4608-8479-512B711C0812}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8073311E-E158-4608-8479-512B711C0812}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8073311E-E158-4608-8479-512B711C0812}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8073311E-E158-4608-8479-512B711C0812}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {66F81B5B-452E-48B0-A360-017D6840BBD2}
EndGlobalSection
EndGlobal
37 changes: 37 additions & 0 deletions samples/Basic/Blazor/WebAssembly/SkiaSharpSample.sln
@@ -0,0 +1,37 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31717.149
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharpSample", "SkiaSharpSample\SkiaSharpSample.csproj", "{DB5BC6AE-C110-4CA0-9E1E-0328E29989EB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.Views.Blazor", "..\..\..\..\source\SkiaSharp.Views.Blazor\SkiaSharp.Views.Blazor\SkiaSharp.Views.Blazor.csproj", "{7BDDB4FB-B8A4-42C3-AA6B-C97AF2877622}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp", "..\..\..\..\binding\SkiaSharp\SkiaSharp.csproj", "{8073311E-E158-4608-8479-512B711C0812}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{DB5BC6AE-C110-4CA0-9E1E-0328E29989EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DB5BC6AE-C110-4CA0-9E1E-0328E29989EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DB5BC6AE-C110-4CA0-9E1E-0328E29989EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DB5BC6AE-C110-4CA0-9E1E-0328E29989EB}.Release|Any CPU.Build.0 = Release|Any CPU
{7BDDB4FB-B8A4-42C3-AA6B-C97AF2877622}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7BDDB4FB-B8A4-42C3-AA6B-C97AF2877622}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7BDDB4FB-B8A4-42C3-AA6B-C97AF2877622}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7BDDB4FB-B8A4-42C3-AA6B-C97AF2877622}.Release|Any CPU.Build.0 = Release|Any CPU
{8073311E-E158-4608-8479-512B711C0812}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8073311E-E158-4608-8479-512B711C0812}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8073311E-E158-4608-8479-512B711C0812}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8073311E-E158-4608-8479-512B711C0812}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {66F81B5B-452E-48B0-A360-017D6840BBD2}
EndGlobalSection
EndGlobal
10 changes: 10 additions & 0 deletions samples/Basic/Blazor/WebAssembly/SkiaSharpSample/App.razor
@@ -0,0 +1,10 @@
<Router AppAssembly="@typeof(Program).Assembly" PreferExactMatches="@true">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
</Found>
<NotFound>
<LayoutView Layout="@typeof(MainLayout)">
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
99 changes: 99 additions & 0 deletions samples/Basic/Blazor/WebAssembly/SkiaSharpSample/Pages/GPU.razor
@@ -0,0 +1,99 @@
@page "/gpu"

<h1>GPU (WebGL) Canvas</h1>

<p>The canvas below is using WebGL. See the great FPS!</p>

<div class="container">
<div class="row">
<div class="col border rounded p-2 canvas-container">

<SKGLView OnPaintSurface="OnPaintSurface" IgnorePixelScaling="true" EnableRenderLoop="true" />

</div>
</div>
</div>

@code {
int tickIndex = 0;
long tickSum = 0;
long[] tickList = new long[100];
long lastTick = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();

void OnPaintSurface(SKPaintGLSurfaceEventArgs e)
{
// the the canvas and properties
var canvas = e.Surface.Canvas;

// make sure the canvas is blank
canvas.Clear(SKColors.White);

using var paint = new SKPaint
{
IsAntialias = true,
StrokeWidth = 5f,
StrokeCap = SKStrokeCap.Round,
TextAlign = SKTextAlign.Center,
TextSize = 24,
};

var surfaceSize = e.Info.Size;
var clockSize = Math.Min(surfaceSize.Width, surfaceSize.Height) * 0.4f;
var center = new SKPoint(surfaceSize.Width / 2f, surfaceSize.Height / 2f);
var now = DateTime.Now;
var fps = GetCurrentFPS();

// draw the fps counter
canvas.DrawText($"{fps:0.00}fps", surfaceSize.Width / 2, surfaceSize.Height - 10f, paint);

// draw the clock
canvas.RotateDegrees(-90f, center.X, center.Y);

// hours
paint.StrokeWidth = 3f;
canvas.Save();
canvas.Translate(center);
canvas.RotateDegrees(360f * (now.Hour / 12f));
canvas.DrawLine(0, 0, clockSize * 0.4f, 0, paint);
canvas.Restore();

// minutes
paint.StrokeWidth = 2f;
canvas.Save();
canvas.Translate(center);
canvas.RotateDegrees(360f * (now.Minute / 60f));
canvas.DrawLine(0, 0, clockSize * 0.6f, 0, paint);
canvas.Restore();

// seconds
paint.StrokeWidth = 1f;
canvas.Save();
canvas.Translate(center);
canvas.RotateDegrees(360f * ((now.Second * 1000f + now.Millisecond) / 1000f / 60f));
canvas.DrawLine(0, 0, clockSize * 0.8f, 0, paint);
canvas.Restore();

// center
canvas.DrawCircle(center, 10f, paint);

// border
paint.Style = SKPaintStyle.Stroke;
canvas.DrawCircle(center, clockSize * 0.9f, paint);
}

double GetCurrentFPS()
{
var newTick = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
var delta = newTick - lastTick;
lastTick = newTick;

tickSum -= tickList[tickIndex];
tickSum += delta;
tickList[tickIndex] = delta;

if (++tickIndex == tickList.Length)
tickIndex = 0;

return 1000.0 / ((double)tickSum / tickList.Length);
}
}
73 changes: 73 additions & 0 deletions samples/Basic/Blazor/WebAssembly/SkiaSharpSample/Pages/Index.razor
@@ -0,0 +1,73 @@
@page "/"

<h1>Raster (Bitmap) Canvas</h1>

<p>The canvas below is using pixels in memory. Click and drag to move the text.</p>

<div class="container">
<div class="row">
<div class="col border rounded p-2 canvas-container">

<SKCanvasView
@ref="skiaView" OnPaintSurface="OnPaintSurface" IgnorePixelScaling="true"
@onpointerdown="OnPointerDown"
@onpointermove="OnPointerMove"
@onpointerup="OnPointerUp" />

</div>
</div>
</div>

@code {
SKCanvasView skiaView = null!;
SKPoint? touchLocation;
[Inject] IJSRuntime JS { get; set; } = null!;

void OnPaintSurface(SKPaintSurfaceEventArgs e)
{
// the the canvas and properties
var canvas = e.Surface.Canvas;

// make sure the canvas is blank
canvas.Clear(SKColors.White);

// decide what the text looks like
using var paint = new SKPaint
{
Color = SKColors.Black,
IsAntialias = true,
Style = SKPaintStyle.Fill,
TextAlign = SKTextAlign.Center,
TextSize = 24
};

// adjust the location based on the pointer
var coord = (touchLocation is SKPoint loc)
? new SKPoint(loc.X, loc.Y)
: new SKPoint(e.Info.Width / 2, (e.Info.Height + paint.TextSize) / 2);

// draw some text
canvas.DrawText("SkiaSharp", coord, paint);
}

void OnPointerDown(PointerEventArgs e)
{
touchLocation = new SKPoint((float)e.OffsetX, (float)e.OffsetY);
skiaView.Invalidate();
}

void OnPointerMove(PointerEventArgs e)
{
if (touchLocation == null)
return;

touchLocation = new SKPoint((float)e.OffsetX, (float)e.OffsetY);
skiaView.Invalidate();
}

void OnPointerUp(PointerEventArgs e)
{
touchLocation = null;
skiaView.Invalidate();
}
}
13 changes: 13 additions & 0 deletions samples/Basic/Blazor/WebAssembly/SkiaSharpSample/Program.cs
@@ -0,0 +1,13 @@
using System;
using System.Net.Http;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.Extensions.DependencyInjection;
using SkiaSharpSample;

var builder = WebAssemblyHostBuilder.CreateDefault(args);

builder.RootComponents.Add<App>("#app");

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

await builder.Build().RunAsync();
@@ -0,0 +1,30 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:13961",
"sslPort": 44319
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"SkiaSharpSample": {
"commandName": "Project",
"dotnetRunMessages": "true",
"launchBrowser": true,
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

0 comments on commit ce7778c

Please sign in to comment.