Skip to content
Merged
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
3 changes: 3 additions & 0 deletions .vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export default defineConfig({
{ text: 'WebGL Recipes', link: '/canvas/guides/webgl-recipes' },
{ text: 'WebGPU Recipes', link: '/canvas/guides/webgpu-recipes' },
{ text: 'Images and ImageBitmap', link: '/canvas/guides/images-and-bitmaps' },
{ text: 'OffscreenCanvas and Workers', link: '/canvas/guides/offscreen-canvas' },
{ text: 'Fonts', link: '/canvas/guides/fonts' },
],
},
Expand All @@ -99,6 +100,7 @@ export default defineConfig({
{ text: 'Events and Input', link: '/canvas/events' },
{ text: 'Performance', link: '/canvas/performance' },
{ text: 'API Overview', link: '/canvas/api' },
{ text: 'Web API Compatibility', link: '/canvas/compatibility' },
{ text: 'Ecosystem Packages', link: '/canvas/ecosystem' },
],
},
Expand All @@ -114,6 +116,7 @@ export default defineConfig({
text: 'Guides',
items: [
{ text: 'Properties and Events', link: '/canvas-svg/guides/properties-and-events' },
{ text: 'Styling', link: '/canvas-svg/guides/styling' },
{ text: 'Building SVG with the DOM', link: '/canvas-svg/guides/dom' },
{ text: 'Animation', link: '/canvas-svg/guides/animation' },
{ text: 'Drawing SVG into a Canvas', link: '/canvas-svg/guides/canvas-integration' },
Expand Down
4 changes: 2 additions & 2 deletions .vitepress/theme/PluginsHome.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const plugins = [
stats: {
contexts: '2D + WebGL + WebGPU',
engine: 'Skia + WGPU',
platforms: 'iOS, tvOS, visionOS & Android',
platforms: 'Apple, Android & Windows',
},
},
{
Expand Down Expand Up @@ -304,7 +304,7 @@ onBeforeUnmount(() => {
</div>
<div class="flex items-center gap-2">
<div class="h-2 w-2 animate-pulse rounded-full bg-blue-500"></div>
<span>iOS, tvOS, visionOS & Android</span>
<span>Apple, Android & Windows</span>
</div>
<div class="flex items-center gap-2">
<div class="h-2 w-2 animate-pulse rounded-full bg-orange-500"></div>
Expand Down
2 changes: 1 addition & 1 deletion .vitepress/theme/components/AudioDocsHome.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const rootRef = ref<HTMLElement | null>(null);
<p class="audio-docs-kicker">Native audio graphs with a web-audio mental model</p>
<h2>@nativescript/audio-context</h2>
<p class="audio-docs-lede">
Build playback, synthesis, effects, routing, and offline rendering pipelines on iOS, tvOS, visionOS and Android with a familiar <code>AudioContext</code>-style API.
Build playback, synthesis, effects, routing, and offline rendering pipelines on iOS, tvOS, visionOS, Android and Windows with a familiar <code>AudioContext</code>-style API.
</p>

<div class="audio-docs-chip-row">
Expand Down
2 changes: 1 addition & 1 deletion .vitepress/theme/components/CanvasDocsHome.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const rootRef = ref<HTMLElement | null>(null);
</p>

<div class="canvas-docs-chip-row">
<span>iOS, tvOS, visionOS + Android</span>
<span>iOS, tvOS, visionOS, Android + Windows</span>
<span>Skia-backed rendering</span>
<span>GPU-ready workflows</span>
<span>Web API muscle memory</span>
Expand Down
2 changes: 1 addition & 1 deletion .vitepress/theme/components/CanvasHome.vue
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ onBeforeUnmount(() => {
</a>
<a href="/canvas/" class="canvas-home-link-panel">
<span>Canvas Docs</span>
<strong>Set up @nativescript/canvas and render with native iOS, tvOS, visionOS and Android surfaces.</strong>
<strong>Set up @nativescript/canvas and render with native iOS, tvOS, visionOS, Android and Windows surfaces.</strong>
</a>
<a href="/canvas/guides/webgl-recipes" class="canvas-home-link-panel">
<span>Rendering Recipes</span>
Expand Down
3 changes: 2 additions & 1 deletion content/audio-context/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ npm install @nativescript/audio-context
## Requirements

- `@nativescript/audio-context` 2.x requires **NativeScript 9.1 or later**. Pair it with `@nativescript/canvas` 3.x if you use both packages.
- Supported platforms: iOS, tvOS, visionOS and Android. The tvOS simulator build is arm64 only, so use an Apple silicon Mac to run it in the simulator.
- Supported platforms: iOS, tvOS, visionOS, Android, Windows and Linux. The tvOS simulator build is arm64 only, so use an Apple silicon Mac to run it in the simulator.
- On Windows and Linux the graph is rendered by the [web-audio-api](https://github.com/orottier/web-audio-api-rs) engine, playing through WASAPI on Windows and ALSA on Linux (PulseAudio and PipeWire work through their ALSA plugins). `decodeAudioData` reads WAV, MP3, Ogg Vorbis, FLAC and AAC. A `WaveShaperNode` takes only one curve: assigning a second throws `InvalidStateError`.

## Verify setup

Expand Down
4 changes: 3 additions & 1 deletion content/canvas-svg/guides/animation.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ A `begin` that waits for an event (such as `click`) never starts on its own.
```

- Keyword easings and `cubic-bezier()` are supported. `steps()` runs as linear.
- Only `#id` selectors are read, which is what SVG exporters produce.
- Any selector that the [stylesheet](/canvas-svg/guides/styling#selectors) supports can start an animation, and so can an element's own `style="animation: …"`. `@keyframes` can be in any `<style>` block.
- `translateX`, `translateY`, `scaleX` and `scaleY` animate a single axis. A `transform: none` keyframe is the identity.
- To animate a document with CSS kept outside it, such as a CodePen's CSS panel, use the [`stylesheet`](/canvas-svg/guides/styling) property.

## Playback

Expand Down
3 changes: 3 additions & 0 deletions content/canvas-svg/guides/properties-and-events.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ description: Svg view properties, events and static helpers in @nativescript/can
| Property | Default | Description |
| --- | --- | --- |
| `src` | | The path, URL or inline markup to render. |
| `stylesheet` | | CSS for the document, as text or a `~/`, absolute or http path to a `.css` file. See [Styling](/canvas-svg/guides/styling). |
| `gpu` | `true` | Rasterize on the GPU (Metal on Apple platforms, Vulkan or GL on Android). If no GPU context can be created, the view falls back to the CPU. |
| `threaded` | `true` | Rasterize off the UI thread. See [Rendering and Performance](/canvas-svg/guides/performance). |
| `shareSrc` | `true` | Views with the same `src` share one parsed document, one animation clock and one recording per frame. |
Expand All @@ -26,11 +27,13 @@ description: Svg view properties, events and static helpers in @nativescript/can
| Event | Fires when |
| --- | --- |
| `animationEnd` | Every animation in the document has finished. It never fires for an animation that repeats forever. |
| `error` | `src` could not be read, or is not a well-formed SVG document. `args.error` says why, and the view draws nothing. |
| `contextLost` | The GPU context could not be rebuilt, and drawing has moved to the CPU. |
| `contextRestored` | A lost GPU context was rebuilt, and GPU drawing has resumed. |

```ts
view.on('animationEnd', () => console.log('done'));
view.on('error', (args) => console.log('could not load:', args.error));
view.on('contextLost', () => console.log('now drawing on the CPU'));
```

Expand Down
56 changes: 56 additions & 0 deletions content/canvas-svg/guides/styling.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
title: Styling
description: Style an SVG document with the stylesheet property, and pass view styles such as color and fill through to it.
---

# Styling

NativeScript CSS in `app.css` styles the `<Svg>` view itself, not the elements inside its document. There are two ways to reach those elements: the `stylesheet` property, and the view styles that the document inherits.

## The `stylesheet` property

`stylesheet` takes CSS text, or a `~/`, absolute or http path to a `.css` file. It works like a `<style>` element at the top of the SVG, so it supports full rules and `@keyframes`. Use it for CSS kept outside the SVG, such as a CodePen's CSS panel:

```xml
<svg:Svg src="~/assets/loader.svg" stylesheet="~/assets/loader.css" />
```

```ts
view.stylesheet = `
@keyframes pulse { 50% { opacity: 0.3; } }
.dot { animation: pulse 1s ease-in-out infinite; }
`;
```

- It is applied again every time `src` reloads.
- Views that [share a `src`](/canvas-svg/guides/properties-and-events) share a document only if they also have the same `stylesheet`.
- For a document built with the [DOM](/canvas-svg/guides/dom) rather than `src`, only its `@keyframes` apply.

## View styles

These styles on the view are inherited by the document, as they would be by an inline `<svg>` on the web:

`color`, `fill`, `fill-rule`, `fill-opacity`, `stroke`, `stroke-width`, `stroke-linecap`, `stroke-linejoin` and `stroke-miterlimit`

They can come from a class in `app.css` or from an inline `style`. `color` is what `currentColor` resolves to, which makes single-colour icons easy to theme:

```xml
<svg:Svg src="~/assets/icon.svg" style="color: #f43f5e; stroke-width: 2" />
```

Only the properties you set are passed on, so the document's own attributes apply otherwise.

## Selectors

Rules in `stylesheet`, and in the document's own `<style>` blocks, support:

- type, `*`, `#id`, `.class` and attribute selectors
- `:root`, `:first-child`, `:last-child` and `:only-child`
- the descendant, `>`, `+` and `~` combinators

Any of these selectors can start a CSS animation. See [Animation](/canvas-svg/guides/animation#css).

## Related docs

- [Properties and Events](/canvas-svg/guides/properties-and-events)
- [Animation](/canvas-svg/guides/animation)
5 changes: 3 additions & 2 deletions content/canvas-svg/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ description: Native SVG rendering for NativeScript with SMIL and CSS animation,

# @nativescript/canvas-svg

`@nativescript/canvas-svg` renders SVG natively on iOS, tvOS, visionOS and Android with Skia. Version 3.0 is a ground-up rewrite.
`@nativescript/canvas-svg` renders SVG natively on iOS, tvOS, visionOS, Android, Windows and Linux with Skia. Version 3.0 is a ground-up rewrite.

- **Animation included.** SMIL (`<animate>`, `<animateTransform>`, `<animateMotion>`, `<set>`) and CSS `@keyframes` play without any extra code.
- **A real DOM.** When [`@nativescript/canvas-polyfill`](/plugins/canvas-polyfill) is installed, you can build and change an SVG with `document.createElementNS`, `setAttribute` and `appendChild`, as in a browser.
- **GPU rasterization.** Metal on Apple platforms, and Vulkan or GL on Android. Drawing happens off the UI thread, and the view falls back to the CPU automatically.
- **GPU rasterization.** Metal on Apple platforms, and Vulkan or GL on Android. Drawing happens off the UI thread, and the view falls back to the CPU automatically. Windows and Linux rasterize on the CPU.
- **Works as a canvas image source.** You can pass an SVG to `drawImage`, `createPattern`, `createImageBitmap`, `texImage2D` and WebGPU's `copyExternalImageToTexture`.

## Installation
Expand Down Expand Up @@ -42,6 +42,7 @@ Any animations in the source start once the view is loaded, and pause while it i
## Guides

- [Properties and Events](/canvas-svg/guides/properties-and-events)
- [Styling](/canvas-svg/guides/styling)
- [Building SVG with the DOM](/canvas-svg/guides/dom)
- [Animation](/canvas-svg/guides/animation)
- [Drawing SVG into a Canvas](/canvas-svg/guides/canvas-integration)
Expand Down
21 changes: 20 additions & 1 deletion content/canvas/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ description: API surface overview and compatibility notes for @nativescript/canv
- WebGPU is aligned with modern WebGPU APIs.
- `bitmaprenderer` follows the ImageBitmapRenderingContext spec.

For the members that are no-ops or not available yet, see [Web API Compatibility](/canvas/compatibility).

## Globals

Importing `@nativescript/canvas` installs these as globals: `CanvasRenderingContext2D`, `WebGLRenderingContext`, `WebGL2RenderingContext`, `ImageBitmapRenderingContext`, `CanvasGradient`, `CanvasPattern`, `Path2D`, `DOMMatrix`, `ImageData`, `ImageBitmap`, `ImageAsset`, `TextEncoder`, `TextDecoder`, `FontFace`, `fonts`, `TouchEvent`, `PointerEvent`, `CustomEvent`, and the WebGPU flag enums (`GPUBufferUsage`, `GPUTextureUsage`, `GPUMapMode`, `GPUShaderStage`).
Importing `@nativescript/canvas` installs these as globals: `OffscreenCanvas`, `OffscreenCanvasRenderingContext2D`, `CanvasRenderingContext2D`, `WebGLRenderingContext`, `WebGL2RenderingContext`, `ImageBitmapRenderingContext`, `CanvasGradient`, `CanvasPattern`, `Path2D`, `DOMMatrix`, `ImageData`, `ImageBitmap`, `ImageAsset`, `TextEncoder`, `TextDecoder`, `FontFace`, `fonts`, `TouchEvent`, `PointerEvent`, `CustomEvent`, and the WebGPU flag enums (`GPUBufferUsage`, `GPUTextureUsage`, `GPUMapMode`, `GPUShaderStage`).

For `window`, `document`, `navigator.gpu`, `createImageBitmap` and `Image`, add [`@nativescript/canvas-polyfill`](/plugins/canvas-polyfill).

Expand All @@ -34,9 +36,24 @@ For `window`, `document`, `navigator.gpu`, `createImageBitmap` and `Image`, add
| Member | Description |
| --- | --- |
| `snapshot(flip?)` | Returns the current pixels as a `@nativescript/core` `ImageSource`. |
| `transferControlToOffscreen()` | Standard. Returns an `OffscreenCanvas` that draws into this view. See [OffscreenCanvas and Workers](/canvas/guides/offscreen-canvas). |
| `Canvas.threaded2D`, `Canvas.threadedWebGL` | Static. The default for the `threaded` context attribute: `true` on Android, iOS and Windows. Set them before calling `getContext`. See [Threaded rendering](/canvas/performance#threaded-rendering). |
| `Canvas.forceGL` | Static. Use GL instead of Metal or Vulkan for 2D. Set it before calling `getContext`. |
| `Canvas.useSurface` | Static, Android only. Use a `SurfaceView` instead of a `TextureView`. |

## Workers

In a Worker, import `@nativescript/canvas/worker` instead of `@nativescript/canvas`. It has the same API without the `Canvas` view. See [OffscreenCanvas and Workers](/canvas/guides/offscreen-canvas#rendering-in-a-worker).

## ImageAsset extras

| Method | Description |
| --- | --- |
| `toImageSource()`, `toImageSourceSync()` | Returns the pixels as a `@nativescript/core` `ImageSource`. |
| `toNativeImage()`, `toNativeImageSync()` | Returns the pixels as the platform's image type: `Bitmap`, `UIImage`, `WriteableBitmap` or `GdkTexture`. |

See [Images and ImageBitmap](/canvas/guides/images-and-bitmaps#showing-an-asset-in-an-image).

## Type imports

For typed usage in TypeScript:
Expand Down Expand Up @@ -65,7 +82,9 @@ import type {
- [Canvas 2D Recipes](/canvas/guides/canvas-2d-recipes)
- [WebGL Recipes](/canvas/guides/webgl-recipes)
- [WebGPU Recipes](/canvas/guides/webgpu-recipes)
- [Web API Compatibility](/canvas/compatibility)
- [Rendering Contexts](/canvas/rendering-contexts)
- [Images and ImageBitmap](/canvas/guides/images-and-bitmaps)
- [OffscreenCanvas and Workers](/canvas/guides/offscreen-canvas)
- [Events and Input](/canvas/events)
- [Ecosystem Packages](/canvas/ecosystem)
Loading
Loading