@liquid-js/qr-code-styling 5.0.0-3 → 5.0.0-5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -74,6 +74,77 @@ Try it here <https://styled-qr.liquidjs.io/>
74
74
  </html>
75
75
  ```
76
76
 
77
+ ### Plugins <img align="right" src="https://raw.githubusercontent.com/Liquid-JS/qr-code-styling/master/src/assets/border.png" width="240" />
78
+
79
+ Version `5.0.0` of the library introduces plugin support to replace the now-deprecated `QRCodeStyling.extension`, with the ability to customize the shape of dots and corners. Existing extensions can still be applied as `plugins: [{ postProcess: extensionFn }]`.
80
+
81
+ While the old API only supports a single extension, it is now possible to apply multiple plugins or even multiple instances of a single plugin. For example, to create a QR code with a complex border:
82
+
83
+ ```ts
84
+ import { BorderPlugin } from '@liquid-js/qr-code-styling/border-plugin'
85
+
86
+ const qrCode = new QRCodeStyling({
87
+ plugins: [
88
+ new BorderPlugin({
89
+ round: 1,
90
+ size: 2,
91
+ color: '#20c9dc'
92
+ }),
93
+ new BorderPlugin({
94
+ round: 1,
95
+ size: 60,
96
+ color: '#4267b2',
97
+ text: {
98
+ font: 'sans-serif',
99
+ color: '#e9ebee',
100
+ size: 30,
101
+ top: {
102
+ content: 'Scan the'.toUpperCase()
103
+ },
104
+ bottom: {
105
+ content: 'QR code'.toUpperCase()
106
+ }
107
+ }
108
+ })
109
+ ]
110
+ // ...other options
111
+ })
112
+ ```
113
+
114
+ #### Plugin development
115
+
116
+ A simple plugin example to customize QR code dots:
117
+
118
+ ```ts
119
+ import { svgPath, DrawArgs } from '@liquid-js/qr-code-styling/plugin-utils'
120
+
121
+ const qrCode = new QRCodeStyling({
122
+ plugins: [
123
+ {
124
+ drawDot: (args: DrawArgs): SVGElement | undefined => {
125
+ const { size, x, y, document } = args
126
+
127
+ const element = document.createElementNS('http://www.w3.org/2000/svg', 'path')
128
+ // Insert your own SVG path definition, or implement neighbour-aware logic through args.getNeighbor()
129
+ element.setAttribute(
130
+ 'd',
131
+ svgPath`M ${x} ${y + (size - size) / 2}
132
+ v ${size}
133
+ h ${size / 2}
134
+ a ${size / 2} ${size / 2} 0 0 0 0 ${-size}
135
+ z`
136
+ )
137
+
138
+ return element
139
+ }
140
+ },
141
+ ]
142
+ // ...other options
143
+ })
144
+ ```
145
+
146
+ See [Border plugin](https://github.com/Liquid-JS/qr-code-styling/blob/master/src/plugins/border.ts) and [figures](https://github.com/Liquid-JS/qr-code-styling/tree/master/src/figures) for further reference.
147
+
77
148
  ### Node
78
149
 
79
150
  > ⚠️ **Note**: make sure to install peer dependencies when running on Node (not needed for browser environments)
@@ -125,44 +196,6 @@ const buffer = await new Promise((resolve) => {
125
196
  await writeFile('qr.pdf', buffer)
126
197
  ```
127
198
 
