Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix border radius not respected for svg output #62

Merged
merged 1 commit into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading