123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- /**
- * 生成微信分享给聊天框内的图片卡片
- */
- 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 (
- <Canvas
- type="2d"
- id="myShareCanvas"
- width={String(canvasWidth)}
- height={String(canvasHeight)}
- style={`width: ${canvasWidth / 2}px; height: ${canvasHeight / 2}px;`}
- className={style.canvas}
- />
- );
- };
|