1. 海报

This commit is contained in:
李琦
2026-08-03 10:18:23 +08:00
parent 3b9520eb0f
commit 807adbc6a4
10 changed files with 1155 additions and 21 deletions

View File

@@ -0,0 +1,113 @@
<template>
<div class="fq" :class="{ 'fq--compact': compact }">
<div class="fq-title">扫码观喜</div>
<div class="fq-frame">
<span class="fq-corner fq-tl"></span>
<span class="fq-corner fq-tr"></span>
<span class="fq-corner fq-bl"></span>
<span class="fq-corner fq-br"></span>
<canvas ref="canvasRef" class="fq-canvas"></canvas>
</div>
<div v-if="!compact" class="fq-hint">手机扫码打开本页</div>
</div>
</template>
<script setup>
import { onMounted, ref, watch } from 'vue'
import { renderFestiveQr } from '@/composables/renderFestiveQr'
const props = defineProps({
url: { type: String, required: true },
size: { type: Number, default: 148 },
compact: { type: Boolean, default: false },
centerImg: { type: String, default: '' },
})
const canvasRef = ref(null)
async function render() {
if (!canvasRef.value || !props.url) return
const width = props.compact ? Math.min(props.size, 112) : props.size
await renderFestiveQr(canvasRef.value, props.url, {
size: width,
centerImg: props.centerImg,
})
}
onMounted(render)
watch(() => [props.url, props.size, props.compact, props.centerImg], render)
</script>
<style scoped>
.fq {
display: flex;
flex-direction: column;
align-items: center;
gap: 0;
padding: 14px 16px 12px;
background:
radial-gradient(circle at 50% 0%, rgba(240, 215, 140, 0.25), transparent 55%),
linear-gradient(180deg, #9b0000, #6e0000);
border: 1.5px solid #d4af37;
border-radius: 12px;
box-shadow: 0 10px 28px rgba(0, 0, 0, 0.28);
color: #f0d78c;
min-width: 200px;
}
.fq--compact {
min-width: 0;
padding: 8px 10px 8px;
border-radius: 10px;
box-shadow: 0 8px 22px rgba(0, 0, 0, 0.32);
}
.fq--compact .fq-title {
font-size: 12px;
letter-spacing: 0.35em;
padding-left: 0.35em;
margin-bottom: 8px;
}
.fq--compact .fq-frame { padding: 8px; }
.fq--compact .fq-corner { font-size: 10px; }
.fq-title {
font-size: 15px;
letter-spacing: 0.45em;
padding-left: 0.45em;
font-weight: 600;
text-shadow: 0 1px 4px rgba(0, 0, 0, 0.25);
margin-bottom: 10px;
line-height: 1.2;
flex-shrink: 0;
}
.fq-frame {
position: relative;
padding: 14px;
background: linear-gradient(145deg, #fff8e7, #f7e7c3);
border: 2px solid #d4af37;
border-radius: 10px;
box-shadow: inset 0 0 0 1px rgba(155, 0, 0, 0.12);
}
.fq-corner {
position: absolute;
font-size: 12px;
font-weight: 700;
color: #c41e3a;
line-height: 1;
opacity: 0.9;
z-index: 1;
pointer-events: none;
}
.fq-tl { top: 3px; left: 4px; }
.fq-tr { top: 3px; right: 4px; }
.fq-bl { bottom: 3px; left: 4px; }
.fq-br { bottom: 3px; right: 4px; }
.fq-canvas {
display: block;
border-radius: 4px;
}
.fq-hint {
margin-top: 8px;
font-size: 11px;
letter-spacing: 0.18em;
color: rgba(240, 215, 140, 0.85);
}
</style>