128
- ### Plugins <img align="right" src="https://raw.githubusercontent.com/Liquid-JS/qr-code-styling/master/src/assets/border.png" width="240" />
129
-
130
- Version `5.0.0` of the library introduces plugin support, enabling you to further customize the shape of dots and corners. Additionally, plugins can apply effects, such as adding borders, to enhance the final QR code output.
131
-
132
- #### Plugin development
133
-
134
- A simple plugin example to customize QR code dots:
135
-
136
- ```ts
137
- import { svgPath, DrawArgs } from '@liquid-js/qr-code-styling/plugin-utils'
138
-
139
- const qrCode = new QRCodeStyling({
140
- plugins: [
141
- {
142
- drawDot: (args: DrawArgs): SVGElement | undefined => {
143
- const { size, x, y, document } = args
144
-
145
- const element = document.createElementNS('http://www.w3.org/2000/svg', 'path')
146
- // Insert your own SVG path definition, or implement neighbour-aware logic through args.getNeighbor()
147
- element.setAttribute(
148
- 'd',
149
- svgPath`M ${x} ${y + (size - size) / 2}
150
- v ${size}
151
- h ${size / 2}
152
- a ${size / 2} ${size / 2} 0 0 0 0 ${-size}
153
- z`
154
- )
155
-
156
- return element
157
- }
158
- },
159
- ]
160
- // ...other options
161
- })
162
- ```
163
-
164
- See [Border plugin](https://github.com/Liquid-JS/qr-code-styling/blob/master/src/plugins/border.ts) and [figures](https://github.com/Liquid-JS/qr-code-styling/tree/master/src/figures) for further reference.
165
-
166
199
  ### Kanji support
167
200
 
168
201
  For Kanji mode to work, import `stringToBytesFuncs` from `@liquid-js/qr-code-styling/kanji` and inclue it with config.
@@ -1,2 +1,2 @@
1
- let t=/\.?0+$/;function e(e){return"string"==typeof e?e:e.toFixed(7).replace(t,"")}function i(t,...i){return t.reduce((t,r,n)=>{let s="";return n&&(s=i[n-1]),"number"==typeof s&&(s=e(s)),`${t}${s}${r}`},"").trim().replace(/[\s\n\r]+/gim," ")}var r,n=r||={};n.top="top",n.bottom="bottom",n.left="left",n.right="right";export var BorderPlugin=class{pluginOptions;id;constructor(t,e=Math.random().toFixed(10).substring(2)){this.pluginOptions=t,this.id=e}postProcess(t,n){let{document:s}=n,o=this.pluginOptions.size+(this.pluginOptions.margin||0)+(this.pluginOptions.innerBorder?.size||0)+(this.pluginOptions.innerBorder?.margin||0)+(this.pluginOptions.outerBorder?.size||0)+(this.pluginOptions.outerBorder?.margin||0),$=function(t,i){t.setAttribute("width",e(parseFloat(t.getAttribute("width")||"0")+2*i)),t.setAttribute("height",e(parseFloat(t.getAttribute("height")||"0")+2*i));let r=(t.getAttribute("viewBox")||"").split(" ").map((t,e)=>parseFloat(t)+(e<2?-1:2)*i);if(t.setAttribute("viewBox",r.map(e).join(" ")),!(r.length<4))return{left:r[0],right:r[2]+r[0],top:r[1],bottom:r[3]+r[1]}}(t,o);if($){var p=($.left+$.right)/2,h=($.top+$.bottom)/2,a=Math.min(n.width,n.height)/2*(1-(this.pluginOptions.round||0)),l=Math.min($.right-$.left-2*o,$.bottom-$.top-2*o)/2-a;n=i=>{const r=i.size,n=l+=(i.margin||0)+r/2,o=this.pluginOptions.round?l:0,$=this.pluginOptions.round?a:a+l;l+=r/2;const u=s.createElementNS("http://www.w3.org/2000/svg","rect");return u.setAttribute("width",e(2*($+o))),u.setAttribute("height",e(2*($+o))),u.setAttribute("x",e(p-$-o)),u.setAttribute("y",e(h-$-o)),u.setAttribute("rx",e(o)),u.setAttribute("fill","none"),u.setAttribute("stroke",i.color),u.setAttribute("stroke-width",e(r)),i.dasharray&&u.setAttribute("stroke-dasharray",i.dasharray),t.appendChild(u),n},this.pluginOptions.innerBorder&&n(this.pluginOptions.innerBorder);var u=n(this.pluginOptions);this.pluginOptions.outerBorder&&n(this.pluginOptions.outerBorder),[r.left,r.top,r.right,r.bottom].forEach(n=>{var o=this.pluginOptions.text[n];if(o){let g=Array.from(t.childNodes).find(t=>"DEFS"==t.tagName.toUpperCase());g||(g=s.createElementNS("http://www.w3.org/2000/svg","defs"),t.appendChild(g));let d=s.createElementNS("http://www.w3.org/2000/svg","path");var $=o.size||this.pluginOptions.text.size||1,l=this.pluginOptions.round?u-$/3:0;let b=this.pluginOptions.round?a:a+(u-$/3);switch(n){case r.top:d.setAttribute("d",i`M ${p} ${h+l+b} h ${-b} a ${l} ${l} 0 0 1 ${-l} ${-l} v ${-2*b} a ${l} ${l} 0 0 1 ${l} ${-l} h ${2*b} a ${l} ${l} 0 0 1 ${l} ${l} v ${2*b} a ${l} ${l} 0 0 1 ${-l} ${l} h ${-b}`);break;case r.bottom:this.pluginOptions.round?l+=2*$/3:b+=2*$/3,d.setAttribute("d",i`M ${p} ${h-l-b} h ${-b} a ${l} ${l} 0 0 0 ${-l} ${l} v ${2*b} a ${l} ${l} 0 0 0 ${l} ${l} h ${2*b} a ${l} ${l} 0 0 0 ${l} ${-l} v ${-2*b} a ${l} ${l} 0 0 0 ${-l} ${-l} h ${-b}`);break;case r.left:d.setAttribute("d",i`M ${p+l+b} ${h} v ${b} a ${l} ${l} 0 0 1 ${-l} ${l} h ${-2*b} a ${l} ${l} 0 0 1 ${-l} ${-l} v ${-2*b} a ${l} ${l} 0 0 1 ${l} ${-l} h ${2*b} a ${l} ${l} 0 0 1 ${l} ${l} v ${b}`);break;case r.right:d.setAttribute("d",i`M ${p-l-b} ${h} v ${-b} a ${l} ${l} 0 0 1 ${l} ${-l} h ${2*b} a ${l} ${l} 0 0 1 ${l} ${l} v ${2*b} a ${l} ${l} 0 0 1 ${-l} ${l} h ${-2*b} a ${l} ${l} 0 0 1 ${-l} ${-l} v ${-b}`)}n=`border-text-${n}-${this.id}`,d.setAttribute("id",n),d.setAttribute("fill","none"),(l=s.createElementNS("http://www.w3.org/2000/svg","tspan")).setAttribute("font-family",o.font||this.pluginOptions.text.font||"sans-serif"),l.setAttribute("fill",o.color||this.pluginOptions.text.color||"#000"),l.setAttribute("font-weight",e(o.fontWeight||this.pluginOptions.text.fontWeight||"normal")),l.setAttribute("font-style",o.fontStyle||this.pluginOptions.text.fontStyle||"normal"),l.setAttribute("font-size",e($)),l.textContent=o.content,(o=s.createElementNS("http://www.w3.org/2000/svg","textPath")).setAttributeNS("http://www.w3.org/1999/xlink","xlink:href","#"+n),o.setAttribute("startOffset","50%"),o.setAttribute("text-anchor","middle"),o.appendChild(l),($=s.createElementNS("http://www.w3.org/2000/svg","text")).appendChild(o),g.appendChild(d),t.appendChild($)}})}}};
1
+ let t=/\.?0+$/;function e(e){return"string"==typeof e?e:e.toFixed(7).replace(t,"")}function i(t,...i){return t.reduce((t,r,s)=>{let o="";return s&&(o=i[s-1]),"number"==typeof o&&(o=e(o)),`${t}${o}${r}`},"").trim().replace(/[\s\n\r]+/gim," ")}var r,s=r||={};s.top="top",s.bottom="bottom",s.left="left",s.right="right";export var BorderPlugin=class{pluginOptions;idSuffix;constructor(t,e=Math.random().toFixed(10).substring(2)){this.pluginOptions=t,this.idSuffix=e}postProcess(t,s){let{document:o}=s,$=this.pluginOptions.size,n=function(t,i){i=Math.max(i,0),t.setAttribute("width",e(parseFloat(t.getAttribute("width")||"0")+2*i)),t.setAttribute("height",e(parseFloat(t.getAttribute("height")||"0")+2*i));let r=(t.getAttribute("viewBox")||"").split(" ").map((t,e)=>parseFloat(t)+(e<2?-1:2)*i);if(t.setAttribute("viewBox",r.map(e).join(" ")),!(r.length<4))return{left:r[0],right:r[2]+r[0],top:r[1],bottom:r[3]+r[1]}}(t,$+(this.pluginOptions.margin||0));if(n){$=Math.abs($);var a=(n.left+n.right)/2,h=(n.top+n.bottom)/2,p=Math.min(s.width,s.height)/2*(1-(this.pluginOptions.round||0)),l=Math.min(n.right-n.left-2*$,n.bottom-n.top-2*$)/2-p+$/2,u=this.pluginOptions.round?l:0,g=this.pluginOptions.round?p:p+l;(s=o.createElementNS("http://www.w3.org/2000/svg","rect")).setAttribute("width",e(2*(g+u))),s.setAttribute("height",e(2*(g+u))),s.setAttribute("x",e(a-g-u)),s.setAttribute("y",e(h-g-u)),s.setAttribute("rx",e(u)),s.setAttribute("fill","none"),s.setAttribute("stroke",this.pluginOptions.color),s.setAttribute("stroke-width",e($)),this.pluginOptions.dasharray&&s.setAttribute("stroke-dasharray",this.pluginOptions.dasharray),t.appendChild(s),[r.left,r.top,r.right,r.bottom].forEach(s=>{var $=this.pluginOptions.text,n=$?.[s];if(n){let d=Array.from(t.childNodes).find(t=>"DEFS"==t.tagName.toUpperCase());d||(d=o.createElementNS("http://www.w3.org/2000/svg","defs"),t.appendChild(d));let b=o.createElementNS("http://www.w3.org/2000/svg","path"),f=n.size||$.size||1;switch(u=this.pluginOptions.round?l-f/3:0,g=this.pluginOptions.round?p:p+(l-f/3),s){case r.top:b.setAttribute("d",i`M ${a} ${h+u+g} h ${-g} a ${u} ${u} 0 0 1 ${-u} ${-u} v ${-2*g} a ${u} ${u} 0 0 1 ${u} ${-u} h ${2*g} a ${u} ${u} 0 0 1 ${u} ${u} v ${2*g} a ${u} ${u} 0 0 1 ${-u} ${u} h ${-g}`);break;case r.bottom:this.pluginOptions.round?u+=2*f/3:g+=2*f/3,b.setAttribute("d",i`M ${a} ${h-u-g} h ${-g} a ${u} ${u} 0 0 0 ${-u} ${u} v ${2*g} a ${u} ${u} 0 0 0 ${u} ${u} h ${2*g} a ${u} ${u} 0 0 0 ${u} ${-u} v ${-2*g} a ${u} ${u} 0 0 0 ${-u} ${-u} h ${-g}`);break;case r.left:b.setAttribute("d",i`M ${a+u+g} ${h} v ${g} a ${u} ${u} 0 0 1 ${-u} ${u} h ${-2*g} a ${u} ${u} 0 0 1 ${-u} ${-u} v ${-2*g} a ${u} ${u} 0 0 1 ${u} ${-u} h ${2*g} a ${u} ${u} 0 0 1 ${u} ${u} v ${g}`);break;case r.right:b.setAttribute("d",i`M ${a-u-g} ${h} v ${-g} a ${u} ${u} 0 0 1 ${u} ${-u} h ${2*g} a ${u} ${u} 0 0 1 ${u} ${u} v ${2*g} a ${u} ${u} 0 0 1 ${-u} ${u} h ${-2*g} a ${u} ${u} 0 0 1 ${-u} ${-u} v ${-g}`)}s=`border-text-${s}-${this.idSuffix}`,b.setAttribute("id",s),b.setAttribute("fill","none");let w=o.createElementNS("http://www.w3.org/2000/svg","tspan");w.setAttribute("font-family",n.font||$.font||"sans-serif"),w.setAttribute("fill",n.color||$.color||"#000"),w.setAttribute("font-weight",e(n.fontWeight||$.fontWeight||"normal")),w.setAttribute("font-style",n.fontStyle||$.fontStyle||"normal"),w.setAttribute("font-size",e(f)),w.textContent=n.content,($=o.createElementNS("http://www.w3.org/2000/svg","textPath")).setAttributeNS("http://www.w3.org/1999/xlink","xlink:href","#"+s),$.setAttribute("startOffset","50%"),$.setAttribute("text-anchor","middle"),$.appendChild(w),(n=o.createElementNS("http://www.w3.org/2000/svg","text")).appendChild($),d.appendChild(b),t.appendChild(n)}})}}};
2
2
  //# sourceMappingURL=border-plugin.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"border-plugin.js","sources":["../src/utils/svg.ts","../src/plugins/border.ts"],"sourcesContent":["import { RotateFigureArgs } from '../types/helper.js'\r\n\r\nconst rx = /\\.?0+$/\r\n\r\nexport function numToAttr(value: number | string) {\r\n if (typeof value == 'string') return value\r\n return value.toFixed(7).replace(rx, '')\r\n}\r\n\r\nexport function svgPath(strings: TemplateStringsArray, ...values: unknown[]) {\r\n return strings\r\n .reduce((t, v, i) => {\r\n let p: unknown = ''\r\n if (i) p = values[i - 1]\r\n if (typeof p == 'number') p = numToAttr(p)\r\n return `${t}${p}${v}`\r\n }, '')\r\n .trim()\r\n .replace(/[\\s\\n\\r]+/gim, ' ')\r\n}\r\n\r\nexport function rotateFigure<T extends SVGElement | ReadonlyArray<SVGElement>>({ draw, ...args }: RotateFigureArgs<T>) {\r\n const { x, y, size, rotation = 0 } = args\r\n const cx = x + size / 2\r\n const cy = y + size / 2\r\n\r\n const element = draw(args)\r\n if (rotation) (Array.isArray(element) ? element : [element])\r\n .forEach(el => el.setAttribute('transform', `rotate(${numToAttr((180 * rotation) / Math.PI)},${cx},${cy})`))\r\n return element\r\n}\r\n\r\nexport function scalePath(path: Array<string | number>, { x, y, size }: {\r\n x: number\r\n y: number\r\n size: number\r\n}) {\r\n let move = false\r\n let i = 0\r\n return path\r\n .map((v) => {\r\n if (typeof v == 'string') {\r\n i = 0\r\n move = v.toUpperCase() == v\r\n return v\r\n }\r\n i++\r\n v = v * size\r\n if (move) {\r\n v += i % 2 == 1 ? x : y\r\n }\r\n return numToAttr(v)\r\n })\r\n .join(' ')\r\n}\r\n\r\nexport function extendSVG(svg: SVGSVGElement, padding: number) {\r\n svg.setAttribute('width', numToAttr(parseFloat(svg.getAttribute('width') || '0') + 2 * padding))\r\n svg.setAttribute('height', numToAttr(parseFloat(svg.getAttribute('height') || '0') + 2 * padding))\r\n const vb = (svg.getAttribute('viewBox') || '').split(' ').map((v, i) => parseFloat(v) + (i < 2 ? -1 : 2) * padding)\r\n svg.setAttribute('viewBox', vb.map(numToAttr).join(' '))\r\n if (vb.length < 4)\r\n return undefined\r\n return {\r\n left: vb[0],\r\n right: vb[2] + vb[0],\r\n top: vb[1],\r\n bottom: vb[3] + vb[1]\r\n }\r\n}\r\n","import { Options, Plugin } from '../utils/options.js'\r\nimport { extendSVG, numToAttr, svgPath } from './utils.js'\r\n\r\nenum TextPosition {\r\n top = 'top',\r\n bottom = 'bottom',\r\n left = 'left',\r\n right = 'right'\r\n}\r\n\r\nexport interface BorderConfig {\r\n size: number\r\n color: string\r\n dasharray?: string\r\n margin?: number\r\n}\r\n\r\nexport interface TextConfig {\r\n font?: string\r\n color?: string\r\n size?: number\r\n fontWeight?: 'normal' | 'bold' | 'bolder' | 'lighter' | number\r\n fontStyle?: 'normal' | 'italic' | 'oblique'\r\n}\r\n\r\nexport interface BorderPluginOptions extends BorderConfig {\r\n /** Border roundnes, from 0 (square) to 1 (circle) */\r\n round?: number\r\n text: TextConfig & {\r\n [key in TextPosition]?: TextConfig & {\r\n content: string\r\n }\r\n }\r\n innerBorder?: BorderConfig\r\n outerBorder?: BorderConfig\r\n}\r\n\r\nexport class BorderPlugin implements Plugin {\r\n\r\n constructor(private readonly pluginOptions: BorderPluginOptions, private readonly id = Math.random().toFixed(10).substring(2)) { }\r\n\r\n postProcess(svg: SVGSVGElement, options: Options) {\r\n const { document } = options\r\n const thickness = (\r\n this.pluginOptions.size + (this.pluginOptions.margin || 0)\r\n + (this.pluginOptions.innerBorder?.size || 0) + (this.pluginOptions.innerBorder?.margin || 0)\r\n + (this.pluginOptions.outerBorder?.size || 0) + (this.pluginOptions.outerBorder?.margin || 0)\r\n )\r\n const drawArea = extendSVG(svg, thickness)\r\n if (!drawArea)\r\n return\r\n\r\n const cx = (drawArea.left + drawArea.right) / 2\r\n const cy = (drawArea.top + drawArea.bottom) / 2\r\n const lineSize = Math.min(options.width, options.height) / 2 * (1 - (this.pluginOptions.round || 0))\r\n let r = (Math.min(drawArea.right - drawArea.left - 2 * thickness, drawArea.bottom - drawArea.top - 2 * thickness) / 2) - lineSize\r\n\r\n const drawBorder = (cfg: BorderConfig) => {\r\n const t = cfg.size\r\n const mid = r += (cfg.margin || 0) + t / 2\r\n const pathR = this.pluginOptions.round ? r : 0\r\n const pathL = this.pluginOptions.round ? lineSize : lineSize + r\r\n r += t / 2\r\n\r\n const element = document.createElementNS('http://www.w3.org/2000/svg', 'rect')\r\n element.setAttribute('width', numToAttr((pathL + pathR) * 2))\r\n element.setAttribute('height', numToAttr((pathL + pathR) * 2))\r\n element.setAttribute('x', numToAttr(cx - pathL - pathR))\r\n element.setAttribute('y', numToAttr(cy - pathL - pathR))\r\n element.setAttribute('rx', numToAttr(pathR))\r\n element.setAttribute('fill', 'none')\r\n element.setAttribute('stroke', cfg.color)\r\n element.setAttribute('stroke-width', numToAttr(t))\r\n if (cfg.dasharray) {\r\n element.setAttribute('stroke-dasharray', cfg.dasharray)\r\n }\r\n\r\n svg.appendChild(element)\r\n return mid\r\n }\r\n\r\n if (this.pluginOptions.innerBorder) {\r\n drawBorder(this.pluginOptions.innerBorder)\r\n }\r\n\r\n const textRadius = drawBorder(this.pluginOptions)\r\n\r\n if (this.pluginOptions.outerBorder) {\r\n drawBorder(this.pluginOptions.outerBorder)\r\n }\r\n\r\n [TextPosition.left, TextPosition.top, TextPosition.right, TextPosition.bottom].forEach(postion => {\r\n const config = this.pluginOptions.text[postion]\r\n if (config) {\r\n let defs = Array.from(svg.childNodes).find(v => (v as HTMLElement).tagName.toUpperCase() == 'DEFS')\r\n if (!defs) {\r\n defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs')\r\n svg.appendChild(defs)\r\n }\r\n const element = document.createElementNS('http://www.w3.org/2000/svg', 'path')\r\n const size = (config.size || this.pluginOptions.text.size || 1)\r\n let pathR = this.pluginOptions.round ? textRadius - size / 3 : 0\r\n let pathL = this.pluginOptions.round ? lineSize : lineSize + (textRadius - size / 3)\r\n switch (postion) {\r\n case TextPosition.top:\r\n element.setAttribute(\r\n 'd',\r\n svgPath`M ${cx} ${cy + pathR + pathL}\r\n h ${-pathL}\r\n a ${pathR} ${pathR} 0 0 1 ${-pathR} ${-pathR}\r\n v ${-2 * pathL}\r\n a ${pathR} ${pathR} 0 0 1 ${pathR} ${-pathR}\r\n h ${2 * pathL}\r\n a ${pathR} ${pathR} 0 0 1 ${pathR} ${pathR}\r\n v ${2 * pathL}\r\n a ${pathR} ${pathR} 0 0 1 ${-pathR} ${pathR}\r\n h ${-pathL}`\r\n )\r\n break\r\n case TextPosition.bottom:\r\n if (this.pluginOptions.round)\r\n pathR += size * 2 / 3\r\n else\r\n pathL += size * 2 / 3\r\n element.setAttribute(\r\n 'd',\r\n svgPath`M ${cx} ${cy - pathR - pathL}\r\n h ${-pathL}\r\n a ${pathR} ${pathR} 0 0 0 ${-pathR} ${pathR}\r\n v ${2 * pathL}\r\n a ${pathR} ${pathR} 0 0 0 ${pathR} ${pathR}\r\n h ${2 * pathL}\r\n a ${pathR} ${pathR} 0 0 0 ${pathR} ${-pathR}\r\n v ${-2 * pathL}\r\n a ${pathR} ${pathR} 0 0 0 ${-pathR} ${-pathR}\r\n h ${-pathL}`\r\n )\r\n break\r\n case TextPosition.left:\r\n element.setAttribute(\r\n 'd',\r\n svgPath`M ${cx + pathR + pathL} ${cy}\r\n v ${pathL}\r\n a ${pathR} ${pathR} 0 0 1 ${-pathR} ${pathR}\r\n h ${-2 * pathL}\r\n a ${pathR} ${pathR} 0 0 1 ${-pathR} ${-pathR}\r\n v ${-2 * pathL}\r\n a ${pathR} ${pathR} 0 0 1 ${pathR} ${-pathR}\r\n h ${2 * pathL}\r\n a ${pathR} ${pathR} 0 0 1 ${pathR} ${pathR}\r\n v ${pathL}`\r\n )\r\n break\r\n case TextPosition.right:\r\n element.setAttribute(\r\n 'd',\r\n svgPath`M ${cx - pathR - pathL} ${cy}\r\n v ${-pathL}\r\n a ${pathR} ${pathR} 0 0 1 ${pathR} ${-pathR}\r\n h ${2 * pathL}\r\n a ${pathR} ${pathR} 0 0 1 ${pathR} ${pathR}\r\n v ${2 * pathL}\r\n a ${pathR} ${pathR} 0 0 1 ${-pathR} ${pathR}\r\n h ${-2 * pathL}\r\n a ${pathR} ${pathR} 0 0 1 ${-pathR} ${-pathR}\r\n v ${-pathL}`\r\n )\r\n break\r\n }\r\n const id = `border-text-${postion}-${this.id}`\r\n element.setAttribute('id', id)\r\n element.setAttribute('fill', 'none')\r\n\r\n const span = document.createElementNS('http://www.w3.org/2000/svg', 'tspan')\r\n span.setAttribute('font-family', config.font || this.pluginOptions.text.font || 'sans-serif')\r\n span.setAttribute('fill', config.color || this.pluginOptions.text.color || '#000')\r\n span.setAttribute('font-weight', numToAttr(config.fontWeight || this.pluginOptions.text.fontWeight || 'normal'))\r\n span.setAttribute('font-style', config.fontStyle || this.pluginOptions.text.fontStyle || 'normal')\r\n span.setAttribute('font-size', numToAttr(size))\r\n span.textContent = config.content\r\n\r\n const textPath = document.createElementNS('http://www.w3.org/2000/svg', 'textPath')\r\n textPath.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', '#' + id)\r\n textPath.setAttribute('startOffset', '50%')\r\n textPath.setAttribute('text-anchor', 'middle')\r\n textPath.appendChild(span)\r\n\r\n const text = document.createElementNS('http://www.w3.org/2000/svg', 'text')\r\n text.appendChild(textPath)\r\n\r\n defs.appendChild(element)\r\n svg.appendChild(text)\r\n }\r\n })\r\n }\r\n}\r\n"],"names":["rx","numToAttr","value","toFixed","replace","svgPath","strings","values","reduce","t","v","i","p","trim","TextPosition","A","top","bottom","left","right","BorderPlugin","pluginOptions","id","constructor","Math","random","substring","this","postProcess","svg","options","document","thickness","size","margin","innerBorder","outerBorder","drawArea","extendSVG","padding","setAttribute","parseFloat","getAttribute","split","map","vb","join","length","cx","cy","lineSize","min","width","height","round","r","drawBorder","cfg","mid","pathR","pathL","element","createElementNS","color","dasharray","appendChild","textRadius","forEach","postion","config","defs","Array","from","childNodes","find","tagName","toUpperCase","text","span","font","fontWeight","fontStyle","textContent","content","textPath","setAttributeNS"],"mappings":"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"}
1
+ {"version":3,"file":"border-plugin.js","sources":["../src/utils/svg.ts","../src/plugins/border.ts"],"sourcesContent":["import { RotateFigureArgs } from '../types/helper.js'\r\n\r\nconst rx = /\\.?0+$/\r\n\r\nexport function numToAttr(value: number | string) {\r\n if (typeof value == 'string') return value\r\n return value.toFixed(7).replace(rx, '')\r\n}\r\n\r\nexport function svgPath(strings: TemplateStringsArray, ...values: unknown[]) {\r\n return strings\r\n .reduce((t, v, i) => {\r\n let p: unknown = ''\r\n if (i) p = values[i - 1]\r\n if (typeof p == 'number') p = numToAttr(p)\r\n return `${t}${p}${v}`\r\n }, '')\r\n .trim()\r\n .replace(/[\\s\\n\\r]+/gim, ' ')\r\n}\r\n\r\nexport function rotateFigure<T extends SVGElement | ReadonlyArray<SVGElement>>({ draw, ...args }: RotateFigureArgs<T>) {\r\n const { x, y, size, rotation = 0 } = args\r\n const cx = x + size / 2\r\n const cy = y + size / 2\r\n\r\n const element = draw(args)\r\n if (rotation) (Array.isArray(element) ? element : [element])\r\n .forEach(el => el.setAttribute('transform', `rotate(${numToAttr((180 * rotation) / Math.PI)},${cx},${cy})`))\r\n return element\r\n}\r\n\r\nexport function scalePath(path: Array<string | number>, { x, y, size }: {\r\n x: number\r\n y: number\r\n size: number\r\n}) {\r\n let move = false\r\n let i = 0\r\n return path\r\n .map((v) => {\r\n if (typeof v == 'string') {\r\n i = 0\r\n move = v.toUpperCase() == v\r\n return v\r\n }\r\n i++\r\n v = v * size\r\n if (move) {\r\n v += i % 2 == 1 ? x : y\r\n }\r\n return numToAttr(v)\r\n })\r\n .join(' ')\r\n}\r\n\r\nexport function extendSVG(svg: SVGSVGElement, padding: number) {\r\n padding = Math.max(padding, 0)\r\n svg.setAttribute('width', numToAttr(parseFloat(svg.getAttribute('width') || '0') + 2 * padding))\r\n svg.setAttribute('height', numToAttr(parseFloat(svg.getAttribute('height') || '0') + 2 * padding))\r\n const vb = (svg.getAttribute('viewBox') || '').split(' ').map((v, i) => parseFloat(v) + (i < 2 ? -1 : 2) * padding)\r\n svg.setAttribute('viewBox', vb.map(numToAttr).join(' '))\r\n if (vb.length < 4)\r\n return undefined\r\n return {\r\n left: vb[0],\r\n right: vb[2] + vb[0],\r\n top: vb[1],\r\n bottom: vb[3] + vb[1]\r\n }\r\n}\r\n","import { Options, Plugin } from '../utils/options.js'\r\nimport { extendSVG, numToAttr, svgPath } from './utils.js'\r\n\r\nenum TextPosition {\r\n top = 'top',\r\n bottom = 'bottom',\r\n left = 'left',\r\n right = 'right'\r\n}\r\n\r\nexport interface TextConfig {\r\n font?: string\r\n color?: string\r\n size?: number\r\n fontWeight?: 'normal' | 'bold' | 'bolder' | 'lighter' | number\r\n fontStyle?: 'normal' | 'italic' | 'oblique'\r\n}\r\n\r\nexport interface BorderPluginOptions {\r\n /** Border roundnes, from 0 (square) to 1 (circle) */\r\n round?: number\r\n size: number\r\n color: string\r\n dasharray?: string\r\n margin?: number\r\n text?: TextConfig & {\r\n [key in TextPosition]?: TextConfig & {\r\n content: string\r\n }\r\n }\r\n}\r\n\r\nexport class BorderPlugin implements Plugin {\r\n\r\n constructor(\r\n private readonly pluginOptions: BorderPluginOptions,\r\n /** @ignore Create unique id for SVG elements to prevent naming collisions; specify your own if neccesary e.g. for testing */\r\n private readonly idSuffix = Math.random().toFixed(10).substring(2)\r\n ) { }\r\n\r\n postProcess(svg: SVGSVGElement, options: Options) {\r\n const { document } = options\r\n const margin = this.pluginOptions.margin || 0\r\n let thickness = this.pluginOptions.size\r\n const drawArea = extendSVG(svg, thickness + margin)\r\n if (!drawArea)\r\n return\r\n\r\n thickness = Math.abs(thickness)\r\n\r\n const cx = (drawArea.left + drawArea.right) / 2\r\n const cy = (drawArea.top + drawArea.bottom) / 2\r\n const lineSize = Math.min(options.width, options.height) / 2 * (1 - (this.pluginOptions.round || 0))\r\n const r = (Math.min(drawArea.right - drawArea.left - 2 * thickness, drawArea.bottom - drawArea.top - 2 * thickness) / 2) - lineSize + thickness / 2\r\n\r\n let pathR = this.pluginOptions.round ? r : 0\r\n let pathL = this.pluginOptions.round ? lineSize : lineSize + r\r\n\r\n const borderEl = document.createElementNS('http://www.w3.org/2000/svg', 'rect')\r\n borderEl.setAttribute('width', numToAttr((pathL + pathR) * 2))\r\n borderEl.setAttribute('height', numToAttr((pathL + pathR) * 2))\r\n borderEl.setAttribute('x', numToAttr(cx - pathL - pathR))\r\n borderEl.setAttribute('y', numToAttr(cy - pathL - pathR))\r\n borderEl.setAttribute('rx', numToAttr(pathR))\r\n borderEl.setAttribute('fill', 'none')\r\n borderEl.setAttribute('stroke', this.pluginOptions.color)\r\n borderEl.setAttribute('stroke-width', numToAttr(thickness))\r\n if (this.pluginOptions.dasharray) {\r\n borderEl.setAttribute('stroke-dasharray', this.pluginOptions.dasharray)\r\n }\r\n\r\n svg.appendChild(borderEl);\r\n\r\n [TextPosition.left, TextPosition.top, TextPosition.right, TextPosition.bottom].forEach(postion => {\r\n const textCfg = this.pluginOptions.text\r\n const config = textCfg?.[postion]\r\n if (config) {\r\n let defs = Array.from(svg.childNodes).find(v => (v as HTMLElement).tagName.toUpperCase() == 'DEFS')\r\n if (!defs) {\r\n defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs')\r\n svg.appendChild(defs)\r\n }\r\n const element = document.createElementNS('http://www.w3.org/2000/svg', 'path')\r\n const size = (config.size || textCfg.size || 1)\r\n pathR = this.pluginOptions.round ? r - size / 3 : 0\r\n pathL = this.pluginOptions.round ? lineSize : lineSize + (r - size / 3)\r\n switch (postion) {\r\n case TextPosition.top:\r\n element.setAttribute(\r\n 'd',\r\n svgPath`M ${cx} ${cy + pathR + pathL}\r\n h ${-pathL}\r\n a ${pathR} ${pathR} 0 0 1 ${-pathR} ${-pathR}\r\n v ${-2 * pathL}\r\n a ${pathR} ${pathR} 0 0 1 ${pathR} ${-pathR}\r\n h ${2 * pathL}\r\n a ${pathR} ${pathR} 0 0 1 ${pathR} ${pathR}\r\n v ${2 * pathL}\r\n a ${pathR} ${pathR} 0 0 1 ${-pathR} ${pathR}\r\n h ${-pathL}`\r\n )\r\n break\r\n case TextPosition.bottom:\r\n if (this.pluginOptions.round)\r\n pathR += size * 2 / 3\r\n else\r\n pathL += size * 2 / 3\r\n element.setAttribute(\r\n 'd',\r\n svgPath`M ${cx} ${cy - pathR - pathL}\r\n h ${-pathL}\r\n a ${pathR} ${pathR} 0 0 0 ${-pathR} ${pathR}\r\n v ${2 * pathL}\r\n a ${pathR} ${pathR} 0 0 0 ${pathR} ${pathR}\r\n h ${2 * pathL}\r\n a ${pathR} ${pathR} 0 0 0 ${pathR} ${-pathR}\r\n v ${-2 * pathL}\r\n a ${pathR} ${pathR} 0 0 0 ${-pathR} ${-pathR}\r\n h ${-pathL}`\r\n )\r\n break\r\n case TextPosition.left:\r\n element.setAttribute(\r\n 'd',\r\n svgPath`M ${cx + pathR + pathL} ${cy}\r\n v ${pathL}\r\n a ${pathR} ${pathR} 0 0 1 ${-pathR} ${pathR}\r\n h ${-2 * pathL}\r\n a ${pathR} ${pathR} 0 0 1 ${-pathR} ${-pathR}\r\n v ${-2 * pathL}\r\n a ${pathR} ${pathR} 0 0 1 ${pathR} ${-pathR}\r\n h ${2 * pathL}\r\n a ${pathR} ${pathR} 0 0 1 ${pathR} ${pathR}\r\n v ${pathL}`\r\n )\r\n break\r\n case TextPosition.right:\r\n element.setAttribute(\r\n 'd',\r\n svgPath`M ${cx - pathR - pathL} ${cy}\r\n v ${-pathL}\r\n a ${pathR} ${pathR} 0 0 1 ${pathR} ${-pathR}\r\n h ${2 * pathL}\r\n a ${pathR} ${pathR} 0 0 1 ${pathR} ${pathR}\r\n v ${2 * pathL}\r\n a ${pathR} ${pathR} 0 0 1 ${-pathR} ${pathR}\r\n h ${-2 * pathL}\r\n a ${pathR} ${pathR} 0 0 1 ${-pathR} ${-pathR}\r\n v ${-pathL}`\r\n )\r\n break\r\n }\r\n const id = `border-text-${postion}-${this.idSuffix}`\r\n element.setAttribute('id', id)\r\n element.setAttribute('fill', 'none')\r\n\r\n const span = document.createElementNS('http://www.w3.org/2000/svg', 'tspan')\r\n span.setAttribute('font-family', config.font || textCfg.font || 'sans-serif')\r\n span.setAttribute('fill', config.color || textCfg.color || '#000')\r\n span.setAttribute('font-weight', numToAttr(config.fontWeight || textCfg.fontWeight || 'normal'))\r\n span.setAttribute('font-style', config.fontStyle || textCfg.fontStyle || 'normal')\r\n span.setAttribute('font-size', numToAttr(size))\r\n span.textContent = config.content\r\n\r\n const textPath = document.createElementNS('http://www.w3.org/2000/svg', 'textPath')\r\n textPath.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', '#' + id)\r\n textPath.setAttribute('startOffset', '50%')\r\n textPath.setAttribute('text-anchor', 'middle')\r\n textPath.appendChild(span)\r\n\r\n const text = document.createElementNS('http://www.w3.org/2000/svg', 'text')\r\n text.appendChild(textPath)\r\n\r\n defs.appendChild(element)\r\n svg.appendChild(text)\r\n }\r\n })\r\n }\r\n}\r\n"],"names":["rx","numToAttr","value","toFixed","replace","svgPath","strings","values","reduce","t","v","i","p","trim","TextPosition","B","top","bottom","left","right","pluginOptions","idSuffix","constructor","Math","random","substring","this","postProcess","svg","options","document","thickness","size","drawArea","extendSVG","padding","max","setAttribute","parseFloat","getAttribute","split","map","vb","join","length","margin","abs","cx","cy","lineSize","min","width","height","round","pathR","r","pathL","borderEl","createElementNS","color","dasharray","appendChild","forEach","postion","text","textCfg","config","defs","Array","from","childNodes","find","tagName","toUpperCase","element","id","span","font","fontWeight","fontStyle","textContent","content","textPath","setAttributeNS"],"mappings":"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"}
@@ -20,7 +20,7 @@ export declare class QRCodeStyling {
20
20
  /** This container will be used for appending of the QR code */
21
21
  container?: HTMLElement): void;
22
22
  /**
23
- * @deprecated Use options.plugins
23
+ * @deprecated Use options.plugins with a postProcess hook
24
24
  * @example
25
25
  *
26
26
  * ```js
@@ -49,7 +49,7 @@ export declare class QRCodeStyling {
49
49
  /** Extension is a function that takes svg and previously applied options and modifies an svg */
50
50
  extension: ExtensionFunction): void;
