/** * 生成微信分享给聊天框内的图片卡片 */ import { Canvas } from "@tarojs/components"; import style from './index.module.less' import { getCanvasTempPath } from "@/utils/index"; import { Application, ImgLoader, Container, Image as DuduImage, RichText, } from "../../libs/duducanvas/index"; import Taro, { useShareAppMessage, useShareTimeline } from "@tarojs/taro"; import { getSharePromise } from "./shareUtils"; import Stage from "@/libs/duducanvas/Stage"; import { TAgent, TAgentDetail } from "@/types/agent"; import { DEFAULT_AVATAR } from "@/config"; const getCanvasSize = () => { // 根据屏幕宽度计算 canvas 宽度 const systemInfo = Taro.getWindowInfo(); const screenWidth = systemInfo.windowWidth; const designWidth = 375; const designHeight = 300; // 宽高放大一倍 const canvasWidth = screenWidth * 2; const canvasHeight = (screenWidth / designWidth) * designHeight * 2; const ratio = canvasWidth / 210; return { canvasWidth, canvasHeight, ratio, }; }; const drawCircleEffect = (avatar: Container, ratio: number)=> { const circle0 = new Container(); circle0.width = 178 * ratio; circle0.height = 178 * ratio; circle0.borderRadius = "100%"; circle0.shadow = "0 0 20px rgba(0,0,0,.02)"; circle0.backgroundColor = "#f6f6f6"; const circle1 = new Container(); circle1.x = 0; circle1.y = 0; circle1.width = 138 * ratio; circle1.height = 138 * ratio; circle1.borderRadius = "100%"; circle1.shadow = "0 0 20px rgba(0,0,0,.02)"; circle1.backgroundColor = "#f8f8f8"; const circle2 = new Container(); circle2.x = 0; circle2.y = 0; circle2.width = 102 * ratio; circle2.height = 102 * ratio; circle2.borderRadius = "100%"; circle2.shadow = "0 0 20px rgba(0,0,0,.02)"; circle2.backgroundColor = "#fafafa"; circle2.addChild(avatar); circle1.addChild(circle2); circle0.addChild(circle1); return circle0 } interface Props { agent: TAgentDetail; } export default (props: Props) => { const { canvasWidth, canvasHeight, ratio } = getCanvasSize(); let stage: Stage|null; // character = useCurrentCharacter const agent = props.agent const initCanvas = async () => { // console.log('share:', character) if(!agent){ return } const app = new Application( "#myShareCanvas", { width: canvasWidth, height: canvasHeight }, null ); stage = await app.init(); if(!stage){ return; } let avatarImg = agent.avatarLogo ?? DEFAULT_AVATAR const card = new Container(); // 如果有头像,加载头像图片先 const imgArr = [ { id: "avatar", src: avatarImg, } ] const loader = new ImgLoader(stage.canvas, imgArr); await loader.load(); card.x = 0; card.y = -140; card.gap = 5; card.width = 210 * ratio; card.height = 200 * ratio; // 矩形用于头像,及头像背景效果 const rect = new Container(); rect.y = -140 * ratio; rect.direction = "column"; rect.justifyContent = "space-around"; rect.width = 210 * ratio; rect.height = 200 * ratio; rect.borderRadius = 0; card.addChild(rect); // 头像 const avatarTexture = loader.get("avatar"); if (avatarTexture) { const dWidth = 80; const avatar = new DuduImage({ image: avatarTexture.image, dWidth: (dWidth) * ratio, dHeight: (avatarTexture.height * dWidth/avatarTexture.width) * ratio, }); const avatarWrapper = new Container() avatarWrapper.width = dWidth * ratio avatarWrapper.height = dWidth * ratio avatarWrapper.overflowHidden = true avatarWrapper.borderRadius = '100%' avatarWrapper.addChild(avatar) const circleBg = drawCircleEffect(avatarWrapper, ratio) card.backgroundColor = "white"; rect.backgroundColor = "#f5f5f5"; rect.addChild(circleBg) } // 名称与公司名容器 const infoList = new Container(); infoList.y = 110 * ratio; infoList.direction = "column"; infoList.gap = 4 * ratio; infoList.width = 216 * ratio; infoList.height = 42 * ratio; // 用户名 const name = new RichText({ text: agent?.name ?? '', fontSize: 15 * ratio, color: "black", fontWeight: 500, }); name.wrapWidth = 180 * ratio; name.lineClamp = 1; name.shadow = '0 0 4 white' name.height = 22 * ratio; // 单位名 const companyName = new RichText(); companyName.x = 0; companyName.y = 0; companyName.lineClamp = 1; companyName.text = agent?.entName ?? ''; companyName.wrapWidth = 160 * ratio; companyName.fontSize = 12 * ratio; companyName.color = "rgba(0, 0, 0, .45)"; companyName.letterSpace = 4; companyName.lineGap = 8; companyName.shadow = '0 0 4 white' infoList.addChild(name, companyName); stage.addChild(card, infoList); stage.update(); }; // 延迟获取 canvas // Taro.nextTick(() => { // initCanvas(); // }); const shareTitle = '小蓝本' // '想了解我?快和我的AI聊聊吧', useShareAppMessage(async () => { const agentId = agent?.agentId; console.log(agent) Taro.showLoading() await initCanvas(); let tmpImage = '' if(stage){ tmpImage = await getCanvasTempPath(stage.canvas, "myShareCanvas"); } const reponse = await getSharePromise(agentId, shareTitle, tmpImage) Taro.hideLoading() return reponse; }); useShareTimeline(() => { const agentId = agent?.agentId; const o = { title: shareTitle, query: `agentId=${agentId}`, }; return o; }); return ( ); };