1. 海报
This commit is contained in:
83
vite-tailwindcss/src/composables/renderFestiveQr.js
Normal file
83
vite-tailwindcss/src/composables/renderFestiveQr.js
Normal file
@@ -0,0 +1,83 @@
|
||||
import QRCode from 'qrcode'
|
||||
|
||||
function loadImage(src) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const img = new Image()
|
||||
img.crossOrigin = 'anonymous'
|
||||
img.onload = () => resolve(img)
|
||||
img.onerror = reject
|
||||
img.src = src
|
||||
})
|
||||
}
|
||||
|
||||
/** 在 canvas 上绘制喜庆二维码,中心为配置图或圆圈大囍 */
|
||||
export async function renderFestiveQr(canvas, url, options = {}) {
|
||||
const size = options.size || 148
|
||||
const centerImg = String(options.centerImg || '').trim()
|
||||
|
||||
await QRCode.toCanvas(canvas, url, {
|
||||
width: size,
|
||||
margin: 1,
|
||||
color: {
|
||||
dark: '#8b0000',
|
||||
light: '#fff8e7',
|
||||
},
|
||||
errorCorrectionLevel: 'H',
|
||||
})
|
||||
|
||||
const ctx = canvas.getContext('2d')
|
||||
if (!ctx) return
|
||||
|
||||
const w = canvas.width
|
||||
const h = canvas.height
|
||||
const cx = w / 2
|
||||
const cy = h / 2
|
||||
const diameter = Math.round(Math.min(w, h) * 0.3)
|
||||
const r = diameter / 2
|
||||
const ring = Math.max(2, Math.round(w * 0.012))
|
||||
|
||||
ctx.save()
|
||||
// 外圈底
|
||||
ctx.beginPath()
|
||||
ctx.arc(cx, cy, r + ring, 0, Math.PI * 2)
|
||||
ctx.fillStyle = '#fff8e7'
|
||||
ctx.fill()
|
||||
ctx.strokeStyle = '#c41e3a'
|
||||
ctx.lineWidth = ring
|
||||
ctx.stroke()
|
||||
|
||||
let drewImg = false
|
||||
if (centerImg) {
|
||||
try {
|
||||
const img = await loadImage(centerImg)
|
||||
ctx.beginPath()
|
||||
ctx.arc(cx, cy, r - 0.5, 0, Math.PI * 2)
|
||||
ctx.clip()
|
||||
const side = (r - 0.5) * 2
|
||||
const scale = Math.max(side / img.width, side / img.height)
|
||||
const dw = img.width * scale
|
||||
const dh = img.height * scale
|
||||
ctx.drawImage(img, cx - dw / 2, cy - dh / 2, dw, dh)
|
||||
drewImg = true
|
||||
} catch {
|
||||
drewImg = false
|
||||
}
|
||||
}
|
||||
|
||||
if (!drewImg) {
|
||||
ctx.beginPath()
|
||||
ctx.arc(cx, cy, r - 0.5, 0, Math.PI * 2)
|
||||
ctx.fillStyle = 'rgba(255, 248, 231, 0.96)'
|
||||
ctx.fill()
|
||||
ctx.strokeStyle = '#c41e3a'
|
||||
ctx.lineWidth = Math.max(1.5, ring * 0.7)
|
||||
ctx.stroke()
|
||||
ctx.fillStyle = '#c41e3a'
|
||||
ctx.font = `700 ${Math.round(r * 1.45)}px "Noto Serif SC","Source Han Serif SC","Songti SC",serif`
|
||||
ctx.textAlign = 'center'
|
||||
ctx.textBaseline = 'middle'
|
||||
ctx.fillText('囍', cx, cy + r * 0.04)
|
||||
}
|
||||
|
||||
ctx.restore()
|
||||
}
|
||||
Reference in New Issue
Block a user