51
51
  /**
52
- * @deprecated Use options.plugins
52
+ * @deprecated Use options.plugins with a postProcess hook
53
53
  */
54
54
  deleteExtension(): void;
55
55
  serialize(): Promise<string | undefined>;
@@ -3,6 +3,7 @@ import { Options } from '../utils/options.js';
3
3
  export declare class QRSVG {
4
4
  private options;
5
5
  private _element;
6
+ private _fakeMatrix?;
6
7
  get element(): SVGSVGElement;
7
8
  private defs;
8
9
  private backgroundMask?;
@@ -1,4 +1,4 @@
1
1
  import { DrawArgs } from '../types/helper.js';
2
2
  import { CornerSquareType, Plugin } from '../utils/options.js';
3
- export declare function getQrCornerSquareFigure(type: `${CornerSquareType}`): (args: DrawArgs) => readonly [SVGPathElement, SVGPathElement];
3
+ export declare function getQrCornerSquareFigure(type: `${CornerSquareType}`): (args: DrawArgs) => readonly [SVGElement, SVGElement];
4
4
  export declare function drawPluginCornerSquare(plugins: Plugin[]): (args: DrawArgs) => readonly [SVGElement, SVGElement] | undefined;
@@ -0,0 +1,27 @@
1
+ import { DrawArgs } from '../types/helper.js';
2
+ /**
3
+ * Draw square lines with rounded corners and endpoints
4
+ */
5
+ export declare function roundedCorners({ x, y, size, document, getNeighbor }: DrawArgs, { corner, end }?: {
6
+ corner?: ((args: import("../types/helper.js").BasicFigureDrawArgs) => SVGElement) | undefined;
7
+ end?: ((args: import("../types/helper.js").BasicFigureDrawArgs, { height }?: {
8
+ height?: number | undefined;
9
+ }) => SVGElement) | undefined;
10
+ }): SVGElement;
11
+ /**
12
+ * Draw square lines with rounded corners and half-rounded endpoints
13
+ */
14
+ export declare function classy({ x, y, size, document, getNeighbor }: DrawArgs, { corner }?: {
15
+ corner?: ((args: import("../types/helper.js").BasicFigureDrawArgs) => SVGElement) | undefined;
16
+ }): SVGElement;
17
+ /**
18
+ * Draw stripes with rounded or square endpoints
19
+ */
20
+ export declare function stripes({ x, y, size, document, getNeighbor }: DrawArgs, { stripe, rotation, endpoint, dot }?: {
21
+ stripe?: number | undefined;
22
+ rotation?: number | undefined;
23
+ endpoint?: ((args: import("../types/helper.js").BasicFigureDrawArgs, { height }?: {
24
+ height?: number | undefined;
25
+ }) => SVGElement) | undefined;
26
+ dot?: ((args: import("../types/helper.js").BasicFigureDrawArgs) => SVGElement) | undefined;
27
+ }): SVGElement;
@@ -1,25 +1,25 @@
1
1
  import { BasicFigureDrawArgs } from '../types/helper.js';
2
2
  export declare const DotElements: {
3
- dot: (args: BasicFigureDrawArgs) => SVGCircleElement;
3
+ dot: (args: BasicFigureDrawArgs) => SVGElement;
4
4
  square: (args: BasicFigureDrawArgs, { width, height }?: {
5
5
  width?: number | undefined;
6
6
  height?: number | undefined;
7
- }) => SVGRectElement;
7
+ }) => SVGElement;
8
8
  sideRounded: (args: BasicFigureDrawArgs, { height }?: {
9
9
  height?: number | undefined;
10
- }) => SVGPathElement;
11
- cornerRounded: (args: BasicFigureDrawArgs) => SVGPathElement;
12
- cornerExtraRounded: (args: BasicFigureDrawArgs) => SVGPathElement;
13
- cornersRounded: (args: BasicFigureDrawArgs) => SVGPathElement;
14
- wave: (args: BasicFigureDrawArgs) => SVGPathElement;
15
- heart: (args: BasicFigureDrawArgs) => SVGPathElement;
16
- rounded: (args: BasicFigureDrawArgs) => SVGRectElement;
17
- classy: (args: BasicFigureDrawArgs) => SVGPathElement;
18
- inpoint: (args: BasicFigureDrawArgs) => SVGPathElement;
10
+ }) => SVGElement;
11
+ cornerRounded: (args: BasicFigureDrawArgs) => SVGElement;
12
+ cornerExtraRounded: (args: BasicFigureDrawArgs) => SVGElement;
13
+ classyDot: (args: BasicFigureDrawArgs) => SVGElement;
14
+ wave: (args: BasicFigureDrawArgs) => SVGElement;
15
+ heart: (args: BasicFigureDrawArgs) => SVGElement;
16
+ rounded: (args: BasicFigureDrawArgs) => SVGElement;
17
+ classy: (args: BasicFigureDrawArgs) => SVGElement;
18
+ inpoint: (args: BasicFigureDrawArgs) => SVGElement;
19
19
  star: (args: BasicFigureDrawArgs, { spikes, outerRadius, innerRadius }?: {
20
20
  spikes?: number | undefined;
21
21
  outerRadius?: number | undefined;
22
22
  innerRadius?: number | undefined;
23
- }) => SVGPathElement;
24
- weave: (args: BasicFigureDrawArgs) => SVGPathElement;
23
+ }) => SVGElement;
24
+ weave: (args: BasicFigureDrawArgs) => SVGElement;
25
25
  };
