Add SKTouchCanvasView Blazor library with touch/pointer event support#364
Add SKTouchCanvasView Blazor library with touch/pointer event support#364
Conversation
…ing and navigation - Copy all source files from PR #357: SKTouchCanvasView component, touch types, JS interop, tests, Touch demo page, nav menu updates, solution/filter updates - Fix touch/mouse dragging not drawing: auto-invalidate canvas after handled touch events in SKTouchCanvasView.OnPointerEvent - Fix ResizeObserver error on navigation: don't manually dispose inner SKCanvasView (let Blazor manage its lifecycle) - Add setPointerCapture on pointerdown for reliable drag tracking Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>
mattleibow
left a comment
There was a problem hiding this comment.
@copilot please fix the issues
| // changes made by the handler are rendered immediately. | ||
| if (args.Handled) | ||
| { | ||
| _skCanvasView?.Invalidate(); |
There was a problem hiding this comment.
@copilot this must be in app code and not the library as the user may just track and not update.
There was a problem hiding this comment.
Removed auto-invalidate from the library. The demo app now calls _canvasView?.Invalidate() directly in its OnTouch handler. Fixed in 026c1f8.
| // Handles pointer events on the SkiaSharp canvas and forwards them to .NET | ||
| // using the same event model as the MAUI SKTouchEventArgs API. | ||
|
|
||
| export function initializeTouchEvents(element, dotNetRef) { |
There was a problem hiding this comment.
Converted to TypeScript (SKTouchInterop.ts). The compiled .js is generated via tsc and the .ts/tsconfig.json are excluded from static web assets in the csproj. Fixed in 026c1f8.
| @inherits ComponentBase | ||
| @implements IAsyncDisposable | ||
|
|
||
| <div @ref="_containerRef" |
There was a problem hiding this comment.
@copilot is there a way to do this without the container? For layout, we can do it in the app razor.
There was a problem hiding this comment.
Simplified — removed the layout-affecting Style/Class parameters and the position: relative/position: absolute styling. The wrapper div now only sets touch-action: none; user-select: none for pointer event capture. We still need a minimal element to get the @ref for JS interop since SKCanvasView doesn't expose its ElementReference. Layout is fully controlled by the app. Fixed in 026c1f8.
…eScript, simplify container - Move Touch.razor inline CSS to separate Touch.razor.css file - Remove auto-invalidate from library OnPointerEvent; app calls Invalidate() directly - Convert SKTouchInterop.js to TypeScript (SKTouchInterop.ts) with proper types - Simplify container div: removed Style/Class parameters, use minimal touch-action wrapper - Properly remove event listeners in disposeTouchEvents instead of relying on clone trick Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>
|
@copilot please look ath the SKCanvasView razor: https://github.com/mono/SkiaSharp/blob/main/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/SKCanvasView.razor <canvas @ref="htmlCanvas" @attributes="AdditionalAttributes" />And then we use es2015 es2015 Truein the msbuild proj instead of a tsconfig file. Are we producing a .map file in additin to the .js? |
…lement from JS Since upstream SKCanvasView splatts AdditionalAttributes directly onto its <canvas> element, we pass a data-sk-touch-id marker through and have JS find the element by attribute selector. This eliminates the wrapper div entirely — no extra DOM nodes, layout fully controlled by the app. JS now sets touch-action:none and user-select:none directly on the canvas. Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>
…pts/ - Add Microsoft.TypeScript.MSBuild (5.7.3) to compile .ts during dotnet build - Move SKTouchInterop.ts from wwwroot/ to Scripts/ (source directory) - Move tsconfig.json to project root with outDir=wwwroot, rootDir=Scripts - Delete pre-compiled .js — now generated automatically during build - Add generated wwwroot/*.js to .gitignore Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>
….MSBuild Microsoft.TypeScript.MSBuild conflicts with Razor SDK static web asset discovery in multi-target builds. Use a simple Exec target with Inputs/Outputs for incremental compilation instead. Also fix MergedAttributes to set internal data-sk-touch-id after user attributes so it cannot be overwritten. Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>
Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>
... Done in 5a76897 → 433ca3e. Since the upstream <SkiaSharp.Views.Blazor.SKCanvasView
@ref="_skCanvasView"
OnPaintSurface="OnPaintSurfaceInternal"
EnableRenderLoop="@EnableRenderLoop"
IgnorePixelScaling="@IgnorePixelScaling"
@attributes="MergedAttributes" />A Also: deleted the pre-compiled |
…s and .map in source control - Replace custom Exec target with Microsoft.TypeScript.MSBuild 5.7.3 (PrivateAssets=all) - Move SKTouchInterop.ts from Scripts/ back to wwwroot/ (matching upstream convention) - Remove tsconfig.json; use TypeScript MSBuild properties in csproj instead - Enable source maps (TypeScriptSourceMap=True) - Remove .gitignore entry — .js and .js.map are now committed to source control - All 3 files (.ts, .js, .js.map) live side-by-side in wwwroot/ like upstream SkiaSharp Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>
|
@copilot the touches are not in the same place as the lines. If I touch the bottom right, the lines are drawn in the upper left region. Basically the content is not scaled. We don't want to do scaling in the canvas view, so we need to apply scaling in the app. |
…draw where the user touches Touch events from JS arrive in CSS pixels, but the SkiaSharp canvas surface renders at device pixel ratio when IgnorePixelScaling is false (default). The app now scales touch coordinates, stroke widths, and legend elements by DPI. This is done in the app per the reviewer's guidance — the library should not apply scaling. Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>
Fixed in 15b7452. The sample app now scales touch coordinates by |


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.