{"id":26550136,"url":"https://github.com/swingcosmic/vue-declarative-canvas","last_synced_at":"2025-06-14T20:34:06.467Z","repository":{"id":223116565,"uuid":"759270148","full_name":"SwingCosmic/vue-declarative-canvas","owner":"SwingCosmic","description":"Declarative drawing \u0026 rendering in vue","archived":false,"fork":false,"pushed_at":"2025-05-26T15:58:04.000Z","size":75,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-26T17:03:04.146Z","etag":null,"topics":["canvas","declarative","renderer","vue"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SwingCosmic.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2024-02-18T05:37:39.000Z","updated_at":"2025-05-26T15:58:09.000Z","dependencies_parsed_at":"2024-03-16T18:13:26.255Z","dependency_job_id":"90fa132b-080a-420d-ad7b-21f1d7849a8e","html_url":"https://github.com/SwingCosmic/vue-declarative-canvas","commit_stats":null,"previous_names":["swingcosmic/vue-declarative-canvas"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/SwingCosmic/vue-declarative-canvas","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SwingCosmic%2Fvue-declarative-canvas","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SwingCosmic%2Fvue-declarative-canvas/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SwingCosmic%2Fvue-declarative-canvas/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SwingCosmic%2Fvue-declarative-canvas/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SwingCosmic","download_url":"https://codeload.github.com/SwingCosmic/vue-declarative-canvas/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SwingCosmic%2Fvue-declarative-canvas/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259879959,"owners_count":22925857,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["canvas","declarative","renderer","vue"],"created_at":"2025-03-22T07:30:27.632Z","updated_at":"2025-06-14T20:34:06.442Z","avatar_url":"https://github.com/SwingCosmic.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# vue-declarative-canvas\n\n基于Vue的声明式绘图渲染，可用于动态生成logo、图标、表情包等\n\n\u003e ⚠️ 由于`vue@\u003e=3.4`对`watchEffect`的破坏性改动，升级依赖将会导致组件不能工作\n\n\u003e ⚠️ 本项目还在早期开发中，API可能会频繁发生变动且不进行通知，请开发时以最新代码为准\n\n## 特性\n\n*  采用声明式的配置对象描述渲染过程，将绘图从冗长的坐标计算中解放出来，所见即所得\n\n   * 使用类似SVG的元素对象层次描述，简单直观\n   * 强大的绑定系统，支持参数引用、表达式计算和字符串模板，满足多种动态处理\n      * 表达式兼容`JavaScript`语法（甚至写`TypeScipt`也是可以的），经过语法安全检查和`Babel`编译，会在一个沙箱环境内执行\n   * 支持HTML+SVG渲染器和Canvas(pixi.js)渲染器，也可以根据配置实现其它的渲染器\n\n* 强类型的绘图模板，提供丰富的自描述元数据信息，满足编辑参数需要\n   * 绘图参数元数据描述：拥有极其严格的类型检查和参数描述，能够直接根据元数据生成编辑参数的表单组件\n   * 模板可以提供预设(presets)，通过切换预设可以让用户快速配出多种变体，便于调整修改\n   * 资源定义：描述自己用到了什么外部资源（如图片、字体等），如果要更换自己的资源加载机制也很容易\n\n## 开始使用\n\n\u003e ⚠️ 运行Binding需要`new Function()`等动态代码执行要求，在部分禁用动态代码的小程序中可能无法使用\n\n目前只实现了`HtmlRender`。\n\n```html\n\u003ctemplate\u003e\n   \u003cHtmlRender ref=\"render\"\n      v-model:params=\"params\"\n      :template=\"template\" \n      :preset=\"preset\"\u003e\n\n   \u003c/HtmlRender\u003e\n\u003c/template\u003e\n\n\u003cscript setup lang=\"ts\"\u003e\nimport { HtmlRender, CanvasTemplate, RenderInstance } from 'vue-declarative-canvas';\nimport 'vue-declarative-canvas/dist/style.css';\n\ninterface Params {\n   // 你自己的参数类型\n}\n\n// 如果将默认预设设为空，就会自动选择第一个预设\nconst preset = ref(\"\");\nconst params = ref\u003cParams\u003e({});\nconst template = ref\u003cCanvasTemplate\u003cParams\u003e\u003e({\n   // 编写模板\n});\n\nconst render = shallowRef\u003cRenderInstance\u003e(null!);\n\n\nasync function exportImage() {\n   const file = await render.value.exportToImage({\n      imageFormat: \"image/png\"\n   });\n   // 下载文件或者展示在img上\n}\n\u003c/script\u003e\n\n```\n\n## 模板元素\n\n模板元素是构成模板的基本组成部分，用于绘制图形内容，或者提供布局，或者执行数据转换逻辑。\n\n### 布局元素\n\n* Group: 分组容器，用于包含其他元素，也可以用于排列子元素，相当于SVG的`g`但支持flex布局\n\n### 内容元素\n* Text: 渲染文本元素\n* Sprite: 渲染图片，图片可以从大的图像文件中进行切割\n* Graphics: 2D几何元素，用于绘制矢量图形\n   * Shape: 每个Graphics都包含了一个几何图形的定义，包括Line, Ellipse，Polygon等，也可以使用类似SVG `path`元素的方式定义复杂图形\n\n### 重要的概念和类型\n\n1. 变换\n\n每个元素都拥有`transform`属性，可以为元素及其子元素提供2D和3D变换\n\n提供Skew、Translate、Scale3D、Rotate3D、Perspective等封装的基本变换，也可以使用上述变换的组合，或者直接使用MatrixTransform提供3x2或者4x4变换矩阵\n\n可以使用多种格式初始化transform属性的值，便于进行绑定\n\n导出图片时会自动计算画布边界，超出可视区域的部分也会被处理。大量使用变换使元素变形并超出容器（特别是在-x轴方向超出），可能会造成画布裁剪错误，或者带来性能问题。\n\n2. 带单位数值\n\n不少属性的类型是`NumberOrUnitValue\u003cU\u003e`，即可以是数值，或者后跟CSS单位的字符串。此类属性可通过不同的单位提供不同方式的数值，实现和CSS类似的便捷数值计算。\n\n对于数值来说，单位采用的是该类物理量的默认单位。例如长度的单位默认为`px`，角度的单位默认为`deg`，等等。\n\n部分属性只能使用该物理量可用单位的一部分子集，会在泛型参数`U`上指定。一些只能使用一种单位的属性，会直接将类型指定为number简化操作。\n\n\n## 绑定\n\n绑定用于将参数值动态加入到渲染中，例如把Text的文字绑到到用户输入的字符串。\n\n模板元素的所有属性（包含对象的嵌套属性和数组元素）均可以使用绑定。\n在编写模板时提供了TypeScript类型解析，可以同时使用原始类型和各种绑定类型而不报错（目前暂不支持嵌套对象的类型检查）\n\n所有的绑定均为对象，并且采用以`@`开头的特殊属性名区分\n\n绑定目前有以下几种：\n\n### 参数引用\n\n最简单的绑定，直接将参数中的某个属性绑定到当前元素的某个属性\n* @ref: 要绑定的参数的路径，对于嵌套对象，中间的每一层使用`.`分隔属性，如果为数组直接使用数字，如`positions.0.x`\n\n### 字符串模板\n\n将多个参数绑定到一个字符串模板中进行拼接\n* @refs: 要绑定的参数列表，每个参数有以下属性：\n   * @name: 参数名称，必须以`$`开头\n   * @ref: 参数引用路径\n* @str: 要拼接的字符串，使用js字符串插值语法`${$paramName}`来插入上面定义的参数`$paramName`\n\n### 表达式\n直接计算参数返回一个值\n\n* @refs: 同字符串模板\n* @expr: 合法的TypeScript表达式，使用上面的参数算出一个值\n\n可以使用ESNext的最新语法，但不会对运行时对象提供任何补丁。\n例如当前版本支持`using`变量声明，但访问`Symbol.dispose`可能得到的依然是`undefined`\n\n表达式有严格的限制，例如必须是无副作用的，不能使用任何形式的赋值表达式，不能写变量、类和函数声明\n\n表达式在全局作用域求值，可以使用部分JS全局对象如`Math`，不过`window`、`self`、`globalThis`之类的都是不能使用的，也不存在`this`。\n\n由于绘图可能发生在nodejs环境(如nw.js)或者web环境，访问DOM API、浏览器API和nodejs API将会带来未定义的行为，请尽量避免此类使用方式\n\n表达式只能写一条语句，如果计算复杂需要多行语句，可以编写箭头函数表达式，最后返回计算结果，例：\n\n```typescript\n() =\u003e {\n   const points: [number, number][] = $points;\n   const line = points\n      .map(p =\u003e p[0] + \",\" + p[1])\n      .join(\" \");\n   return `M0,0 L${line} Z`;\n};\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswingcosmic%2Fvue-declarative-canvas","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fswingcosmic%2Fvue-declarative-canvas","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswingcosmic%2Fvue-declarative-canvas/lists"}