@@ -1,9 +1,9 @@
1
1
  import { BasicFigureDrawArgs } from '../types/helper.js';
2
2
  export declare const SquareElements: {
3
- dot: (args: BasicFigureDrawArgs) => readonly [SVGPathElement, SVGPathElement];
4
- square: (args: BasicFigureDrawArgs) => readonly [SVGPathElement, SVGPathElement];
5
- extraRounded: (args: BasicFigureDrawArgs) => readonly [SVGPathElement, SVGPathElement];
6
- classy: (args: BasicFigureDrawArgs) => readonly [SVGPathElement, SVGPathElement];
7
- inpoint: (args: BasicFigureDrawArgs) => readonly [SVGPathElement, SVGPathElement];
8
- centerCircle: (args: BasicFigureDrawArgs) => readonly [SVGPathElement, SVGPathElement];
3
+ dot: (args: BasicFigureDrawArgs) => [SVGElement, SVGElement];
4
+ square: (args: BasicFigureDrawArgs) => [SVGElement, SVGElement];
5
+ extraRounded: (args: BasicFigureDrawArgs) => [SVGElement, SVGElement];
6
+ classy: (args: BasicFigureDrawArgs) => [SVGElement, SVGElement];
7
+ inpoint: (args: BasicFigureDrawArgs) => [SVGElement, SVGElement];
8
+ centerCircle: (args: BasicFigureDrawArgs) => [SVGElement, SVGElement];
9
9
  };
