|
1 | 1 | <script lang="ts" setup>
|
2 |
| -import { encode, renderSVG } from 'uqr' |
| 2 | +import type { EncodedBlock } from '~~/utils/lt-code' |
| 3 | +import { blockToBinary, createEncoder } from '~~/utils/lt-code' |
| 4 | +import { fromUint8Array } from 'js-base64' |
| 5 | +import { renderSVG } from 'uqr' |
3 | 6 |
|
4 | 7 | const props = withDefaults(defineProps<{
|
5 |
| - data: string[] |
| 8 | + data: Uint8Array |
6 | 9 | speed: number
|
7 | 10 | }>(), {
|
8 | 11 | speed: 250,
|
9 | 12 | })
|
10 | 13 |
|
11 |
| -const ecc = 'L' as const |
12 |
| -const minVersion = computed(() => encode(props.data[0]! || '', { ecc }).version) |
13 |
| -const svgList = computed(() => props.data.map(content => renderSVG(content, { |
14 |
| - border: 1, |
15 |
| - ecc, |
16 |
| - minVersion: minVersion.value, |
17 |
| -}))) |
18 |
| -const activeIndex = ref(0) |
19 |
| -watch(() => props.data, () => activeIndex.value = 0) |
| 14 | +const count = ref(0) |
| 15 | +const encoder = createEncoder(props.data, 1000) |
| 16 | +const svg = ref<string>() |
| 17 | +const block = shallowRef<EncodedBlock>() |
20 | 18 |
|
21 |
| -let intervalId: any |
22 |
| -function initInterval() { |
23 |
| - intervalId = setInterval(() => { |
24 |
| - activeIndex.value = (activeIndex.value + 1) % svgList.value.length |
25 |
| - }, props.speed) |
26 |
| -} |
27 |
| -watch(() => props.speed, () => { |
28 |
| - intervalId && clearInterval(intervalId) |
29 |
| - initInterval() |
30 |
| -}, { immediate: true }) |
31 |
| -onUnmounted(() => intervalId && clearInterval(intervalId)) |
| 19 | +const renderTime = ref(0) |
| 20 | +const framePerSecond = computed(() => 1000 / renderTime.value) |
| 21 | +
|
| 22 | +onMounted(() => { |
| 23 | + let frame = performance.now() |
| 24 | +
|
| 25 | + useIntervalFn(() => { |
| 26 | + count.value++ |
| 27 | + const data = encoder.fountain().next().value |
| 28 | + block.value = data |
| 29 | + const binary = blockToBinary(data) |
| 30 | + const str = fromUint8Array(binary) |
| 31 | + svg.value = renderSVG(str, { border: 1 }) |
| 32 | + const now = performance.now() |
| 33 | + renderTime.value = now - frame |
| 34 | + frame = now |
| 35 | + }, () => props.speed) |
| 36 | +}) |
32 | 37 | </script>
|
33 | 38 |
|
34 | 39 | <template>
|
35 |
| - <div flex flex-col items-center> |
36 |
| - <p mb-4> |
37 |
| - {{ activeIndex }}/{{ svgList.length }} |
| 40 | + <div flex flex-col items-center pb-20> |
| 41 | + <p mb-4 w-full of-x-auto ws-nowrap font-mono> |
| 42 | + Indices: {{ block?.indices }}<br> |
| 43 | + Total: {{ block?.k }}<br> |
| 44 | + Bytes: {{ ((block?.bytes || 0) / 1024).toFixed(2) }} KB<br> |
| 45 | + Bitrate: {{ ((block?.bytes || 0) / 1024 * framePerSecond).toFixed(2) }} Kbps<br> |
| 46 | + Frame Count: {{ count }}<br> |
| 47 | + FPS: {{ framePerSecond.toFixed(2) }} |
38 | 48 | </p>
|
39 | 49 | <div class="relative h-full w-full">
|
40 | 50 | <div
|
41 |
| - class="arc aspect-square" absolute inset-0 |
42 |
| - :style="{ '--deg': `${(activeIndex + 1) * 360 / svgList.length}deg` }" |
43 |
| - /> |
44 |
| - <div |
45 |
| - v-for="svg, idx of svgList" |
46 |
| - :key="idx" |
47 |
| - :class="{ hidden: idx !== activeIndex }" |
48 | 51 | class="aspect-square [&>svg]:h-full [&>svg]:w-full"
|
49 | 52 | h-full w-full
|
50 | 53 | v-html="svg"
|
|
0 commit comments