@liquid-js/qr-code-styling 5.1.0 → 5.2.0
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 +12 -1
- package/lib/border-plugin.js.map +1 -1
- package/lib/core/qr-svg.d.ts +0 -3
- package/lib/font-faces-plugin.js +2 -0
- package/lib/font-faces-plugin.js.map +1 -0
- package/lib/plugins/border.d.ts +5 -1
- package/lib/plugins/font-faces.d.ts +19 -0
- package/lib/qr-code-styling-node.js +28 -35
- package/lib/qr-code-styling-node.js.map +1 -1
- package/lib/qr-code-styling.js +1 -1
- package/lib/qr-code-styling.js.map +1 -1
- package/lib/utils/options.d.ts +3 -3
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -84,6 +84,7 @@ While the old API only supports a single extension, it is now possible to apply
|
|
|
84
84
|
|
|
85
85
|
```ts
|
|
86
86
|
import BorderPlugin from '@liquid-js/qr-code-styling/border-plugin'
|
|
87
|
+
import FontFacesPlugin from '@liquid-js/qr-code-styling/font-faces-plugin'
|
|
87
88
|
|
|
88
89
|
const qrCode = new QRCodeStyling({
|
|
89
90
|
plugins: [
|
|
@@ -107,7 +108,17 @@ const qrCode = new QRCodeStyling({
|
|
|
107
108
|
content: 'QR code'.toUpperCase()
|
|
108
109
|
}
|
|
109
110
|
}
|
|
110
|
-
})
|
|
111
|
+
}),
|
|
112
|
+
/**
|
|
113
|
+
* Embed fonts used with BorderPlugin
|
|
114
|
+
*
|
|
115
|
+
* Not needed when using standard or local fonts, but recommended for portability and consistency; use
|
|
116
|
+
* subsetting if possible to reduce the generated file size.
|
|
117
|
+
*/
|
|
118
|
+
new FontFacesPlugin([{
|
|
119
|
+
font: 'sans-serif',
|
|
120
|
+
src: `url(data:font/otf;base64,d09GMgABAA...)`
|
|
121
|
+
}])
|
|
111
122
|
]
|
|
112
123
|
// ...other options
|
|
113
124
|
})
|
package/lib/border-plugin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"border-plugin.js","sources":["../src/plugins/border.ts"],"sourcesContent":["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' | 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 /**\r\n * If true, all dimensions are proportional to the code size,\r\n * i.e. `size: 0.1` means the border thickness is 1/10 of the QR code size\r\n *\r\n * This is useful to keep the border visually consistent regardless of the amount of data\r\n *\r\n * Note: if using dasharray, use percentage values to maintain consistency\r\n */\r\n proportional?: boolean\r\n text?: TextConfig & {\r\n [key in TextPosition]?: TextConfig & {\r\n content: string\r\n }\r\n }\r\n /** A string of embedded CSS @font-face rules */\r\n fontFaces?: string\r\n}\r\n\r\nexport default 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 sizeFactor = this.pluginOptions.proportional ? options.size : 1\r\n\r\n const margin = (this.pluginOptions.margin || 0) * sizeFactor\r\n let thickness = (this.pluginOptions.size) * sizeFactor\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 = options.size / 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) * sizeFactor\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 if (this.pluginOptions.fontFaces) {\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 style = document.createElementNS('http://www.w3.org/2000/svg', 'style')\r\n style.textContent = this.pluginOptions.fontFaces\r\n defs.appendChild(style)\r\n }\r\n }\r\n}\r\n"],"names":["extendSVG","numToAttr","TextPosition","g","v","top","bottom","left","right","pluginOptions","idSuffix","constructor","Math","random","toFixed","substring","this","postProcess","svg","options","document","sizeFactor","proportional","size","thickness","drawArea","margin","abs","cx","cy","round","min","lineSize","pathR","r","pathL","createElementNS","setAttribute","borderEl","color","dasharray","appendChild","forEach","postion","text","textCfg","config","defs","Array","from","childNodes","find","tagName","toUpperCase","element","svgPath","id","span","font","fontWeight","fontStyle","textContent","content","textPath","setAttributeNS","fontFaces","style"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"border-plugin.js","sources":["../src/plugins/border.ts"],"sourcesContent":["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' | 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 /**\r\n * If true, all dimensions are proportional to the code size,\r\n * i.e. `size: 0.1` means the border thickness is 1/10 of the QR code size\r\n *\r\n * This is useful to keep the border visually consistent regardless of the amount of data\r\n *\r\n * Note: if using dasharray, use percentage values to maintain consistency\r\n */\r\n proportional?: boolean\r\n text?: TextConfig & {\r\n [key in TextPosition]?: TextConfig & {\r\n content: string\r\n }\r\n }\r\n /**\r\n * A string of embedded CSS @font-face rules\r\n *\r\n * @deprecated Use @liquid-js/qr-code-styling/font-faces-plugin\r\n */\r\n fontFaces?: string\r\n}\r\n\r\nexport default 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 sizeFactor = this.pluginOptions.proportional ? options.size : 1\r\n\r\n const margin = (this.pluginOptions.margin || 0) * sizeFactor\r\n let thickness = (this.pluginOptions.size) * sizeFactor\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 = options.size / 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) * sizeFactor\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 // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n if (this.pluginOptions.fontFaces) {\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 style = document.createElementNS('http://www.w3.org/2000/svg', 'style')\r\n // eslint-disable-next-line @typescript-eslint/no-deprecated\r\n style.textContent = this.pluginOptions.fontFaces\r\n defs.appendChild(style)\r\n }\r\n }\r\n}\r\n"],"names":["extendSVG","numToAttr","TextPosition","g","v","top","bottom","left","right","pluginOptions","idSuffix","constructor","Math","random","toFixed","substring","this","postProcess","svg","options","document","sizeFactor","proportional","size","thickness","drawArea","margin","abs","cx","cy","round","min","lineSize","pathR","r","pathL","createElementNS","setAttribute","borderEl","color","dasharray","appendChild","forEach","postion","text","textCfg","config","defs","Array","from","childNodes","find","tagName","toUpperCase","element","svgPath","id","span","font","fontWeight","fontStyle","textContent","content","textPath","setAttributeNS","fontFaces","style"],"mappings":"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"}
|
package/lib/core/qr-svg.d.ts
CHANGED
|
@@ -7,11 +7,8 @@ export declare class QRSVG {
|
|
|
7
7
|
get element(): SVGSVGElement;
|
|
8
8
|
private defs;
|
|
9
9
|
private backgroundMask?;
|
|
10
|
-
private backgroundMaskGroup?;
|
|
11
10
|
private dotsMask?;
|
|
12
|
-
private dotsMaskGroup?;
|
|
13
11
|
private lightDotsMask?;
|
|
14
|
-
private lightDotsMaskGroup?;
|
|
15
12
|
private qr?;
|
|
16
13
|
private document;
|
|
17
14
|
private imageTools;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export default class{fontFaces;constructor(t){this.fontFaces=t.map(t=>"string"==typeof t?t:`@font-face { font-family: ${JSON.stringify(t.font)}; src: ${t.src}; ${t.fontStyle?`font-style: ${t.fontStyle};`:""} ${t.fontWeight?`font-weight: ${t.fontWeight};`:""} }`).join("\n")}postProcess(t,e){let o=e.document;(e=Array.from(t.childNodes).find(t=>"DEFS"==t.tagName.toUpperCase()))||(e=o.createElementNS("http://www.w3.org/2000/svg","defs"),t.appendChild(e)),(t=o.createElementNS("http://www.w3.org/2000/svg","style")).textContent=this.fontFaces,e.appendChild(t)}}
|
|
2
|
+
//# sourceMappingURL=font-faces-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"font-faces-plugin.js","sources":["../src/plugins/font-faces.ts"],"sourcesContent":["import { Options, Plugin } from '../utils/options.js'\r\nimport { TextConfig } from './border.js'\r\n\r\nexport interface FontFace extends Pick<TextConfig, 'font' | 'fontWeight' | 'fontStyle'> {\r\n /**\r\n * Base64 encoded font, e.g. `url(data:font/otf;base64,...)`\r\n */\r\n src: string\r\n}\r\n\r\n/**\r\n * Embed font faces into the generated SVG\r\n *\r\n * Use as the last plugin when using BorderPlugin({ text: { ... } })\r\n * or other plugins that insert text.\r\n */\r\nexport default class FontFacesPlugin implements Plugin {\r\n private readonly fontFaces: string\r\n constructor(fontFaces: Array<FontFace | string>) {\r\n this.fontFaces = fontFaces.map(v => {\r\n if (typeof v == 'string')\r\n return v\r\n return `@font-face { font-family: ${JSON.stringify(v.font)}; src: ${v.src}; ${v.fontStyle ? `font-style: ${v.fontStyle};` : ''} ${v.fontWeight ? `font-weight: ${v.fontWeight};` : ''} }`\r\n }).join('\\n')\r\n }\r\n\r\n postProcess(svg: SVGSVGElement, options: Options) {\r\n const document = options.document\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 style = document.createElementNS('http://www.w3.org/2000/svg', 'style')\r\n style.textContent = this.fontFaces\r\n defs.appendChild(style)\r\n }\r\n}\r\n"],"names":["fontFaces","constructor","this","map","v","JSON","stringify","font","src","fontStyle","fontWeight","join","postProcess","svg","options","document","defs","Array","from","childNodes","find","tagName","toUpperCase","createElementNS","appendChild","style","textContent"],"mappings":"eAgBc,MACOA,UACjBC,WAAAA,CAAYD,GACRE,KAAKF,UAAYA,EAAUG,IAAIC,GACX,iBAALA,EACAA,EACJ,6BAA6BC,KAAKC,UAAUF,EAAEG,eAAeH,EAAEI,QAAQJ,EAAEK,UAAY,eAAeL,EAAEK,aAAe,MAAML,EAAEM,WAAa,gBAAgBN,EAAEM,cAAgB,QACpLC,KAAK,KALmC,CAQ/CC,WAAAA,CAAYC,EAAoBC,GAC5B,IAAAC,EAAcD,EAAGC,UACbC,EAAOC,MAAMC,KAAKL,EAAIM,YAAYC,KAAKhB,GAAiD,QAA3CA,EAAkBiB,QAAQC,kBAEvEN,EAAOD,EAASQ,gBAAgB,6BAA8B,QAC9DV,EAAIW,YAAYR,KAEpBS,EAAWV,EAAGQ,6CAAqD,UAC7DG,YAAcxB,KAAKF,UACzBgB,EAAKQ,YAAYC,EAT2B"}
|
package/lib/plugins/border.d.ts
CHANGED
|
@@ -33,7 +33,11 @@ export interface BorderPluginOptions {
|
|
|
33
33
|
content: string;
|
|
34
34
|
};
|
|
35
35
|
};
|
|
36
|
-
/**
|
|
36
|
+
/**
|
|
37
|
+
* A string of embedded CSS @font-face rules
|
|
38
|
+
*
|
|
39
|
+
* @deprecated Use @liquid-js/qr-code-styling/font-faces-plugin
|
|
40
|
+
*/
|
|
37
41
|
fontFaces?: string;
|
|
38
42
|
}
|
|
39
43
|
export default class BorderPlugin implements Plugin {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Options, Plugin } from '../utils/options.js';
|
|
2
|
+
import { TextConfig } from './border.js';
|
|
3
|
+
export interface FontFace extends Pick<TextConfig, 'font' | 'fontWeight' | 'fontStyle'> {
|
|
4
|
+
/**
|
|
5
|
+
* Base64 encoded font, e.g. `url(data:font/otf;base64,...)`
|
|
6
|
+
*/
|
|
7
|
+
src: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Embed font faces into the generated SVG
|
|
11
|
+
*
|
|
12
|
+
* Use as the last plugin when using BorderPlugin({ text: { ... } })
|
|
13
|
+
* or other plugins that insert text.
|
|
14
|
+
*/
|
|
15
|
+
export default class FontFacesPlugin implements Plugin {
|
|
16
|
+
private readonly fontFaces;
|
|
17
|
+
constructor(fontFaces: Array<FontFace | string>);
|
|
18
|
+
postProcess(svg: SVGSVGElement, options: Options): void;
|
|
19
|
+
}
|
|
@@ -684,11 +684,8 @@ class QRSVG {
|
|
|
684
684
|
}
|
|
685
685
|
defs;
|
|
686
686
|
backgroundMask;
|
|
687
|
-
backgroundMaskGroup;
|
|
688
687
|
dotsMask;
|
|
689
|
-
dotsMaskGroup;
|
|
690
688
|
lightDotsMask;
|
|
691
|
-
lightDotsMaskGroup;
|
|
692
689
|
qr;
|
|
693
690
|
document;
|
|
694
691
|
imageTools;
|
|
@@ -799,27 +796,26 @@ class QRSVG {
|
|
|
799
796
|
name: "background-color"
|
|
800
797
|
});
|
|
801
798
|
let element = this.document.createElementNS("http://www.w3.org/2000/svg", "rect");
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
element.setAttribute("
|
|
805
|
-
element.setAttribute("
|
|
806
|
-
this.
|
|
799
|
+
this.backgroundMask = this.createMask("mask-background-color"), this.defs.appendChild(this.backgroundMask),
|
|
800
|
+
element.setAttribute("x", numToAttr(0)), element.setAttribute("y", numToAttr(0)),
|
|
801
|
+
element.setAttribute("width", numToAttr(options.size)), element.setAttribute("height", numToAttr(options.size)),
|
|
802
|
+
element.setAttribute("rx", numToAttr(options.size / 2 * (options.backgroundOptions.round || 0))),
|
|
803
|
+
this.backgroundMask.appendChild(element);
|
|
807
804
|
}
|
|
808
805
|
}
|
|
809
806
|
drawDots(filter) {
|
|
810
807
|
if (!this.qr) throw new Error("QR code is not defined");
|
|
811
808
|
let options = this.options, count = this.qr.getModuleCount();
|
|
812
809
|
if (count > options.size) throw new Error("The canvas is too small");
|
|
813
|
-
let dotSize = this.options.dotsOptions.size;
|
|
814
|
-
options.imageOptions.mode == ImageMode.background && (
|
|
810
|
+
let dotSize = this.options.dotsOptions.size, size = options.size;
|
|
811
|
+
options.imageOptions.mode == ImageMode.background && (size -= 2 * dotSize * (options.imageOptions.margin || 0));
|
|
815
812
|
let beginning = Math.floor((options.size - count * dotSize) / 2), draw = getQrDotFigure(options.dotsOptions.type, options.plugins);
|
|
816
|
-
|
|
817
|
-
options.imageOptions.mode == ImageMode.background && (
|
|
813
|
+
this.dotsMask = this.createMask("mask-dot-color"), this.defs.appendChild(this.dotsMask),
|
|
814
|
+
options.imageOptions.mode == ImageMode.background && (this.lightDotsMask = this.createMask("mask-light-dot-color"),
|
|
818
815
|
this.defs.appendChild(this.lightDotsMask));
|
|
819
816
|
let margin = 0, additionalDots = 0, fakeCount = count;
|
|
820
817
|
options.shape === ShapeType.circle ? (margin = this.options.backgroundOptions && this.options.backgroundOptions.margin || 0,
|
|
821
|
-
additionalDots = Math.floor((
|
|
822
|
-
fakeCount = count + 2 * additionalDots) : options.imageOptions.mode == ImageMode.background && (additionalDots = 1,
|
|
818
|
+
additionalDots = Math.floor((size / dotSize - count - 2 * margin) / 2), fakeCount = count + 2 * additionalDots) : options.imageOptions.mode == ImageMode.background && (additionalDots = 1,
|
|
823
819
|
fakeCount = count + 2 * additionalDots);
|
|
824
820
|
let fakeBeginning = beginning - additionalDots * dotSize, colorCount = count + 2 * additionalDots;
|
|
825
821
|
this._fakeMatrix = new Array(fakeCount);
|
|
@@ -841,14 +837,14 @@ class QRSVG {
|
|
|
841
837
|
for (let j = 0; j < fakeCount; j++) {
|
|
842
838
|
let jAlign = alignment.find(v => j - additionalDots > v - 3 && j - additionalDots < v + 3);
|
|
843
839
|
null != this._fakeMatrix[i][j] && (this.lightDotsMask && (draw = iAlign && jAlign && (iAlign != alignment[0] && jAlign != alignment[0] || jAlign != alignment[0] && jAlign != alignment[alignment.length - 1] || iAlign != alignment[0] && iAlign != alignment[alignment.length - 1]) ? getQrDotFigure(DotType.square) : getQrDotFigure(DotType.tinySquare)),
|
|
844
|
-
this._fakeMatrix[i][j] ? this.
|
|
840
|
+
this._fakeMatrix[i][j] ? this.dotsMask && this.dotsMask.appendChild(draw({
|
|
845
841
|
x: fakeBeginning + i * dotSize,
|
|
846
842
|
y: fakeBeginning + j * dotSize,
|
|
847
843
|
size: dotSize,
|
|
848
844
|
document: this.options.document,
|
|
849
845
|
getNeighbor: (xOffset, yOffset) => !0 === this._fakeMatrix[i + xOffset]?.[j + yOffset],
|
|
850
846
|
getPRandom: getRng(this._fakeMatrix, i, j)
|
|
851
|
-
})) : this.lightDotsMask && this.
|
|
847
|
+
})) : this.lightDotsMask && this.lightDotsMask && this.lightDotsMask.appendChild(draw({
|
|
852
848
|
x: fakeBeginning + i * dotSize,
|
|
853
849
|
y: fakeBeginning + j * dotSize,
|
|
854
850
|
size: dotSize,
|
|
@@ -884,9 +880,9 @@ class QRSVG {
|
|
|
884
880
|
if (!element) throw new Error("Element code is not defined");
|
|
885
881
|
let count = this.qr.getModuleCount(), dotSize = this.options.dotsOptions.size, cornersSquareSize = 7 * dotSize, cornersDotSize = 3 * dotSize, beginning = Math.floor((options.size - count * dotSize) / 2);
|
|
886
882
|
[ [ 0, 0, 0 ], [ 1, 0, Math.PI / 2 ], [ 0, 1, -Math.PI / 2 ] ].forEach(([column, row, rotation]) => {
|
|
887
|
-
let x = beginning + column * dotSize * (count - 7), y = beginning + row * dotSize * (count - 7), cornersSquareMask = this.dotsMask,
|
|
888
|
-
(options.cornersSquareOptions?.gradient || options.cornersSquareOptions?.color) && (
|
|
889
|
-
this.defs.appendChild(cornersSquareMask), cornersDotMask = cornersSquareMask,
|
|
883
|
+
let x = beginning + column * dotSize * (count - 7), y = beginning + row * dotSize * (count - 7), cornersSquareMask = this.dotsMask, cornersDotMask = this.dotsMask;
|
|
884
|
+
(options.cornersSquareOptions?.gradient || options.cornersSquareOptions?.color) && (cornersSquareMask = this.createMask(`mask-corners-square-color-${column}-${row}`),
|
|
885
|
+
this.defs.appendChild(cornersSquareMask), cornersDotMask = cornersSquareMask, cornersDotMask = cornersSquareMask,
|
|
890
886
|
this.createColor({
|
|
891
887
|
options: options.cornersSquareOptions?.gradient,
|
|
892
888
|
color: options.cornersSquareOptions?.color,
|
|
@@ -912,20 +908,20 @@ class QRSVG {
|
|
|
912
908
|
var plugins, type, val;
|
|
913
909
|
if (pluinCornerSquare) {
|
|
914
910
|
let [cornerElement, cornerFill] = pluinCornerSquare;
|
|
915
|
-
|
|
911
|
+
cornersSquareMask && cornersSquareMask.appendChild(cornerElement), this.lightDotsMask && this.lightDotsMask.appendChild(cornerFill);
|
|
916
912
|
} else if (val = options.cornersSquareOptions?.type, val && cornerSquareTypes.has(val)) {
|
|
917
913
|
let draw = (type = options.cornersSquareOptions.type, qrCornerSquareFigures[type] || qrCornerSquareFigures[CornerSquareType.square]), [cornerElement, cornerFill] = draw(squareArgs);
|
|
918
|
-
|
|
914
|
+
cornersSquareMask && cornersSquareMask.appendChild(cornerElement), this.lightDotsMask && this.lightDotsMask.appendChild(cornerFill);
|
|
919
915
|
} else {
|
|
920
916
|
let draw = getQrDotFigure(options.cornersSquareOptions?.type || options.dotsOptions.type, options.plugins);
|
|
921
|
-
for (let i = 0; i < squareMask.length; i++) for (let j = 0; j < squareMask[i].length; j++) squareMask[i]?.[j] ?
|
|
917
|
+
for (let i = 0; i < squareMask.length; i++) for (let j = 0; j < squareMask[i].length; j++) squareMask[i]?.[j] ? cornersSquareMask && cornersSquareMask.appendChild(draw({
|
|
922
918
|
x: x + i * dotSize,
|
|
923
919
|
y: y + j * dotSize,
|
|
924
920
|
size: dotSize,
|
|
925
921
|
document: this.options.document,
|
|
926
922
|
getNeighbor: (xOffset, yOffset) => !!squareMask[i + xOffset]?.[j + yOffset],
|
|
927
923
|
getPRandom: getRng(this._fakeMatrix, x / dotSize + i, y / dotSize + j, !1)
|
|
928
|
-
})) : this.lightDotsMask && !dotMask[i]?.[j] && this.
|
|
924
|
+
})) : this.lightDotsMask && !dotMask[i]?.[j] && this.lightDotsMask && this.lightDotsMask.appendChild(draw({
|
|
929
925
|
x: x + i * dotSize,
|
|
930
926
|
y: y + j * dotSize,
|
|
931
927
|
size: dotSize,
|
|
@@ -933,7 +929,7 @@ class QRSVG {
|
|
|
933
929
|
getNeighbor: (xOffset, yOffset) => !squareMask[i + xOffset]?.[j + yOffset] && !dotMask[i + xOffset]?.[j + yOffset],
|
|
934
930
|
getPRandom: getRng(this._fakeMatrix, x / dotSize + i, y / dotSize + j, !1)
|
|
935
931
|
}));
|
|
936
|
-
if (this.lightDotsMask) for (let i = -1; i < 8; i++) for (let j = -1; j < 8; j++) -1 != i && 7 != i && -1 != j && 7 != j || this.
|
|
932
|
+
if (this.lightDotsMask) for (let i = -1; i < 8; i++) for (let j = -1; j < 8; j++) -1 != i && 7 != i && -1 != j && 7 != j || this.lightDotsMask && this.lightDotsMask.appendChild(draw({
|
|
937
933
|
x: x + i * dotSize,
|
|
938
934
|
y: y + j * dotSize,
|
|
939
935
|
size: dotSize,
|
|
@@ -945,7 +941,7 @@ class QRSVG {
|
|
|
945
941
|
getPRandom: getRng(this._fakeMatrix, x / dotSize + i, y / dotSize + j, !1)
|
|
946
942
|
}));
|
|
947
943
|
}
|
|
948
|
-
(options.cornersDotOptions?.gradient || options.cornersDotOptions?.color) && (
|
|
944
|
+
(options.cornersDotOptions?.gradient || options.cornersDotOptions?.color) && (cornersDotMask = this.createMask(`mask-corners-dot-color-${column}-${row}`),
|
|
949
945
|
this.defs.appendChild(cornersDotMask), this.createColor({
|
|
950
946
|
options: options.cornersDotOptions?.gradient,
|
|
951
947
|
color: options.cornersDotOptions?.color,
|
|
@@ -970,16 +966,16 @@ class QRSVG {
|
|
|
970
966
|
}
|
|
971
967
|
};
|
|
972
968
|
}(options.plugins)(dotArgs) : void 0;
|
|
973
|
-
if (pluinCornerDot)
|
|
969
|
+
if (pluinCornerDot) cornersDotMask && cornersDotMask.appendChild(pluinCornerDot); else if (function(val) {
|
|
974
970
|
return !(!val || !cornerDotTypes.has(val));
|
|
975
971
|
}(options.cornersDotOptions?.type)) {
|
|
976
972
|
let draw = function(type) {
|
|
977
973
|
return qrCornerDotFigures[type] || qrCornerDotFigures[CornerDotType.square];
|
|
978
974
|
}(options.cornersDotOptions.type);
|
|
979
|
-
|
|
975
|
+
cornersDotMask && cornersDotMask.appendChild(draw(dotArgs));
|
|
980
976
|
} else {
|
|
981
977
|
let draw = getQrDotFigure(options.cornersDotOptions?.type || options.dotsOptions.type, options.plugins);
|
|
982
|
-
for (let i = 0; i < dotMask.length; i++) for (let j = 0; j < dotMask[i].length; j++) dotMask[i]?.[j] &&
|
|
978
|
+
for (let i = 0; i < dotMask.length; i++) for (let j = 0; j < dotMask[i].length; j++) dotMask[i]?.[j] && cornersDotMask && cornersDotMask.appendChild(draw({
|
|
983
979
|
x: x + i * dotSize,
|
|
984
980
|
y: y + j * dotSize,
|
|
985
981
|
size: dotSize,
|
|
@@ -1014,7 +1010,7 @@ class QRSVG {
|
|
|
1014
1010
|
let rect = this.document.createElementNS("http://www.w3.org/2000/svg", "rect");
|
|
1015
1011
|
if (rect.setAttribute("x", numToAttr(x)), rect.setAttribute("y", numToAttr(y)),
|
|
1016
1012
|
rect.setAttribute("height", numToAttr(height)), rect.setAttribute("width", numToAttr(width)),
|
|
1017
|
-
rect.setAttribute("
|
|
1013
|
+
rect.setAttribute("clip-path", `url(#mask-${name})`), options) {
|
|
1018
1014
|
let gradient;
|
|
1019
1015
|
if (options.type === GradientType.radial) gradient = this.document.createElementNS("http://www.w3.org/2000/svg", "radialGradient"),
|
|
1020
1016
|
gradient.setAttribute("id", name), gradient.setAttribute("gradientUnits", "userSpaceOnUse"),
|
|
@@ -1046,12 +1042,9 @@ class QRSVG {
|
|
|
1046
1042
|
this._element.appendChild(rect);
|
|
1047
1043
|
}
|
|
1048
1044
|
createMask(id) {
|
|
1049
|
-
let
|
|
1050
|
-
mask.setAttribute("id", id), mask.setAttribute("
|
|
1051
|
-
mask
|
|
1052
|
-
mask.setAttribute("height", numToAttr(options.size));
|
|
1053
|
-
let group = this.document.createElementNS("http://www.w3.org/2000/svg", "g");
|
|
1054
|
-
return group.setAttribute("fill", "#fff"), mask.appendChild(group), [ mask, group ];
|
|
1045
|
+
let mask = this.document.createElementNS("http://www.w3.org/2000/svg", "clipPath");
|
|
1046
|
+
return mask.setAttribute("id", id), mask.setAttribute("clipPathUnits", "userSpaceOnUse"),
|
|
1047
|
+
mask;
|
|
1055
1048
|
}
|
|
1056
1049
|
}
|
|
1057
1050
|
|