@@ -1,2 +1,2 @@
1
- let t=/\.?0+$/;function e(e){return"string"==typeof e?e:e.toFixed(7).replace(t,"")}function r(t,r){t.setAttribute("width",e(parseFloat(t.getAttribute("width")||"0")+2*r)),t.setAttribute("height",e(parseFloat(t.getAttribute("height")||"0")+2*r));let i=(t.getAttribute("viewBox")||"").split(" ").map((t,e)=>parseFloat(t)+(e<2?-1:2)*r);if(t.setAttribute("viewBox",i.map(e).join(" ")),!(i.length<4))return{left:i[0],right:i[2]+i[0],top:i[1],bottom:i[3]+i[1]}}function i({draw:t,...r}){let{x:i,y:o,size:n,rotation:a=0}=r,u=i+n/2,s=o+n/2;return t=t(r),a&&(Array.isArray(t)?t:[t]).forEach(t=>t.setAttribute("transform",`rotate(${e(180*a/Math.PI)},${u},${s})`)),t}function o(t,{x:r,y:i,size:o}){let n=!1,a=0;return t.map(t=>"string"==typeof t?(a=0,n=t.toUpperCase()==t,t):(a++,t*=o,n&&(t+=a%2==1?r:i),e(t))).join(" ")}function n(t,...r){return t.reduce((t,i,o)=>{let n="";return o&&(n=r[o-1]),"number"==typeof n&&(n=e(n)),`${t}${n}${i}`},"").trim().replace(/[\s\n\r]+/gim," ")}export{r as extendSVG,e as numToAttr,i as rotateFigure,o as scalePath,n as svgPath};
1
+ let t=/\.?0+$/;function e(e){return"string"==typeof e?e:e.toFixed(7).replace(t,"")}function r(t,r){r=Math.max(r,0),t.setAttribute("width",e(parseFloat(t.getAttribute("width")||"0")+2*r)),t.setAttribute("height",e(parseFloat(t.getAttribute("height")||"0")+2*r));let i=(t.getAttribute("viewBox")||"").split(" ").map((t,e)=>parseFloat(t)+(e<2?-1:2)*r);if(t.setAttribute("viewBox",i.map(e).join(" ")),!(i.length<4))return{left:i[0],right:i[2]+i[0],top:i[1],bottom:i[3]+i[1]}}function i({draw:t,...r}){let{x:i,y:o,size:n,rotation:a=0}=r,u=i+n/2,s=o+n/2;return t=t(r),a&&(Array.isArray(t)?t:[t]).forEach(t=>t.setAttribute("transform",`rotate(${e(180*a/Math.PI)},${u},${s})`)),t}function o(t,{x:r,y:i,size:o}){let n=!1,a=0;return t.map(t=>"string"==typeof t?(a=0,n=t.toUpperCase()==t,t):(a++,t*=o,n&&(t+=a%2==1?r:i),e(t))).join(" ")}function n(t,...r){return t.reduce((t,i,o)=>{let n="";return o&&(n=r[o-1]),"number"==typeof n&&(n=e(n)),`${t}${n}${i}`},"").trim().replace(/[\s\n\r]+/gim," ")}export{r as extendSVG,e as numToAttr,i as rotateFigure,o as scalePath,n as svgPath};
2
2
  //# sourceMappingURL=plugin-utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-utils.js","sources":["../src/utils/svg.ts"],"sourcesContent":["import { RotateFigureArgs } from '../types/helper.js'\r\n\r\nconst rx = /\\.?0+$/\r\n\r\nexport function numToAttr(value: number | string) {\r\n if (typeof value == 'string') return value\r\n return value.toFixed(7).replace(rx, '')\r\n}\r\n\r\nexport function svgPath(strings: TemplateStringsArray, ...values: unknown[]) {\r\n return strings\r\n .reduce((t, v, i) => {\r\n let p: unknown = ''\r\n if (i) p = values[i - 1]\r\n if (typeof p == 'number') p = numToAttr(p)\r\n return `${t}${p}${v}`\r\n }, '')\r\n .trim()\r\n .replace(/[\\s\\n\\r]+/gim, ' ')\r\n}\r\n\r\nexport function rotateFigure<T extends SVGElement | ReadonlyArray<SVGElement>>({ draw, ...args }: RotateFigureArgs<T>) {\r\n const { x, y, size, rotation = 0 } = args\r\n const cx = x + size / 2\r\n const cy = y + size / 2\r\n\r\n const element = draw(args)\r\n if (rotation) (Array.isArray(element) ? element : [element])\r\n .forEach(el => el.setAttribute('transform', `rotate(${numToAttr((180 * rotation) / Math.PI)},${cx},${cy})`))\r\n return element\r\n}\r\n\r\nexport function scalePath(path: Array<string | number>, { x, y, size }: {\r\n x: number\r\n y: number\r\n size: number\r\n}) {\r\n let move = false\r\n let i = 0\r\n return path\r\n .map((v) => {\r\n if (typeof v == 'string') {\r\n i = 0\r\n move = v.toUpperCase() == v\r\n return v\r\n }\r\n i++\r\n v = v * size\r\n if (move) {\r\n v += i % 2 == 1 ? x : y\r\n }\r\n return numToAttr(v)\r\n })\r\n .join(' ')\r\n}\r\n\r\nexport function extendSVG(svg: SVGSVGElement, padding: number) {\r\n svg.setAttribute('width', numToAttr(parseFloat(svg.getAttribute('width') || '0') + 2 * padding))\r\n svg.setAttribute('height', numToAttr(parseFloat(svg.getAttribute('height') || '0') + 2 * padding))\r\n const vb = (svg.getAttribute('viewBox') || '').split(' ').map((v, i) => parseFloat(v) + (i < 2 ? -1 : 2) * padding)\r\n svg.setAttribute('viewBox', vb.map(numToAttr).join(' '))\r\n if (vb.length < 4)\r\n return undefined\r\n return {\r\n left: vb[0],\r\n right: vb[2] + vb[0],\r\n top: vb[1],\r\n bottom: vb[3] + vb[1]\r\n }\r\n}\r\n"],"names":["rx","numToAttr","value","toFixed","replace","extendSVG","svg","setAttribute","k","parseFloat","getAttribute","d","a","b","split","h","map","i","length","left","right","vb","top","bottom","rotateFigure","x","y","rotation","e","cy","args","forEach","element","Math","PI","l","scalePath","c","f","v","size","move","join","reduce","trim","svgPath"],"mappings":"AAEA,IAAAA,WAEMC,SAAUA,EAAUC,GACtB,MAAoB,mBAAiBA,EAC9BA,EAAMC,QAAQ,GAAGC,QAAQJ,EAAI,GAFQ,YAoD1CK,EAAAA,GAAAA,EAAoBC,aAClBC,QAAaC,EAAAC,0BAAkCC,eAAf,EAAwCC,IAAlDC,EAAAL,aACtBA,SAAaC,EAAAC,0BAAmCC,gBAAf,EAAyCC,IAAnD,IAAAE,GAC3BD,EAAAF,aAAYA,gBAAJI,MAAqCA,SAAE,CAAvCC,EAAgDC,IAAEP,WAASA,IAAAA,EAAA,GAAT,EAA2BQ,GAAAN,GACzD,GADyDC,EAA3BL,aACtDA,UAAaM,EAAAG,IAAjBR,GAA+BQ,KAAH,QAA5BH,EACAK,OAAOA,SAAP,CAEAC,KAAAN,EACIM,GAAAA,MADGN,EAEHO,GAAAA,EAAOC,GAAAC,IAAWT,EAFf,GAGHS,OACAC,EAAAA,GAAAA,EAAQF,GAAA,aA9CVG,KAAsBZ,KAAqDD,IAAM,IAA3Dc,EACxBZ,EAAAa,EAAAX,OAASW,EAAGC,gBAAMA,EAAUd,EAA5Be,EAAA,QAAA,EAMyGC,kBAFzFC,MAEXC,cADUnB,IAAyBoB,QACnCD,GAAAA,EAAAA,aAAiBxB,YAAa,kBAAuB0B,KAAiBN,OAAiBO,KAA5CC,OAChDvB,CAAA,CAAA,gBAGEwB,EAAAA,EAAAA,EAAAA,KAAkDrB,IAAA,IAAAa,GAAQ,EAAAS,EAAR,EAIvD,OACczB,EAAXI,IAEAsB,GACe,iBAALC,GACcF,EAAA,EAAAT,EAAhBU,8BAEWvB,EACAwB,IAEXtB,GAAAoB,EACIE,GAAIC,EACJC,KACcjC,EAAIiB,KAEtBiB,KAAA,IAAiBH,oBA1CN,OACnB3B,EAAA+B,OACKA,UAAWJ,IAAJF,EAAY,GAGhB,OAFAT,IAAiBS,EACbpB,EAAJW,EAAA,IACI,iBAAAS,QAAJA,IACA,GAAAxB,wBAEH+B,QACAxC,eAAQ,IAAA,QAT0DC,eAAAG,eAAAgB,kBAAAY,eAAAS"}
