2024-11-12 21:27:19 +00:00
|
|
|
<script lang="ts">
|
|
|
|
|
import QRCode from "qrcode"
|
|
|
|
|
import Button from "@lib/components/Button.svelte"
|
2026-06-08 21:14:40 +00:00
|
|
|
import {clip} from "@app/toast"
|
2024-11-12 21:27:19 +00:00
|
|
|
|
2025-05-07 22:04:35 +00:00
|
|
|
const {code, ...props} = $props()
|
2024-11-12 21:27:19 +00:00
|
|
|
|
2026-07-08 22:03:08 +00:00
|
|
|
let canvas: HTMLCanvasElement | undefined = $state()
|
2025-02-04 00:37:14 +00:00
|
|
|
let wrapper: Element | undefined = $state()
|
|
|
|
|
let scale = $state(0.1)
|
|
|
|
|
let height = $state(0)
|
2024-11-12 21:27:19 +00:00
|
|
|
|
2025-01-31 22:14:42 +00:00
|
|
|
const copy = () => clip(code)
|
|
|
|
|
|
2026-07-08 22:03:08 +00:00
|
|
|
$effect(() => {
|
2026-07-08 22:03:08 +00:00
|
|
|
if (canvas && wrapper && code) {
|
2025-02-04 00:37:14 +00:00
|
|
|
QRCode.toCanvas(canvas, code)
|
2026-07-08 22:03:08 +00:00
|
|
|
}
|
|
|
|
|
})
|
2024-11-12 21:27:19 +00:00
|
|
|
|
2026-07-08 22:03:08 +00:00
|
|
|
$effect(() => {
|
|
|
|
|
// Draw first so canvas.width/height reflect the current code, then fit the
|
|
|
|
|
// intrinsic canvas size to the wrapper. Measure the intrinsic size (not
|
|
|
|
|
// getBoundingClientRect, which includes the transform below) so this stays
|
|
|
|
|
// idempotent — otherwise scale feeds back into its own measurement and loops.
|
|
|
|
|
if (canvas && wrapper && code) {
|
2025-02-04 00:37:14 +00:00
|
|
|
const wrapperRect = wrapper.getBoundingClientRect()
|
2024-11-12 21:27:19 +00:00
|
|
|
|
2026-07-08 22:03:08 +00:00
|
|
|
scale = wrapperRect.width / canvas.width
|
|
|
|
|
height = canvas.height * scale
|
2025-02-04 00:37:14 +00:00
|
|
|
}
|
2024-11-12 21:27:19 +00:00
|
|
|
})
|
|
|
|
|
</script>
|
|
|
|
|
|
2025-09-22 21:57:43 +00:00
|
|
|
<Button class="flex w-full justify-center {props.class}" onclick={copy}>
|
|
|
|
|
<div bind:this={wrapper} class="w-md" style={`height: ${height}px`}>
|
2024-11-12 21:27:19 +00:00
|
|
|
<canvas
|
2026-06-24 20:56:53 +00:00
|
|
|
class="rounded-2xl"
|
2024-11-12 21:27:19 +00:00
|
|
|
bind:this={canvas}
|
2025-02-03 23:01:42 +00:00
|
|
|
style={`transform-origin: top left; transform: scale(${scale}, ${scale})`}>
|
|
|
|
|
</canvas>
|
2024-11-12 21:27:19 +00:00
|
|
|
</div>
|
|
|
|
|
</Button>
|