{"id":15018584,"url":"https://github.com/nativescript-community/ui-canvas","last_synced_at":"2026-05-12T22:00:49.147Z","repository":{"id":46778882,"uuid":"167823493","full_name":"nativescript-community/ui-canvas","owner":"nativescript-community","description":"Implement Canvas into your NativeScript apps.","archived":false,"fork":false,"pushed_at":"2026-04-30T12:21:52.000Z","size":85494,"stargazers_count":37,"open_issues_count":15,"forks_count":9,"subscribers_count":13,"default_branch":"master","last_synced_at":"2026-04-30T14:16:29.035Z","etag":null,"topics":["android","canvas","cgcontext","ios","nativescript"],"latest_commit_sha":null,"homepage":"https://nativescript-community.github.io/ui-canvas/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nativescript-community.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["farfromrefug"]}},"created_at":"2019-01-27T15:20:36.000Z","updated_at":"2026-04-30T12:22:09.000Z","dependencies_parsed_at":"2024-01-15T22:25:42.614Z","dependency_job_id":"76d88490-4665-436b-a29d-710f4c16a67b","html_url":"https://github.com/nativescript-community/ui-canvas","commit_stats":{"total_commits":640,"total_committers":14,"mean_commits":"45.714285714285715","dds":0.4046875,"last_synced_commit":"dfc68e4dc4055125e673808198f1c39bebcee1f6"},"previous_names":["akylas/nativescript-canvas"],"tags_count":282,"template":false,"template_full_name":null,"purl":"pkg:github/nativescript-community/ui-canvas","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nativescript-community%2Fui-canvas","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nativescript-community%2Fui-canvas/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nativescript-community%2Fui-canvas/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nativescript-community%2Fui-canvas/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nativescript-community","download_url":"https://codeload.github.com/nativescript-community/ui-canvas/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nativescript-community%2Fui-canvas/sbom","scorecard":{"id":10085,"data":{"date":"2025-08-04","repo":{"name":"github.com/nativescript-community/ui-canvas","commit":"5365bef7770ac4eeb486e86eeb7db1bb9fec69ba"},"scorecard":{"version":"v5.2.1-28-gc1d103a9","commit":"c1d103a9bb9f635ec7260bf9aa0699466fa4be0e"},"score":3.4,"checks":[{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/release.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#token-permissions"}},{"name":"Code-Review","score":1,"reason":"Found 3/25 approved changesets -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#code-review"}},{"name":"Maintained","score":5,"reason":"5 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 5","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#maintained"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#cii-best-practices"}},{"name":"Binary-Artifacts","score":9,"reason":"binaries present in source code","details":["Warn: binary detected: src-native/android/gradle/wrapper/gradle-wrapper.jar:1"],"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/nativescript-community/ui-canvas/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/nativescript-community/ui-canvas/release.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/nativescript-community/ui-canvas/release.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:38: update your workflow using https://app.stepsecurity.io/secureworkflow/nativescript-community/ui-canvas/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:59: update your workflow using https://app.stepsecurity.io/secureworkflow/nativescript-community/ui-canvas/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:68: update your workflow using https://app.stepsecurity.io/secureworkflow/nativescript-community/ui-canvas/release.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:80: update your workflow using https://app.stepsecurity.io/secureworkflow/nativescript-community/ui-canvas/release.yml/master?enable=pin","Info:   0 out of   4 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   3 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#pinned-dependencies"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#branch-protection"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/release.yml:17"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#packaging"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 8 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"30 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-x4c5-c7rf-jjgv","Warn: Project is vulnerable to: GHSA-h5c3-5r3r-rr8q","Warn: Project is vulnerable to: GHSA-rmvr-2pp2-xj38","Warn: Project is vulnerable to: GHSA-xx4v-prfh-6cgc","Warn: Project is vulnerable to: GHSA-qwcr-r2fm-qrc7","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-pxg6-pf52-xh8x","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-p7v2-p9m8-qqg7","Warn: Project is vulnerable to: GHSA-7x97-j373-85x5","Warn: Project is vulnerable to: GHSA-7m48-wc93-9g85","Warn: Project is vulnerable to: GHSA-qqvq-6xgj-jw8g","Warn: Project is vulnerable to: GHSA-6r2x-8pq8-9489","Warn: Project is vulnerable to: GHSA-67mh-4wv8-2f99","Warn: Project is vulnerable to: GHSA-qw6h-vgh9-j6wx","Warn: Project is vulnerable to: GHSA-pfrx-2q88-qq97","Warn: Project is vulnerable to: GHSA-2p57-rm9w-gvfp","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-mwcw-c2x4-8c55","Warn: Project is vulnerable to: GHSA-9wv6-86v2-598j","Warn: Project is vulnerable to: GHSA-rhx6-c78j-4q9w","Warn: Project is vulnerable to: GHSA-7fh5-64p2-3v2j","Warn: Project is vulnerable to: GHSA-m6fv-jmcg-4jfg","Warn: Project is vulnerable to: GHSA-cm22-4g7w-348p","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6","Warn: Project is vulnerable to: GHSA-5j4c-8p2g-v4jx","Warn: Project is vulnerable to: GHSA-4vvj-4cpr-p986","Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-14T14:22:31.964Z","repository_id":46778882,"created_at":"2025-08-14T14:22:31.964Z","updated_at":"2025-08-14T14:22:31.964Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32954963,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-12T09:19:52.626Z","status":"ssl_error","status_checked_at":"2026-05-12T09:17:33.438Z","response_time":102,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","canvas","cgcontext","ios","nativescript"],"created_at":"2024-09-24T19:52:08.889Z","updated_at":"2026-05-12T22:00:49.139Z","avatar_url":"https://github.com/nativescript-community.png","language":"TypeScript","funding_links":["https://github.com/sponsors/farfromrefug"],"categories":["Plugins"],"sub_categories":["UI Plugins"],"readme":"\u003c!-- ⚠️ This README has been generated from the file(s) \"blueprint.md\" ⚠️--\u003eThis monorepo contains multiple packages:\u003cbr\u003e\u003cbr\u003e\n\u003cdetails open\u003e\n\u003csummary\u003e\u003cb\u003eui-canvas\u003c/b\u003e\u003c/summary\u003e\n\n\u003c!-- ⚠️ This README has been generated from the file(s) \"blueprint.md\" ⚠️--\u003e\n\u003c!--  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      DO NOT EDIT THIS READEME DIRECTLY! Edit \"bluesprint.md\" instead.\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --\u003e\n\u003ch1 align=\"center\"\u003e@nativescript-community/ui-canvas\u003c/h1\u003e\n\u003cp align=\"center\"\u003e\n\t\t\u003ca href=\"https://npmcharts.com/compare/@nativescript-community/ui-canvas?minimal=true\"\u003e\u003cimg alt=\"Downloads per month\" src=\"https://img.shields.io/npm/dm/@nativescript-community/ui-canvas.svg\" height=\"20\"/\u003e\u003c/a\u003e\r\n\u003ca href=\"https://www.npmjs.com/package/@nativescript-community/ui-canvas\"\u003e\u003cimg alt=\"NPM Version\" src=\"https://img.shields.io/npm/v/@nativescript-community/ui-canvas.svg\" height=\"20\"/\u003e\u003c/a\u003e\n\t\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cb\u003eImplement Canvas into your NativeScript apps.\u003c/b\u003e\u003c/br\u003e\n  \u003csub\u003e\u003csub\u003e\n\u003c/p\u003e\n\n\u003cbr /\u003e\n\n\n\r\n[](#table-of-contents)\r\n\r\n\r\n[](#table-of-contents)\r\n\r\n## Table of Contents\n\n* [Installation](#installation)\r\n\t* [Usage](#usage)\r\n* [Plain NativeScript](#plain-nativescript)\r\n\t* [XML](#xml)\r\n* [NativeScript + Angular](#nativescript--angular)\r\n* [NativeScript + Vue](#nativescript--vue)\r\n* [NativeScript + Svelte](#nativescript--svelte)\r\n* [Draw Method ](#draw-method-)\r\n\t* [Examples:](#examples)\r\n* [Demos and Development](#demos-and-development)\r\n\t* [Repo Setup](#repo-setup)\r\n\t* [Build](#build)\r\n\t* [Demos](#demos)\r\n* [Contributing](#contributing)\r\n\t* [Update repo ](#update-repo-)\r\n\t* [Update readme ](#update-readme-)\r\n\t* [Update doc ](#update-doc-)\r\n\t* [Publish](#publish)\r\n\t* [modifying submodules](#modifying-submodules)\r\n* [Questions](#questions)\n\n\r\n[](#installation)\r\n\r\n\r\n[](#installation)\r\n\r\n## Installation\nRun the following command from the root of your project:\n\n`ns plugin add @nativescript-community/ui-canvas`\n\n### Usage\n\nThe nativescript Canvas is based on the [Android Canvas](https://developer.android.com/reference/android/graphics/Canvas) class.\nThe android API is actually a direct subclass with some Additions\n\n\r\n[](#plain-nativescript)\r\n\r\n\r\n[](#plain-nativescript)\r\n\r\n## Plain NativeScript\n\n\u003cspan style=\"color:red\"\u003eIMPORTANT: \u003c/span\u003e_Make sure you include `xmlns:cv=\"@nativescript-community/ui-canvas\"` on the Page element_\n\n### XML\n\n```XML\n\u003cPage xmlns:cv=\"@nativescript-community/ui-canvas\"\u003e\n    \u003cStackLayout horizontalAlignment=\"center\"\u003e\n        \u003ccv:CanvasView width=\"100\" height=\"100\" draw=\"draw\"/\u003e\n   \u003c/StackLayout\u003e\n\u003c/Page\u003e\n```\n\n\r\n[](#nativescript--angular)\r\n\r\n\r\n[](#nativescript--angular)\r\n\r\n## NativeScript + Angular\n\n```typescript\nimport { registerElement } from 'nativescript-angular/element-registry';\nimport { CanvasView } from '@nativescript-community/ui-canvas';\nregisterElement('CanvasView', () =\u003e CanvasView);\n```\n\n```html\n\u003cCanvasView width=\"100\" height=\"100\" (draw)=\"draw($event)\u003e\u003c/CanvasView\u003e\n```\n\n\r\n[](#nativescript--vue)\r\n\r\n\r\n[](#nativescript--vue)\r\n\r\n## NativeScript + Vue\n\n```javascript\nimport Vue from 'nativescript-vue';\nimport CanvasPlugin from '@nativescript-community/ui-canvas/vue';\n\nVue.use(CanvasPlugin);\n```\n\n```html\n\u003cCanvasView  width=\"100\" height=\"100\" @draw=\"draw\"/\u003e\n```\n\n\r\n[](#nativescript--svelte)\r\n\r\n\r\n[](#nativescript--svelte)\r\n\r\n## NativeScript + Svelte\n\n```ts\n// app/app.ts\nimport { registerNativeViewElement } from 'svelte-native/dom';\nregisterNativeViewElement('canvasView', () =\u003e require('@nativescript-community/ui-canvas').CanvasView);\n```\n\n```svelte\n\u003c!-- app/components/Foo.svelte --\u003e\n\u003cstackLayout\u003e\n    \u003ccanvasView width=\"300\" height=\"300\" on:draw={draw} /\u003e\n\u003c/stackLayout\u003e\n```\n\n\r\n[](#draw-method-)\r\n\r\n\r\n[](#draw-method-)\r\n\r\n## Draw Method \n\n```ts\nimport type { Canvas } from '@nativescript-community/ui-canvas';\nimport { Paint, createRect } from '@nativescript-community/ui-canvas';\nimport { Color } from '@nativescript/core';\n\nfunction draw(event: { canvas: Canvas }) {\n    const canvas = event.canvas;\n    const paint = new Paint();\n    paint.setColor(new Color('black'));\n    paint.strokeWidth = 10;\n    canvas.drawRect(createRect(0, 0, 200, 100), paint);\n}\n```\n\n### Examples:\n\n- [Simple](demo-snippets/vue/Simple.vue)\n  - A basic example\n- [Image](demo-snippets/vue/Image.vue)\n  - An example drawing an image\n- [Shapes](demo-snippets/vue/Shapes.vue)\n  - An example drawing shapes using template\n- [Animation](demo-snippets/vue/Animation.vue)\n  - An example of animating a shape\n- [Complex](demo-snippets/vue/Complex.vue)\n  - An example of animating a shape\n\n\r\n[](#demos-and-development)\r\n\r\n\r\n[](#demos-and-development)\r\n\r\n## Demos and Development\n\n\n### Repo Setup\n\nThe repo uses submodules. If you did not clone with ` --recursive` then you need to call\n```\ngit submodule update --init\n```\n\nThe package manager used to install and link dependencies must be `pnpm` or `yarn`. `npm` wont work.\n\nTo develop and test:\nif you use `yarn` then run `yarn`\nif you use `pnpm` then run `pnpm i`\n\n**Interactive Menu:**\n\nTo start the interactive menu, run `npm start` (or `yarn start` or `pnpm start`). This will list all of the commonly used scripts.\n\n### Build\n\n```bash\nnpm run build.all\n```\nWARNING: it seems `yarn build.all` wont always work (not finding binaries in `node_modules/.bin`) which is why the doc explicitly uses `npm run`\n\n### Demos\n\n```bash\nnpm run demo.[ng|react|svelte|vue].[ios|android]\n\nnpm run demo.svelte.ios # Example\n```\n\nDemo setup is a bit special in the sense that if you want to modify/add demos you dont work directly in `demo-[ng|react|svelte|vue]`\nInstead you work in `demo-snippets/[ng|react|svelte|vue]`\nYou can start from the `install.ts` of each flavor to see how to register new demos \n\n\r\n[](#contributing)\r\n\r\n\r\n[](#contributing)\r\n\r\n## Contributing\n\n### Update repo \n\nYou can update the repo files quite easily\n\nFirst update the submodules\n\n```bash\nnpm run update\n```\n\nThen commit the changes\nThen update common files\n\n```bash\nnpm run sync\n```\nThen you can run `yarn|pnpm`, commit changed files if any\n\n### Update readme \n```bash\nnpm run readme\n```\n\n### Update doc \n```bash\nnpm run doc\n```\n\n### Publish\n\nThe publishing is completely handled by `lerna` (you can add `-- --bump major` to force a major release)\nSimply run \n```shell\nnpm run publish\n```\n\n### modifying submodules\n\nThe repo uses https:// for submodules which means you won't be able to push directly into the submodules.\nOne easy solution is t modify `~/.gitconfig` and add\n```\n[url \"ssh://git@github.com/\"]\n\tpushInsteadOf = https://github.com/\n```\n\n\r\n[](#questions)\r\n\r\n\r\n[](#questions)\r\n\r\n## Questions\n\nIf you have any questions/issues/comments please feel free to create an issue or start a conversation in the [NativeScript Community Discord](https://nativescript.org/discord).\n\n\u003c/details\u003e\n\u003cdetails open\u003e\n\u003csummary\u003e\u003cb\u003eui-canvaslabel\u003c/b\u003e\u003c/summary\u003e\n\n\u003c!-- ⚠️ This README has been generated from the file(s) \"blueprint.md\" ⚠️--\u003e\n\u003c!--  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      DO NOT EDIT THIS READEME DIRECTLY! Edit \"bluesprint.md\" instead.\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --\u003e\n\u003ch1 align=\"center\"\u003e@nativescript-community/ui-canvaslabel\u003c/h1\u003e\n\u003cp align=\"center\"\u003e\n\t\t\u003ca href=\"https://npmcharts.com/compare/@nativescript-community/ui-canvaslabel?minimal=true\"\u003e\u003cimg alt=\"Downloads per month\" src=\"https://img.shields.io/npm/dm/@nativescript-community/ui-canvaslabel.svg\" height=\"20\"/\u003e\u003c/a\u003e\r\n\u003ca href=\"https://www.npmjs.com/package/@nativescript-community/ui-canvaslabel\"\u003e\u003cimg alt=\"NPM Version\" src=\"https://img.shields.io/npm/v/@nativescript-community/ui-canvaslabel.svg\" height=\"20\"/\u003e\u003c/a\u003e\n\t\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cb\u003eAlternative to the built-in NativeScript Label but uses canvas which allows extreme complexity and customization.\u003c/b\u003e\u003c/br\u003e\n  \u003csub\u003e\u003csub\u003e\n\u003c/p\u003e\n\n\u003cbr /\u003e\n\n\n\r\n[](#table-of-contents)\r\n\r\n\r\n[](#table-of-contents)\r\n\r\n## Table of Contents\n\n* [Installation](#installation)\r\n* [Configuration](#configuration)\r\n* [Performances](#performances)\r\n* [TODO / Limitations](#todo--limitations)\r\n\t* [Examples:](#examples)\r\n* [Demos and Development](#demos-and-development)\r\n\t* [Repo Setup](#repo-setup)\r\n\t* [Build](#build)\r\n\t* [Demos](#demos)\r\n* [Contributing](#contributing)\r\n\t* [Update repo ](#update-repo-)\r\n\t* [Update readme ](#update-readme-)\r\n\t* [Update doc ](#update-doc-)\r\n\t* [Publish](#publish)\r\n\t* [modifying submodules](#modifying-submodules)\r\n* [Questions](#questions)\n\nA NativeScript Label widget. This widget takes a different approch from other label components. It is based on `nativescript-canvas` and allows drawing\nmultiple labels within one single widget.\nIt allows extreme complexity and customization.\n\n\r\n[](#installation)\r\n\r\n\r\n[](#installation)\r\n\r\n## Installation\nRun the following command from the root of your project:\n\n`ns plugin add @nativescript-community/ui-canvaslabel`\n\n\r\n[](#configuration)\r\n\r\n\r\n[](#configuration)\r\n\r\n## Configuration\nIt works almost like a normal label.\nYou can create spans, just like with the {N} labels. However there is a big difference with the {N} component.\n`CSpan` do not support css class and never will! It was actually made on purpose to make to make the component much more efficient.\n\nFor now `CanvasLabel` do not auto size itself. I will add some way of doing it in the future but in a sense it defies the purpose of this component.\n\nThe `CanvasLabel` component supports most labels properties:\n`color`, `fontSize`,`fontFamily`,`fontStyle`, `fontWeight`,`textAlignment`. Those can be defined through css.\n\nNow with `CanvasLabel` you don't set the text directly. Instead you create `CSpan` or `CGroup`\n\nHere is a complex Vue layout as an example\n```html\n\u003cCanvasLabel id=\"canvaslabel\" fontSize=\"10\" color=\"white\" backgroundColor=\"darkgray\"\u003e\n    \u003cCGroup fontSize=\"18\" verticalAlignment=\"middle\" paddingLeft=\"20\"\u003e\n        \u003cCSpan :text=\"item.text1\" fontWeight=\"bold\" /\u003e\n        \u003cCSpan :text=\"'\\n' + item.text2\" color=\"#ccc\" fontSize=\"16\" /\u003e\n    \u003c/CGroup\u003e\n\n    \u003cCGroup fontSize=\"12\" verticalAlignment=\"bottom\" paddingLeft=\"20\" paddingBottom=\"1\"\u003e\n        \u003cCSpan :text=\"item.icon1\" fontSize=\"20\" color=\"green\" :fontFamily=\"mdiFontFamily\" /\u003e\n        \u003cCSpan :text=\"' ' + item.texticon1\" verticalTextAlignment=\"center\" /\u003e\n        \u003cCSpan :text=\"'   ' + item.icon2\" fontSize=\"20\" color=\"red\" :fontFamily=\"mdiFontFamily\" /\u003e\n        \u003cCSpan :text=\"' ' + item.texticon2\" verticalTextAlignment=\"center\" /\u003e\n        \u003cCSpan :text=\"'   ' + item.icon3\" fontSize=\"20\" color=\"yellow\" :fontFamily=\"mdiFontFamily\" /\u003e\n        \u003cCSpan :text=\"' ' + item.texticon3\" verticalTextAlignment=\"center\" /\u003e\n    \u003c/CGroup\u003e\n\n    \u003cCGroup fontSize=\"12\" verticalAlignment=\"middle\" horizontalAlignment=\"center\" textAlignment=\"right\" paddingRight=\"20\" color=\"brown\" width=\"60\"\u003e\n        \u003cCSpan :text=\"item.icon1\" fontSize=\"14\" :fontFamily=\"mdiFontFamily\" /\u003e\n        \u003cCSpan :text=\"'\\n' + item.texticon1\" paddingRight=\"10\" /\u003e\n    \u003c/CGroup\u003e\n    \u003cCSpan :text=\"item.text4\" color=\"lightgray\" fontSize=\"14\" textAlignment=\"right\" paddingRight=\"20\" paddingTop=\"4\" /\u003e\n\u003c/CanvasLabel\u003e\n```\n\nFor full example / doc look at the vue demo and the typings.\n\n\r\n[](#performances)\r\n\r\n\r\n[](#performances)\r\n\r\n## Performances\n\n`CanvasLabel` is made to be real fast. It was designed principaly to be used within list views. It uses the technique of drawing the text directly instead of using heavy native text components.\nThat technique is used by many apps looking for the best performances. One of the best examples is Telegram.\n\n\r\n[](#todo--limitations)\r\n\r\n\r\n[](#todo--limitations)\r\n\r\n## TODO / Limitations\n\n* For now there is no accessibility support (but it should be possible)\n* The label can't size itself. I will add some ways of doing that. But possibly not in the way you are used to.\n* no ellipsize support yet. Will come ([this](https://github.com/lsjwzh/FastTextView/blob/5e440575539ab1f470d853b1e7462fe0251eb869/widget.FastTextView/src/main/java/android/text/EllipsisSpannedContainer.java) could be a solution)\n* a lot of canvas features can be added like shadows, gradient ...\n* transform supoort should be possible at least for groups and top spans.\n\n### Examples:\n\n- [Basic](demo-snippets/vue/CanvasLabel.vue)\n  - A basic SVG example\n\n\r\n[](#demos-and-development)\r\n\r\n\r\n[](#demos-and-development)\r\n\r\n## Demos and Development\n\n\n### Repo Setup\n\nThe repo uses submodules. If you did not clone with ` --recursive` then you need to call\n```\ngit submodule update --init\n```\n\nThe package manager used to install and link dependencies must be `pnpm` or `yarn`. `npm` wont work.\n\nTo develop and test:\nif you use `yarn` then run `yarn`\nif you use `pnpm` then run `pnpm i`\n\n**Interactive Menu:**\n\nTo start the interactive menu, run `npm start` (or `yarn start` or `pnpm start`). This will list all of the commonly used scripts.\n\n### Build\n\n```bash\nnpm run build.all\n```\nWARNING: it seems `yarn build.all` wont always work (not finding binaries in `node_modules/.bin`) which is why the doc explicitly uses `npm run`\n\n### Demos\n\n```bash\nnpm run demo.[ng|react|svelte|vue].[ios|android]\n\nnpm run demo.svelte.ios # Example\n```\n\nDemo setup is a bit special in the sense that if you want to modify/add demos you dont work directly in `demo-[ng|react|svelte|vue]`\nInstead you work in `demo-snippets/[ng|react|svelte|vue]`\nYou can start from the `install.ts` of each flavor to see how to register new demos \n\n\r\n[](#contributing)\r\n\r\n\r\n[](#contributing)\r\n\r\n## Contributing\n\n### Update repo \n\nYou can update the repo files quite easily\n\nFirst update the submodules\n\n```bash\nnpm run update\n```\n\nThen commit the changes\nThen update common files\n\n```bash\nnpm run sync\n```\nThen you can run `yarn|pnpm`, commit changed files if any\n\n### Update readme \n```bash\nnpm run readme\n```\n\n### Update doc \n```bash\nnpm run doc\n```\n\n### Publish\n\nThe publishing is completely handled by `lerna` (you can add `-- --bump major` to force a major release)\nSimply run \n```shell\nnpm run publish\n```\n\n### modifying submodules\n\nThe repo uses https:// for submodules which means you won't be able to push directly into the submodules.\nOne easy solution is t modify `~/.gitconfig` and add\n```\n[url \"ssh://git@github.com/\"]\n\tpushInsteadOf = https://github.com/\n```\n\n\r\n[](#questions)\r\n\r\n\r\n[](#questions)\r\n\r\n## Questions\n\nIf you have any questions/issues/comments please feel free to create an issue or start a conversation in the [NativeScript Community Discord](https://nativescript.org/discord).\n\u003c/details\u003e\n\u003cdetails open\u003e\n\u003csummary\u003e\u003cb\u003eui-drawingcanvas\u003c/b\u003e\u003c/summary\u003e\n\n\u003c!-- ⚠️ This README has been generated from the file(s) \"blueprint.md\" ⚠️--\u003e\n\u003c!--  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      DO NOT EDIT THIS READEME DIRECTLY! Edit \"bluesprint.md\" instead.\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --\u003e\n\u003ch1 align=\"center\"\u003e@nativescript-community/ui-drawingcanvas\u003c/h1\u003e\n\u003cp align=\"center\"\u003e\n\t\t\u003ca href=\"https://npmcharts.com/compare/@nativescript-community/ui-drawingcanvas?minimal=true\"\u003e\u003cimg alt=\"Downloads per month\" src=\"https://img.shields.io/npm/dm/@nativescript-community/ui-drawingcanvas.svg\" height=\"20\"/\u003e\u003c/a\u003e\r\n\u003ca href=\"https://www.npmjs.com/package/@nativescript-community/ui-drawingcanvas\"\u003e\u003cimg alt=\"NPM Version\" src=\"https://img.shields.io/npm/v/@nativescript-community/ui-drawingcanvas.svg\" height=\"20\"/\u003e\u003c/a\u003e\n\t\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cb\u003eInteractive drawing canvas plugin for NativeScript – draw shapes, images and freehand paths with multiple modes, layers, undo/redo and JSON serialization.\u003c/b\u003e\u003c/br\u003e\n  \u003csub\u003e\u003csub\u003e\n\u003c/p\u003e\n\n\u003cbr /\u003e\n\n\n\r\n[](#table-of-contents)\r\n\r\n\r\n[](#table-of-contents)\r\n\r\n## Table of Contents\n\n* [Features](#features)\r\n* [Installation](#installation)\r\n* [Usage](#usage)\r\n\t* [NativeScript Core / TypeScript](#nativescript-core--typescript)\r\n\t* [Vue (NativeScript-Vue)](#vue-nativescript-vue)\r\n* [Drawing Modes](#drawing-modes)\r\n* [Undo / Redo](#undo--redo)\r\n* [Layer Management](#layer-management)\r\n* [JSON Serialization](#json-serialization)\r\n* [Path Simplification](#path-simplification)\r\n* [Custom Modes](#custom-modes)\r\n* [Custom Shape Types](#custom-shape-types)\r\n* [Events](#events)\r\n\t* [Examples:](#examples)\r\n* [Demos and Development](#demos-and-development)\r\n\t* [Repo Setup](#repo-setup)\r\n\t* [Build](#build)\r\n\t* [Demos](#demos)\r\n* [Contributing](#contributing)\r\n\t* [Update repo ](#update-repo-)\r\n\t* [Update readme ](#update-readme-)\r\n\t* [Update doc ](#update-doc-)\r\n\t* [Publish](#publish)\r\n\t* [modifying submodules](#modifying-submodules)\r\n* [Questions](#questions)\n\nAn interactive drawing canvas plugin for NativeScript, built on top of `@nativescript-community/ui-canvas`.\n\n\r\n[](#features)\r\n\r\n\r\n[](#features)\r\n\r\n## Features\n\n- **Multiple drawing modes**: pen/freehand, rectangle, ellipse, arrow, image placement, select/transform, and move (pan)\n- **Layer management**: access shapes as an ordered list of layers – reorder, remove, duplicate\n- **Undo / Redo**: full history with configurable depth\n- **Shape selection \u0026 transform**: resize, rotate and move any shape with on-canvas handles\n- **Colour \u0026 style**: stroke colour, fill colour, stroke width and opacity per shape\n- **JSON serialization**: export the entire canvas to a compact JSON string and re-import it later\n- **Path simplification**: automatic Douglas-Peucker + Catmull-Rom smoothing for pen strokes (configurable, extensible)\n- **Extensible**: register custom drawing modes and custom shape types\n\n\n\r\n[](#installation)\r\n\r\n\r\n[](#installation)\r\n\r\n## Installation\nRun the following command from the root of your project:\n\n`ns plugin add @nativescript-community/ui-drawingcanvas`\n\n\r\n[](#usage)\r\n\r\n\r\n[](#usage)\r\n\r\n## Usage\n\n### NativeScript Core / TypeScript\n\n```typescript\nimport { DrawingCanvas } from '@nativescript-community/ui-drawingcanvas';\n\nconst dc = new DrawingCanvas();\ndc.strokeColor = new Color('red');\ndc.strokeWidth = 3;\ndc.setMode('pen');          // 'pen' | 'select' | 'move' | 'rectangle' | 'ellipse' | 'arrow' | 'image'\n```\n\n### Vue (NativeScript-Vue)\n\n```typescript\n// app.ts / main.ts\nimport DrawingCanvasPlugin from '@nativescript-community/ui-drawingcanvas/vue';\nVue.use(DrawingCanvasPlugin);\n```\n\n```html\n\u003cDrawingCanvas ref=\"dc\" width=\"100%\" height=\"100%\" /\u003e\n```\n\n\r\n[](#drawing-modes)\r\n\r\n\r\n[](#drawing-modes)\r\n\r\n## Drawing Modes\n\n| Mode | Description |\n|------|-------------|\n| `pen` | Freehand stroke |\n| `rectangle` | Tap-drag to draw a rectangle |\n| `ellipse` | Tap-drag to draw an ellipse / circle |\n| `arrow` | Tap-drag to draw an arrow |\n| `image` | Tap to place an image (set `imageSource` on the `ImageMode` first) |\n| `select` | Tap to select shapes; drag handles to resize / rotate; drag body to move |\n| `move` | Pan gesture (emits `pan` event with `dx`/`dy`) |\n\n\r\n[](#undo--redo)\r\n\r\n\r\n[](#undo--redo)\r\n\r\n## Undo / Redo\n\n```typescript\ndc.undo();\ndc.redo();\nconsole.log(dc.canUndo, dc.canRedo);\n\n// Configure undo history depth (default: 50)\ndc.maxUndoDepth = 30;\n```\n\n\r\n[](#layer-management)\r\n\r\n\r\n[](#layer-management)\r\n\r\n## Layer Management\n\n```typescript\nconst layers = dc.layers;          // DrawableShape[]\ndc.moveLayerUp(shape);\ndc.moveLayerDown(shape);\ndc.duplicateShape(shape);\ndc.removeLayer(shape);\n```\n\n\r\n[](#json-serialization)\r\n\r\n\r\n[](#json-serialization)\r\n\r\n## JSON Serialization\n\n```typescript\nconst json = dc.exportJSON();\n// later …\ndc.importJSON(json);\n```\n\n\r\n[](#path-simplification)\r\n\r\n\r\n[](#path-simplification)\r\n\r\n## Path Simplification\n\n```typescript\ndc.simplificationOptions = {\n    enabled: true,\n    epsilon: 2,           // Douglas-Peucker tolerance in dp\n    smoothing: true,      // apply Catmull-Rom spline\n    splineSegments: 8,\n    splineAlpha: 0.5      // 0=uniform, 0.5=centripetal (recommended)\n};\n```\n\n\r\n[](#custom-modes)\r\n\r\n\r\n[](#custom-modes)\r\n\r\n## Custom Modes\n\n```typescript\nimport { DrawingMode } from '@nativescript-community/ui-drawingcanvas';\n\nclass MyMode extends DrawingMode {\n    readonly name = 'mymode';\n    onTouchEnd(point) {\n        // … create and commit a shape\n        this.canvas.commitShape(myShape);\n    }\n}\ndc.registerMode(new MyMode(dc));\ndc.setMode('mymode');\n```\n\n\r\n[](#custom-shape-types)\r\n\r\n\r\n[](#custom-shape-types)\r\n\r\n## Custom Shape Types\n\n```typescript\nimport { CustomShape } from '@nativescript-community/ui-drawingcanvas';\n\n// Register a factory so importJSON can recreate the shape\ndc.registerShapeFactory('star', () =\u003e new StarShape());\n```\n\n\r\n[](#events)\r\n\r\n\r\n[](#events)\r\n\r\n## Events\n\n| Event | Payload | Description |\n|-------|---------|-------------|\n| `shapeAdded` | `{ shape }` | Fired when a shape is committed |\n| `selectionChange` | `{ shape }` | Fired when the selected shape changes in `select` mode |\n| `modeChange` | `{ mode }` | Fired when the active mode changes |\n| `historyChange` | `{ canUndo, canRedo }` | Fired after undo / redo stack changes |\n| `pan` | `{ dx, dy }` | Fired by `move` mode on each gesture move |\n\n### Examples:\n\n- [Basic](demo-snippets/vue/DrawingCanvas.vue)\n  - A basic Drawing example\n\n\r\n[](#demos-and-development)\r\n\r\n\r\n[](#demos-and-development)\r\n\r\n## Demos and Development\n\n\n### Repo Setup\n\nThe repo uses submodules. If you did not clone with ` --recursive` then you need to call\n```\ngit submodule update --init\n```\n\nThe package manager used to install and link dependencies must be `pnpm` or `yarn`. `npm` wont work.\n\nTo develop and test:\nif you use `yarn` then run `yarn`\nif you use `pnpm` then run `pnpm i`\n\n**Interactive Menu:**\n\nTo start the interactive menu, run `npm start` (or `yarn start` or `pnpm start`). This will list all of the commonly used scripts.\n\n### Build\n\n```bash\nnpm run build.all\n```\nWARNING: it seems `yarn build.all` wont always work (not finding binaries in `node_modules/.bin`) which is why the doc explicitly uses `npm run`\n\n### Demos\n\n```bash\nnpm run demo.[ng|react|svelte|vue].[ios|android]\n\nnpm run demo.svelte.ios # Example\n```\n\nDemo setup is a bit special in the sense that if you want to modify/add demos you dont work directly in `demo-[ng|react|svelte|vue]`\nInstead you work in `demo-snippets/[ng|react|svelte|vue]`\nYou can start from the `install.ts` of each flavor to see how to register new demos \n\n\r\n[](#contributing)\r\n\r\n\r\n[](#contributing)\r\n\r\n## Contributing\n\n### Update repo \n\nYou can update the repo files quite easily\n\nFirst update the submodules\n\n```bash\nnpm run update\n```\n\nThen commit the changes\nThen update common files\n\n```bash\nnpm run sync\n```\nThen you can run `yarn|pnpm`, commit changed files if any\n\n### Update readme \n```bash\nnpm run readme\n```\n\n### Update doc \n```bash\nnpm run doc\n```\n\n### Publish\n\nThe publishing is completely handled by `lerna` (you can add `-- --bump major` to force a major release)\nSimply run \n```shell\nnpm run publish\n```\n\n### modifying submodules\n\nThe repo uses https:// for submodules which means you won't be able to push directly into the submodules.\nOne easy solution is t modify `~/.gitconfig` and add\n```\n[url \"ssh://git@github.com/\"]\n\tpushInsteadOf = https://github.com/\n```\n\n\r\n[](#questions)\r\n\r\n\r\n[](#questions)\r\n\r\n## Questions\n\nIf you have any questions/issues/comments please feel free to create an issue or start a conversation in the [NativeScript Community Discord](https://nativescript.org/discord).\n\u003c/details\u003e\n\u003cdetails open\u003e\n\u003csummary\u003e\u003cb\u003eui-svg\u003c/b\u003e\u003c/summary\u003e\n\n\u003c!-- ⚠️ This README has been generated from the file(s) \"blueprint.md\" ⚠️--\u003e\n\u003c!--  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      DO NOT EDIT THIS READEME DIRECTLY! Edit \"bluesprint.md\" instead.\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --\u003e\n\u003ch1 align=\"center\"\u003e@nativescript-community/ui-svg\u003c/h1\u003e\n\u003cp align=\"center\"\u003e\n\t\t\u003ca href=\"https://npmcharts.com/compare/@nativescript-community/ui-svg?minimal=true\"\u003e\u003cimg alt=\"Downloads per month\" src=\"https://img.shields.io/npm/dm/@nativescript-community/ui-svg.svg\" height=\"20\"/\u003e\u003c/a\u003e\r\n\u003ca href=\"https://www.npmjs.com/package/@nativescript-community/ui-svg\"\u003e\u003cimg alt=\"NPM Version\" src=\"https://img.shields.io/npm/v/@nativescript-community/ui-svg.svg\" height=\"20\"/\u003e\u003c/a\u003e\n\t\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cb\u003eAdds support for SVGs in your NativeScript apps.\u003c/b\u003e\u003c/br\u003e\n  \u003csub\u003e\u003csub\u003e\n\u003c/p\u003e\n\n\u003cbr /\u003e\n\n\n\r\n[](#table-of-contents)\r\n\r\n\r\n[](#table-of-contents)\r\n\r\n## Table of Contents\n\n* [Installation](#installation)\r\n\t* [NativeScript + Vue](#nativescript--vue)\r\n\t* [NativeScript + Svelte](#nativescript--svelte)\r\n\t* [Examples:](#examples)\r\n* [Demos and Development](#demos-and-development)\r\n\t* [Repo Setup](#repo-setup)\r\n\t* [Build](#build)\r\n\t* [Demos](#demos)\r\n* [Contributing](#contributing)\r\n\t* [Update repo ](#update-repo-)\r\n\t* [Update readme ](#update-readme-)\r\n\t* [Update doc ](#update-doc-)\r\n\t* [Publish](#publish)\r\n\t* [modifying submodules](#modifying-submodules)\r\n* [Questions](#questions)\n\n\r\n[](#installation)\r\n\r\n\r\n[](#installation)\r\n\r\n## Installation\nRun the following command from the root of your project:\n\n`ns plugin add @nativescript-community/ui-svg`\n\n\n### NativeScript + Vue\n\n```ts\nimport SVGPlugin from '@nativescript-community/ui-svg/vue';\nVue.use(SVGPlugin);\n// or if you want the canvas version\nimport CanvasSVGPlugin from '@nativescript-community/ui-svg/vue/canvas';\nVue.use(CanvasSVGPlugin);\n```\n\nFor other flavors you need to register the components directly:\n```ts\nimport { SVGView } from '@nativescript-community/ui-svg';\nimport { CanvasSVG, SVG } from '@nativescript-community/ui-svg/canvas';\n\n```\n\nIt works in 3 ways!.\n\n`CanvasSVG` extending `Canvas`\n\n\n```html\n\u003cCanvasSVG\u003e\n    \u003cCSVG horizontalAlignment=\"left\" src=\"~/assets/svgs/Ghostscript_Tiger.svg\" height=\"100%\" stretch=\"aspectFit\" /\u003e\n\u003c/CanvasSVG\u003e\n```\n\nor `SVGView` which is a basic svg view with support for auto sizing\n\n```html\n\u003cSVGView height=\"30%\" src=\"~/assets/svgs/Ghostscript_Tiger.svg\" stretch=\"aspectFit\" backgroundColor=\"red\" /\u003e\n```\n\nOr within and Canvas View extending `CanvasView` like `CanvasLabel`\n\n```html\n\u003cCanvasLabel\u003e\n \u003cCGroup fontSize=\"18\" verticalAlignment=\"middle\" paddingLeft=\"20\"\u003e\n        \u003cCSpan text=\"test\" fontWeight=\"bold\" /\u003e\n        \u003cCSpan text=\"test2\" color=\"#ccc\" fontSize=\"16\" /\u003e\n    \u003c/CGroup\u003e\n    \u003cCSVG horizontalAlignment=\"left\" src=\"~/assets/svgs/Ghostscript_Tiger.svg\" height=\"10\" stretch=\"aspectFit\" /\u003e\n\u003c/CanvasSVG\u003e\n```\n\n### NativeScript + Svelte\n\n```ts\n// app/app.ts\nimport { registerNativeViewElement } from 'svelte-native/dom';\nregisterNativeViewElement('svgView', () =\u003e require('@nativescript-community/ui-svg').SVGView);\n```\n\n```svelte\n\u003c!-- app/components/Foo.svelte --\u003e\n\u003csvgView src=\"~/assets/foo.svg\" aspectFit=\"stretch\" /\u003e\n```\n\n### Examples:\n\n- [Basic](demo-snippets/vue/SVG.vue)\n  - A basic SVG example\n\n\r\n[](#demos-and-development)\r\n\r\n\r\n[](#demos-and-development)\r\n\r\n## Demos and Development\n\n\n### Repo Setup\n\nThe repo uses submodules. If you did not clone with ` --recursive` then you need to call\n```\ngit submodule update --init\n```\n\nThe package manager used to install and link dependencies must be `pnpm` or `yarn`. `npm` wont work.\n\nTo develop and test:\nif you use `yarn` then run `yarn`\nif you use `pnpm` then run `pnpm i`\n\n**Interactive Menu:**\n\nTo start the interactive menu, run `npm start` (or `yarn start` or `pnpm start`). This will list all of the commonly used scripts.\n\n### Build\n\n```bash\nnpm run build.all\n```\nWARNING: it seems `yarn build.all` wont always work (not finding binaries in `node_modules/.bin`) which is why the doc explicitly uses `npm run`\n\n### Demos\n\n```bash\nnpm run demo.[ng|react|svelte|vue].[ios|android]\n\nnpm run demo.svelte.ios # Example\n```\n\nDemo setup is a bit special in the sense that if you want to modify/add demos you dont work directly in `demo-[ng|react|svelte|vue]`\nInstead you work in `demo-snippets/[ng|react|svelte|vue]`\nYou can start from the `install.ts` of each flavor to see how to register new demos \n\n\r\n[](#contributing)\r\n\r\n\r\n[](#contributing)\r\n\r\n## Contributing\n\n### Update repo \n\nYou can update the repo files quite easily\n\nFirst update the submodules\n\n```bash\nnpm run update\n```\n\nThen commit the changes\nThen update common files\n\n```bash\nnpm run sync\n```\nThen you can run `yarn|pnpm`, commit changed files if any\n\n### Update readme \n```bash\nnpm run readme\n```\n\n### Update doc \n```bash\nnpm run doc\n```\n\n### Publish\n\nThe publishing is completely handled by `lerna` (you can add `-- --bump major` to force a major release)\nSimply run \n```shell\nnpm run publish\n```\n\n### modifying submodules\n\nThe repo uses https:// for submodules which means you won't be able to push directly into the submodules.\nOne easy solution is t modify `~/.gitconfig` and add\n```\n[url \"ssh://git@github.com/\"]\n\tpushInsteadOf = https://github.com/\n```\n\n\r\n[](#questions)\r\n\r\n\r\n[](#questions)\r\n\r\n## Questions\n\nIf you have any questions/issues/comments please feel free to create an issue or start a conversation in the [NativeScript Community Discord](https://nativescript.org/discord).\n\n\u003c/details\u003e\n\r\n[](#demos-and-development)\r\n\r\n## Demos and Development\n\n\n### Repo Setup\n\nThe repo uses submodules. If you did not clone with ` --recursive` then you need to call\n```\ngit submodule update --init\n```\n\nThe package manager used to install and link dependencies must be `pnpm` or `yarn`. `npm` wont work.\n\nTo develop and test:\nif you use `yarn` then run `yarn`\nif you use `pnpm` then run `pnpm i`\n\n**Interactive Menu:**\n\nTo start the interactive menu, run `npm start` (or `yarn start` or `pnpm start`). This will list all of the commonly used scripts.\n\n### Build\n\n```bash\nnpm run build.all\n```\nWARNING: it seems `yarn build.all` wont always work (not finding binaries in `node_modules/.bin`) which is why the doc explicitly uses `npm run`\n\n### Demos\n\n```bash\nnpm run demo.[ng|react|svelte|vue].[ios|android]\n\nnpm run demo.svelte.ios # Example\n```\n\nDemo setup is a bit special in the sense that if you want to modify/add demos you dont work directly in `demo-[ng|react|svelte|vue]`\nInstead you work in `demo-snippets/[ng|react|svelte|vue]`\nYou can start from the `install.ts` of each flavor to see how to register new demos \n\n\r\n[](#contributing)\r\n\r\n## Contributing\n\n### Update repo \n\nYou can update the repo files quite easily\n\nFirst update the submodules\n\n```bash\nnpm run update\n```\n\nThen commit the changes\nThen update common files\n\n```bash\nnpm run sync\n```\nThen you can run `yarn|pnpm`, commit changed files if any\n\n### Update readme \n```bash\nnpm run readme\n```\n\n### Update doc \n```bash\nnpm run doc\n```\n\n### Publish\n\nThe publishing is completely handled by `lerna` (you can add `-- --bump major` to force a major release)\nSimply run \n```shell\nnpm run publish\n```\n\n### modifying submodules\n\nThe repo uses https:// for submodules which means you won't be able to push directly into the submodules.\nOne easy solution is t modify `~/.gitconfig` and add\n```\n[url \"ssh://git@github.com/\"]\n\tpushInsteadOf = https://github.com/\n```\n\r\n[](#questions)\r\n\r\n## Questions\n\nIf you have any questions/issues/comments please feel free to create an issue or start a conversation in the [NativeScript Community Discord](https://nativescript.org/discord).","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnativescript-community%2Fui-canvas","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnativescript-community%2Fui-canvas","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnativescript-community%2Fui-canvas/lists"}