1
+ {"version":3,"file":"plugin-utils.js","sources":["../src/utils/svg.ts"],"sourcesContent":["import { RotateFigureArgs } from '../types/helper.js'\r\n\r\nconst rx = /\\.?0+$/\r\n\r\nexport function numToAttr(value: number | string) {\r\n if (typeof value == 'string') return value\r\n return value.toFixed(7).replace(rx, '')\r\n}\r\n\r\nexport function svgPath(strings: TemplateStringsArray, ...values: unknown[]) {\r\n return strings\r\n .reduce((t, v, i) => {\r\n let p: unknown = ''\r\n if (i) p = values[i - 1]\r\n if (typeof p == 'number') p = numToAttr(p)\r\n return `${t}${p}${v}`\r\n }, '')\r\n .trim()\r\n .replace(/[\\s\\n\\r]+/gim, ' ')\r\n}\r\n\r\nexport function rotateFigure<T extends SVGElement | ReadonlyArray<SVGElement>>({ draw, ...args }: RotateFigureArgs<T>) {\r\n const { x, y, size, rotation = 0 } = args\r\n const cx = x + size / 2\r\n const cy = y + size / 2\r\n\r\n const element = draw(args)\r\n if (rotation) (Array.isArray(element) ? element : [element])\r\n .forEach(el => el.setAttribute('transform', `rotate(${numToAttr((180 * rotation) / Math.PI)},${cx},${cy})`))\r\n return element\r\n}\r\n\r\nexport function scalePath(path: Array<string | number>, { x, y, size }: {\r\n x: number\r\n y: number\r\n size: number\r\n}) {\r\n let move = false\r\n let i = 0\r\n return path\r\n .map((v) => {\r\n if (typeof v == 'string') {\r\n i = 0\r\n move = v.toUpperCase() == v\r\n return v\r\n }\r\n i++\r\n v = v * size\r\n if (move) {\r\n v += i % 2 == 1 ? x : y\r\n }\r\n return numToAttr(v)\r\n })\r\n .join(' ')\r\n}\r\n\r\nexport function extendSVG(svg: SVGSVGElement, padding: number) {\r\n padding = Math.max(padding, 0)\r\n svg.setAttribute('width', numToAttr(parseFloat(svg.getAttribute('width') || '0') + 2 * padding))\r\n svg.setAttribute('height', numToAttr(parseFloat(svg.getAttribute('height') || '0') + 2 * padding))\r\n const vb = (svg.getAttribute('viewBox') || '').split(' ').map((v, i) => parseFloat(v) + (i < 2 ? -1 : 2) * padding)\r\n svg.setAttribute('viewBox', vb.map(numToAttr).join(' '))\r\n if (vb.length < 4)\r\n return undefined\r\n return {\r\n left: vb[0],\r\n right: vb[2] + vb[0],\r\n top: vb[1],\r\n bottom: vb[3] + vb[1]\r\n }\r\n}\r\n"],"names":["rx","numToAttr","value","toFixed","replace","extendSVG","svg","padding","max","k","parseFloat","c","a","setAttribute","getAttribute","b","split","h","map","i","length","left","right","vb","top","bottom","e","d","f","size","rotation","isArray","draw","args","forEach","Math","PI","cy","element","scalePath","path","y","v","toUpperCase","reduce","trim","rotateFigure","svgPath"],"mappings":"AAEA,IAAAA,WAEMC,SAAUA,EAAUC,GACtB,MAAoB,iBAATA,EAA0BA,EAC9BA,EAAMC,QAAQ,GAAGC,QAAQJ,EAAI,GAFQ,YAoD1CK,EAAAA,GAAAA,EAAoBC,KACtBC,MAAeC,GAAAA,EAAID,qBACFE,EAAAC,WAAmBA,EAAAA,uBAA4B,KAA5B,EAAwCC,IAAlDC,EAAAC,aACtBA,SAAaJ,EAAAC,WAAoBA,EAAAA,aAAeI,WAAa,KAA5B,EAAyCH,IAAnD,IAAAI,GAC3BH,EAAAE,aAAYA,gBAAJE,MAAqCA,KAAAA,KAArCC,EAAgDC,IAAER,WAASA,IAAAA,EAAA,GAAT,EAA2BS,GAAAR,GACzD,GADyDC,EAA3BC,uBACzCE,EAAAG,IAAjBT,GAA+BS,KAAH,QAA5BH,SACOK,GAAAA,MAAP,CAEAC,KAAAN,EACIM,GAAAA,MADGN,EAEHO,GAAAA,EAAOC,GAAAC,IAAWT,EAFf,GAGHS,OACAC,EAAAA,GAAAA,EAAQF,GAAA,qCA/C+DN,OAAAS,WAC3EC,EAAM,GAANhB,EAASiB,EAATb,EAAYW,EAAA,EAAAG,EAAMZ,EAAAS,EAAA,EAMyDI,OANzDlB,EAAAA,EAAAD,GAAlBgB,UAAAI,WAIaC,EAAGC,CAAHrB,IACbsB,QAAqBH,kBAChBG,YAAiBrB,UAAAA,EAAAA,IAAac,EAAAQ,KAAAC,mBAAyDA,CAAAA,CAA5C,SAAyDC,EACzGzB,GAAO0B,EAR0G3B,mBAW/G4B,SAAoBC,OAAmC5B,EAAA6B,IAAGb,oBAKjDA,GAGDc,EAAD,EACDhB,EAAAE,EAAIe,eAAYf,EAAhBA,IAGID,IAAAC,GAAOc,EAAAA,IADEC,GAAAA,EAAAA,GAAAA,EAAAA,EAAF5B,GAGXN,YAEA,IACa,oBAxCF,OACnBG,EAAAgC,OACKA,UAAWF,IAAJf,EAAY,GAGhB,OAFAD,IAAiBC,EACbR,EAAJO,EAAA,IACI,iBAAAC,QAAJA,IACA,GAAAZ,wBAEH8B,QACAzC,eAAQ,IAAA,QAT0DC,eAAAI,eAAAqC,kBAAAP,eAAAQ"}
@@ -5,12 +5,6 @@ declare enum TextPosition {
5
5
  left = "left",
6
6
  right = "right"
7
7
  }
