56 lines
1.1 KiB
Vue
56 lines
1.1 KiB
Vue
<script setup lang="ts">
|
|
import { computed } from 'vue'
|
|
import { createQrCodeMatrix } from '@/utils/qrcode'
|
|
|
|
const props = withDefaults(defineProps<{
|
|
value: string
|
|
size?: number
|
|
}>(), {
|
|
size: 180,
|
|
})
|
|
|
|
const quietZone = 4
|
|
|
|
const qrCode = computed(() => createQrCodeMatrix(props.value))
|
|
const viewBoxSize = computed(() => qrCode.value.size + quietZone * 2)
|
|
|
|
const darkModules = computed(() => {
|
|
return qrCode.value.modules.flatMap((row, y) => {
|
|
return row
|
|
.map((dark, x) => ({ dark, x: x + quietZone, y: y + quietZone }))
|
|
.filter(module => module.dark)
|
|
})
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<svg
|
|
aria-label="報到 QR Code"
|
|
class="qr-code"
|
|
:height="size"
|
|
role="img"
|
|
shape-rendering="crispEdges"
|
|
:viewBox="`0 0 ${viewBoxSize} ${viewBoxSize}`"
|
|
:width="size"
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
>
|
|
<rect fill="#ffffff" height="100%" width="100%" />
|
|
|
|
<rect
|
|
v-for="module in darkModules"
|
|
:key="`${module.x}-${module.y}`"
|
|
fill="#000000"
|
|
height="1"
|
|
width="1"
|
|
:x="module.x"
|
|
:y="module.y"
|
|
/>
|
|
</svg>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.qr-code {
|
|
display: block;
|
|
}
|
|
</style>
|