小程序二维码功能
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { View, Canvas } from '@tarojs/components';
|
||||
import Taro from '@tarojs/taro';
|
||||
import {
|
||||
REDEEM_QR_DISPLAY_SIZE,
|
||||
buildRedeemQrDataUrl,
|
||||
drawRedeemQrOnCanvas,
|
||||
} from '../lib/redeem-qr';
|
||||
|
||||
const CANVAS_ID = 'redeem-qr-canvas';
|
||||
|
||||
type RedeemQrCodeProps = {
|
||||
token: string;
|
||||
};
|
||||
|
||||
function drawOnWeappCanvas(token: string) {
|
||||
const page = Taro.getCurrentInstance().page;
|
||||
const query = page ? Taro.createSelectorQuery().in(page) : Taro.createSelectorQuery();
|
||||
query
|
||||
.select(`#${CANVAS_ID}`)
|
||||
.fields({ node: true, size: true })
|
||||
.exec((res) => {
|
||||
const item = res[0] as { node?: WechatMiniprogram.Canvas; width?: number; height?: number } | undefined;
|
||||
const canvas = item?.node;
|
||||
if (!canvas) return;
|
||||
|
||||
const layoutW = item.width || REDEEM_QR_DISPLAY_SIZE;
|
||||
const layoutH = item.height || REDEEM_QR_DISPLAY_SIZE;
|
||||
const drawSize = Math.min(layoutW, layoutH);
|
||||
|
||||
const ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
|
||||
const dpr = Taro.getSystemInfoSync().pixelRatio || 2;
|
||||
canvas.width = layoutW * dpr;
|
||||
canvas.height = layoutH * dpr;
|
||||
ctx.scale(dpr, dpr);
|
||||
drawRedeemQrOnCanvas(ctx, token, drawSize);
|
||||
});
|
||||
}
|
||||
|
||||
export default function RedeemQrCode({ token }: RedeemQrCodeProps) {
|
||||
const [imgSrc, setImgSrc] = useState('');
|
||||
const isWeapp = process.env.TARO_ENV === 'weapp';
|
||||
|
||||
useEffect(() => {
|
||||
if (!token) {
|
||||
setImgSrc('');
|
||||
return;
|
||||
}
|
||||
|
||||
if (isWeapp) {
|
||||
const timer = setTimeout(() => drawOnWeappCanvas(token), 120);
|
||||
return () => clearTimeout(timer);
|
||||
}
|
||||
|
||||
let cancelled = false;
|
||||
void buildRedeemQrDataUrl(token).then((url) => {
|
||||
if (!cancelled) setImgSrc(url);
|
||||
});
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [token, isWeapp]);
|
||||
|
||||
return (
|
||||
<View className="redeem-qr-box">
|
||||
<View className="redeem-qr-placeholder" />
|
||||
{isWeapp ? (
|
||||
<Canvas type="2d" id={CANVAS_ID} canvasId={CANVAS_ID} className="redeem-qr-canvas" />
|
||||
) : imgSrc ? (
|
||||
<View className="redeem-qr-img" style={{ backgroundImage: `url(${imgSrc})` }} />
|
||||
) : null}
|
||||
<View className="redeem-qr-scanline" />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user