8
- export interface BorderConfig {
9
- size: number;
10
- color: string;
11
- dasharray?: string;
12
- margin?: number;
13
- }
14
8
  export interface TextConfig {
15
9
  font?: string;
16
10
  color?: string;
@@ -18,21 +12,26 @@ export interface TextConfig {
18
12
  fontWeight?: 'normal' | 'bold' | 'bolder' | 'lighter' | number;
19
13
  fontStyle?: 'normal' | 'italic' | 'oblique';
20
14
  }
21
- export interface BorderPluginOptions extends BorderConfig {
15
+ export interface BorderPluginOptions {
22
16
  /** Border roundnes, from 0 (square) to 1 (circle) */
23
17
  round?: number;
24
- text: TextConfig & {
18
+ size: number;
19
+ color: string;
20
+ dasharray?: string;
21
+ margin?: number;
22
+ text?: TextConfig & {
25
23
  [key in TextPosition]?: TextConfig & {
26
24
  content: string;
27
25
  };
28
26
  };
29
- innerBorder?: BorderConfig;
30
- outerBorder?: BorderConfig;
31
27
  }
32
28
  export declare class BorderPlugin implements Plugin {
33
29
  private readonly pluginOptions;
34
- private readonly id;
35
- constructor(pluginOptions: BorderPluginOptions, id?: string);
30
+ /** @ignore Create unique id for SVG elements to prevent naming collisions; specify your own if neccesary e.g. for testing */
31
+ private readonly idSuffix;
32
+ constructor(pluginOptions: BorderPluginOptions,
33
+ /** @ignore Create unique id for SVG elements to prevent naming collisions; specify your own if neccesary e.g. for testing */
34
+ idSuffix?: string);
36
35
  postProcess(svg: SVGSVGElement, options: Options): void;
37
36
  }
38
37
  export {};