Skip to content

Commit

Permalink
fix border radius not respected for svg output (#62)
Browse files Browse the repository at this point in the history
  • Loading branch information
lyqht authored Oct 23, 2024
1 parent 9618489 commit fbd2372
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 19 deletions.
27 changes: 22 additions & 5 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
downloadPngElement,
downloadSvgElement,
getPngElement,
getSvgElement,
getSvgString,
IS_COPY_IMAGE_TO_CLIPBOARD_SUPPORTED
} from '@/utils/convertToImage'
Expand Down Expand Up @@ -228,7 +227,12 @@ function downloadQRImageAsPng() {
if (exportMode.value === ExportMode.Single) {
const qrCode = document.querySelector('#qr-code-container')
if (qrCode) {
downloadPngElement(qrCode as HTMLElement, 'qr-code.png', options.value)
downloadPngElement(
qrCode as HTMLElement,
'qr-code.png',
options.value,
styledBorderRadiusFormatted.value
)
}
} else {
generateBatchQRCodes('png')
Expand All @@ -239,7 +243,12 @@ function downloadQRImageAsSvg() {
if (exportMode.value === ExportMode.Single) {
const qrCode = document.querySelector('#qr-code-container')
if (qrCode) {
downloadSvgElement(qrCode as HTMLElement, 'qr-code.svg', options.value)
downloadSvgElement(
qrCode as HTMLElement,
'qr-code.svg',
options.value,
styledBorderRadiusFormatted.value
)
}
} else {
generateBatchQRCodes('svg')
Expand Down Expand Up @@ -494,9 +503,17 @@ async function generateBatchQRCodes(format: 'png' | 'svg') {
await sleep(1000)
let dataUrl: string = ''
if (format === 'png') {
dataUrl = await getPngElement(qrCode as HTMLElement, options.value)
dataUrl = await getPngElement(
qrCode as HTMLElement,
options.value,
styledBorderRadiusFormatted.value
)
} else {
dataUrl = await getSvgString(qrCode as HTMLElement, options.value)
dataUrl = await getSvgString(
qrCode as HTMLElement,
options.value,
styledBorderRadiusFormatted.value
)
}
createZipFile(zip, dataUrl, index, format)
numQrCodesCreated++
Expand Down
54 changes: 40 additions & 14 deletions src/utils/convertToImage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@ const defaultOptions: Options = {
height: 400
}

const getFormattedOptions = (element: HTMLElement, options: Options): Options => {
const getFormattedOptions = (
element: HTMLElement,
options: Options,
borderRadius?: string
): Options => {
if (options.width && options.height) {
const scale = getResizeScaleToFit(element, options.width, options.height)
return {
style: { scale, transformOrigin: 'left top', borderRadius: '48px' },
style: { scale, transformOrigin: 'left top', borderRadius: borderRadius ?? '48px' },
quality: 100,
...options
}
Expand All @@ -32,9 +36,13 @@ const getResizeScaleToFit = (child: HTMLElement, width: number, height: number):
export const IS_COPY_IMAGE_TO_CLIPBOARD_SUPPORTED =
navigator.clipboard && navigator.clipboard.write != undefined

export async function copyImageToClipboard(element: HTMLElement, options: Options) {
export async function copyImageToClipboard(
element: HTMLElement,
options: Options,
borderRadius?: string
) {
if (IS_COPY_IMAGE_TO_CLIPBOARD_SUPPORTED) {
const formattedOptions = getFormattedOptions(element, options)
const formattedOptions = getFormattedOptions(element, options, borderRadius)
console.debug('Converting to blob')
domtoimage.toBlob(element, formattedOptions).then((blob: Blob) => {
const item = new ClipboardItem({ [blob.type]: blob })
Expand All @@ -50,13 +58,18 @@ export async function copyImageToClipboard(element: HTMLElement, options: Option
}
}

export function getPngElement(element: HTMLElement, options: Options) {
const formattedOptions = getFormattedOptions(element, options)
export function getPngElement(element: HTMLElement, options: Options, borderRadius?: string) {
const formattedOptions = getFormattedOptions(element, options, borderRadius)
return domtoimage.toPng(element, formattedOptions)
}

export function downloadPngElement(element: HTMLElement, filename: string, options: Options) {
getPngElement(element, options)
export function downloadPngElement(
element: HTMLElement,
filename: string,
options: Options,
borderRadius?: string
) {
getPngElement(element, options, borderRadius)
.then((dataUrl: string) => {
const link = document.createElement('a')
link.href = dataUrl
Expand All @@ -79,23 +92,36 @@ function applySvgOptions(svgDocument: Document, options: Options) {
}
}

export async function getSvgString(element: HTMLElement, options: Options): Promise<string> {
const formattedOptions = getFormattedOptions(element, options)
export async function getSvgString(
element: HTMLElement,
options: Options,
borderRadius?: string
): Promise<string> {
const formattedOptions = getFormattedOptions(element, options, borderRadius)
const svgDocument = elementToSVG(element)
await inlineResources(svgDocument.documentElement)
applySvgOptions(svgDocument, formattedOptions)
return new XMLSerializer().serializeToString(svgDocument)
}

export async function getSvgElement(element: HTMLElement, options: Options): Promise<string> {
const svgString = await getSvgString(element, options)
export async function getSvgElement(
element: HTMLElement,
options: Options,
borderRadius?: string
): Promise<string> {
const svgString = await getSvgString(element, options, borderRadius)

// Convert SVG string to data URL
return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgString)}`
}

export function downloadSvgElement(element: HTMLElement, filename: string, options: Options) {
getSvgElement(element, options)
export function downloadSvgElement(
element: HTMLElement,
filename: string,
options: Options,
borderRadius?: string
) {
getSvgElement(element, options, borderRadius)
.then((dataUrl: string) => {
const link = document.createElement('a')
link.href = dataUrl
Expand Down

0 comments on commit fbd2372

Please sign in to comment.