Merge branch 'feat/liujie'
This commit is contained in:
@@ -220,7 +220,7 @@
|
|||||||
|
|
||||||
& > .input {
|
& > .input {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 36px;
|
height: 24px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import addComment from "@/static/detail/icon-write.svg";
|
|||||||
import emptyComment from "@/static/emptyStatus/comment-empty.png";
|
import emptyComment from "@/static/emptyStatus/comment-empty.png";
|
||||||
import CommonPopup from "../CommonPopup";
|
import CommonPopup from "../CommonPopup";
|
||||||
import styles from "./index.module.scss";
|
import styles from "./index.module.scss";
|
||||||
|
import { useKeyboardHeight } from "@/store/keyboardStore";
|
||||||
|
|
||||||
// const PAGESIZE = 4;
|
// const PAGESIZE = 4;
|
||||||
const PAGESIZE = 1000;
|
const PAGESIZE = 1000;
|
||||||
@@ -58,9 +59,30 @@ const CommentInput = forwardRef<CommentInputRef, CommentInputProps>(function (
|
|||||||
CommentInputReplyParamsType | undefined
|
CommentInputReplyParamsType | undefined
|
||||||
>();
|
>();
|
||||||
|
|
||||||
const inputDomRef = useRef(null);
|
const {
|
||||||
|
keyboardHeight,
|
||||||
|
isKeyboardVisible,
|
||||||
|
addListener,
|
||||||
|
initializeKeyboardListener,
|
||||||
|
} = useKeyboardHeight();
|
||||||
|
|
||||||
const [adjust, setAdjust] = useState(false);
|
// 使用全局键盘状态监听
|
||||||
|
useEffect(() => {
|
||||||
|
// 初始化全局键盘监听器
|
||||||
|
initializeKeyboardListener();
|
||||||
|
|
||||||
|
// 添加本地监听器
|
||||||
|
const removeListener = addListener((height, visible) => {
|
||||||
|
console.log("PublishBall 收到键盘变化:", height, visible);
|
||||||
|
// 这里只记录或用于其他逻辑,布局是否响应交由 shouldReactToKeyboard 决定
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
removeListener();
|
||||||
|
};
|
||||||
|
}, [initializeKeyboardListener, addListener]);
|
||||||
|
|
||||||
|
const inputDomRef = useRef(null);
|
||||||
|
|
||||||
useImperativeHandle(ref, () => ({
|
useImperativeHandle(ref, () => ({
|
||||||
show: (_params: CommentInputReplyParamsType | undefined) => {
|
show: (_params: CommentInputReplyParamsType | undefined) => {
|
||||||
@@ -84,9 +106,9 @@ const CommentInput = forwardRef<CommentInputRef, CommentInputProps>(function (
|
|||||||
function onClose() {
|
function onClose() {
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
setValue("");
|
setValue("");
|
||||||
setAdjust(false);
|
|
||||||
inputDomRef.current && inputDomRef.current?.blur();
|
inputDomRef.current && inputDomRef.current?.blur();
|
||||||
}
|
}
|
||||||
|
console.log(keyboardHeight, "keyboardHeight");
|
||||||
return (
|
return (
|
||||||
<CommonPopup
|
<CommonPopup
|
||||||
visible={visible}
|
visible={visible}
|
||||||
@@ -97,27 +119,23 @@ const CommentInput = forwardRef<CommentInputRef, CommentInputProps>(function (
|
|||||||
style={{
|
style={{
|
||||||
height: "60px!important",
|
height: "60px!important",
|
||||||
minHeight: "unset",
|
minHeight: "unset",
|
||||||
|
bottom:
|
||||||
|
isKeyboardVisible && keyboardHeight > 0 ? `${keyboardHeight}px` : "0",
|
||||||
}}
|
}}
|
||||||
enableDragToClose={false}
|
enableDragToClose={false}
|
||||||
>
|
>
|
||||||
<View className={styles.inputContainer}>
|
<View className={styles.inputContainer}>
|
||||||
<View className={styles.inputWrapper}>
|
<View className={styles.inputWrapper}>
|
||||||
<Input
|
<Input
|
||||||
adjustPosition={adjust}
|
adjustPosition={false}
|
||||||
ref={inputDomRef}
|
ref={inputDomRef}
|
||||||
className={styles.input}
|
className={styles.input}
|
||||||
value={value}
|
value={value}
|
||||||
onInput={(e) => setValue(e.detail.value)}
|
onInput={(e) => setValue(e.detail.value)}
|
||||||
cursorSpacing={20}
|
|
||||||
placeholder={
|
placeholder={
|
||||||
params?.reply_to_user_id ? `回复 @${params.nickname}` : "写评论"
|
params?.reply_to_user_id ? `回复 @${params.nickname}` : "写评论"
|
||||||
}
|
}
|
||||||
focus
|
focus
|
||||||
onFocus={() => {
|
|
||||||
setTimeout(() => {
|
|
||||||
setAdjust(true);
|
|
||||||
}, 10);
|
|
||||||
}}
|
|
||||||
maxlength={100}
|
maxlength={100}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
@@ -1,355 +0,0 @@
|
|||||||
import { useEffect, useImperativeHandle, forwardRef } from "react";
|
|
||||||
import { Canvas } from "@tarojs/components";
|
|
||||||
import Taro from "@tarojs/taro";
|
|
||||||
|
|
||||||
function getImageWh(src): Promise<{ width: number; height: number }> {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
Taro.getImageInfo({
|
|
||||||
src,
|
|
||||||
success: ({ width, height }) => resolve({ width, height }),
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const qrCodeUrl =
|
|
||||||
"https://bimwe.oss-cn-shanghai.aliyuncs.com/front/ball/images/5e013195-fc79-4082-bf06-9aa79aea65ae.png";
|
|
||||||
|
|
||||||
const ringUrl =
|
|
||||||
"https://bimwe.oss-cn-shanghai.aliyuncs.com/front/ball/images/b635164f-ecec-434a-a00b-69614a918f2f.png";
|
|
||||||
|
|
||||||
const dateIcon =
|
|
||||||
"https://bimwe.oss-cn-shanghai.aliyuncs.com/front/ball/images/1b49476e-0eda-42ff-b08c-002ce510df82.jpg";
|
|
||||||
|
|
||||||
const mapIcon =
|
|
||||||
"https://bimwe.oss-cn-shanghai.aliyuncs.com/front/ball/images/06b994fa-9227-4708-8555-8a07af8d0c3b.jpg";
|
|
||||||
|
|
||||||
// const logo = "http://bimwe.oss-cn-shanghai.aliyuncs.com/front/ball/images/fb732da6-11b9-4022-a524-a377b17635eb.jpg"
|
|
||||||
|
|
||||||
const logoText =
|
|
||||||
"https://bimwe.oss-cn-shanghai.aliyuncs.com/front/ball/images/9d8cbc9d-9601-4e2d-ab23-76420a4537d6.png";
|
|
||||||
|
|
||||||
const Poster = (props, ref) => {
|
|
||||||
const { data } = props;
|
|
||||||
const {
|
|
||||||
playType,
|
|
||||||
ntrp,
|
|
||||||
mainCoursal,
|
|
||||||
nickname,
|
|
||||||
avatarUrl,
|
|
||||||
title,
|
|
||||||
locationName,
|
|
||||||
date,
|
|
||||||
time,
|
|
||||||
} = data;
|
|
||||||
useEffect(() => {
|
|
||||||
drawCard();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useImperativeHandle(ref, () => ({
|
|
||||||
generateImage: () =>
|
|
||||||
new Promise((resolve, reject) => {
|
|
||||||
const query = Taro.createSelectorQuery();
|
|
||||||
query
|
|
||||||
.select("#cardCanvas")
|
|
||||||
.fields({ node: true, size: true })
|
|
||||||
.exec((res) => {
|
|
||||||
const canvas = res[0].node;
|
|
||||||
// ⚠️ 关键:传 canvas,而不是 canvasId
|
|
||||||
Taro.canvasToTempFilePath({
|
|
||||||
canvas,
|
|
||||||
success: (res) => resolve(res.tempFilePath),
|
|
||||||
fail: (err) => reject(err),
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
}));
|
|
||||||
|
|
||||||
const drawCard = async () => {
|
|
||||||
const query = Taro.createSelectorQuery();
|
|
||||||
query
|
|
||||||
.select("#cardCanvas")
|
|
||||||
.fields({ node: true, size: true })
|
|
||||||
.exec(async (res) => {
|
|
||||||
const canvas = res[0].node;
|
|
||||||
const ctx = canvas.getContext("2d");
|
|
||||||
const dpr = Taro.getWindowInfo().pixelRatio;
|
|
||||||
const width = 600; // px
|
|
||||||
const height = 1000;
|
|
||||||
|
|
||||||
canvas.width = width * dpr;
|
|
||||||
canvas.height = height * dpr;
|
|
||||||
ctx.scale(dpr, dpr);
|
|
||||||
|
|
||||||
// 背景卡片
|
|
||||||
// roundRect(ctx, 0, 0, width, height, 20, "#fff");
|
|
||||||
|
|
||||||
// 整体背景
|
|
||||||
roundRectGradient(ctx, 0, 0, width, height, 24, "#BFFFEF", "#F2FFFC");
|
|
||||||
|
|
||||||
// 顶部图片
|
|
||||||
const img = await loadImage(canvas, mainCoursal);
|
|
||||||
// roundRect(ctx, 20, 20, width - 40, width - 40, 20, "#fff");
|
|
||||||
await drawCoverImage(
|
|
||||||
ctx,
|
|
||||||
mainCoursal,
|
|
||||||
img,
|
|
||||||
10,
|
|
||||||
10,
|
|
||||||
width - 20,
|
|
||||||
width - 20,
|
|
||||||
20
|
|
||||||
);
|
|
||||||
|
|
||||||
// 标签
|
|
||||||
let left = drawTag(ctx, playType, 18, 18);
|
|
||||||
drawTag(ctx, ntrp, left + 4, 18);
|
|
||||||
|
|
||||||
let top = width - 10;
|
|
||||||
left = 16;
|
|
||||||
|
|
||||||
top += 16;
|
|
||||||
|
|
||||||
// 用户头像(圆形)
|
|
||||||
const avatar = await loadImage(canvas, avatarUrl);
|
|
||||||
ctx.save();
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.arc(left + 30, top + 30, 30, 0, Math.PI * 2);
|
|
||||||
ctx.clip();
|
|
||||||
ctx.drawImage(avatar, left, top, 60, 60);
|
|
||||||
ctx.restore();
|
|
||||||
|
|
||||||
// 头像右边 6
|
|
||||||
left += 66;
|
|
||||||
|
|
||||||
top += 40;
|
|
||||||
|
|
||||||
// 用户名 + 邀请
|
|
||||||
ctx.fillStyle = "#333";
|
|
||||||
ctx.font = "bold 28px sans-serif";
|
|
||||||
// ctx.fillText("华巴轮卡 邀你加入球局", 100, 370);
|
|
||||||
const nickNameText = `${nickname} 邀你加入`;
|
|
||||||
ctx.fillText(nickNameText, left, top);
|
|
||||||
let textW = ctx.measureText(nickNameText).width;
|
|
||||||
left += textW;
|
|
||||||
ctx.fillStyle = "#00B578";
|
|
||||||
ctx.fillText("球局", left, top);
|
|
||||||
const ringImg = await loadImage(canvas, ringUrl);
|
|
||||||
ctx.drawImage(ringImg, left - 10, top - 30, 80, 36);
|
|
||||||
|
|
||||||
left = 16;
|
|
||||||
top += 60;
|
|
||||||
|
|
||||||
// 活动标题
|
|
||||||
ctx.fillStyle = "#333";
|
|
||||||
ctx.font = "bold 34px sans-serif";
|
|
||||||
let r = drawTextWrap(ctx, title, left, top, width - 32, 40);
|
|
||||||
|
|
||||||
top = r.top + 40;
|
|
||||||
left = 16;
|
|
||||||
const dateImg = await loadImage(canvas, dateIcon);
|
|
||||||
await drawCoverImage(ctx, dateIcon, dateImg, left, top, 40, 40, 8);
|
|
||||||
|
|
||||||
left += 40 + 8;
|
|
||||||
|
|
||||||
top += 30;
|
|
||||||
|
|
||||||
// 时间
|
|
||||||
ctx.font = "26px sans-serif";
|
|
||||||
ctx.fillStyle = "#00B578";
|
|
||||||
ctx.fillText(date, left, top);
|
|
||||||
textW = ctx.measureText(date).width;
|
|
||||||
left += 8 + textW;
|
|
||||||
ctx.fillStyle = "#333";
|
|
||||||
ctx.fillText(time, left, top);
|
|
||||||
|
|
||||||
left = 16;
|
|
||||||
top += 24;
|
|
||||||
const mapImg = await loadImage(canvas, mapIcon);
|
|
||||||
await drawCoverImage(ctx, dateIcon, mapImg, left, top, 40, 40, 8);
|
|
||||||
|
|
||||||
left += 40 + 8;
|
|
||||||
top += 30;
|
|
||||||
|
|
||||||
// 地址
|
|
||||||
ctx.fillStyle = "#666";
|
|
||||||
ctx.font = "26px sans-serif";
|
|
||||||
r = drawTextWrap(ctx, locationName, left, top, width - 32 - left, 34);
|
|
||||||
|
|
||||||
left = 16;
|
|
||||||
top = r.top + 60;
|
|
||||||
|
|
||||||
const logoWh = await getImageWh(logoText);
|
|
||||||
console.log(logoWh);
|
|
||||||
const logoTextImg = await loadImage(canvas, logoText);
|
|
||||||
ctx.drawImage(
|
|
||||||
logoTextImg,
|
|
||||||
left,
|
|
||||||
top,
|
|
||||||
400,
|
|
||||||
// 56
|
|
||||||
400 / (logoWh.width / logoWh.height)
|
|
||||||
);
|
|
||||||
|
|
||||||
const qrImg = await loadImage(canvas, qrCodeUrl);
|
|
||||||
ctx.drawImage(qrImg, width - 12 - 150, top - 50, 160, 160);
|
|
||||||
|
|
||||||
left = 16;
|
|
||||||
top += 400 / (logoWh.width / logoWh.height) + 30;
|
|
||||||
|
|
||||||
// 底部文字
|
|
||||||
ctx.fillStyle = "#333";
|
|
||||||
ctx.font = "20px sans-serif";
|
|
||||||
ctx.fillText("长按识别二维码,快来加入,有你就有场!", left, top);
|
|
||||||
|
|
||||||
// 小程序码
|
|
||||||
// const qrcode = await loadImage(canvas, "小程序码路径");
|
|
||||||
// ctx.drawImage(qrcode, 480, 880, 100, 100);
|
|
||||||
|
|
||||||
// 导出图片
|
|
||||||
// Taro.canvasToTempFilePath({
|
|
||||||
// canvas,
|
|
||||||
// success: (res) => {
|
|
||||||
// console.log("导出路径", res.tempFilePath);
|
|
||||||
// },
|
|
||||||
// fail: (err) => console.error(err),
|
|
||||||
// });
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const roundRectGradient = (ctx, x, y, w, h, r, color1, color2) => {
|
|
||||||
const gradient = ctx.createLinearGradient(x, y, x, y + h);
|
|
||||||
gradient.addColorStop(0, color1);
|
|
||||||
gradient.addColorStop(1, color2);
|
|
||||||
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.moveTo(x + r, y);
|
|
||||||
ctx.lineTo(x + w - r, y);
|
|
||||||
ctx.arcTo(x + w, y, x + w, y + r, r);
|
|
||||||
ctx.lineTo(x + w, y + h - r);
|
|
||||||
ctx.arcTo(x + w, y + h, x + w - r, y + h, r);
|
|
||||||
ctx.lineTo(x + r, y + h);
|
|
||||||
ctx.arcTo(x, y + h, x, y + h - r, r);
|
|
||||||
ctx.lineTo(x, y + r);
|
|
||||||
ctx.arcTo(x, y, x + r, y, r);
|
|
||||||
ctx.closePath();
|
|
||||||
|
|
||||||
ctx.fillStyle = gradient;
|
|
||||||
ctx.fill();
|
|
||||||
};
|
|
||||||
|
|
||||||
const drawCoverImage = async (ctx, src, img, x, y, w, h, r = 0) => {
|
|
||||||
const { width, height } = await getImageWh(src);
|
|
||||||
const imgW = width;
|
|
||||||
const imgH = height;
|
|
||||||
|
|
||||||
// 计算缩放比例,取较大值,保证完全覆盖
|
|
||||||
const scale = Math.max(w / imgW, h / imgH);
|
|
||||||
|
|
||||||
// 缩放后的宽高
|
|
||||||
const newW = imgW * scale;
|
|
||||||
const newH = imgH * scale;
|
|
||||||
|
|
||||||
// 居中偏移
|
|
||||||
const offsetX = x + (w - newW) / 2;
|
|
||||||
const offsetY = y + (h - newH) / 2;
|
|
||||||
|
|
||||||
ctx.save();
|
|
||||||
|
|
||||||
// 如果需要圆角
|
|
||||||
if (r > 0) {
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.moveTo(x + r, y);
|
|
||||||
ctx.lineTo(x + w - r, y);
|
|
||||||
ctx.arcTo(x + w, y, x + w, y + r, r);
|
|
||||||
ctx.lineTo(x + w, y + h - r);
|
|
||||||
ctx.arcTo(x + w, y + h, x + w - r, y + h, r);
|
|
||||||
ctx.lineTo(x + r, y + h);
|
|
||||||
ctx.arcTo(x, y + h, x, y + h - r, r);
|
|
||||||
ctx.lineTo(x, y + r);
|
|
||||||
ctx.arcTo(x, y, x + r, y, r);
|
|
||||||
ctx.closePath();
|
|
||||||
ctx.clip();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 绘制图片 (cover 效果)
|
|
||||||
ctx.drawImage(img, offsetX, offsetY, newW, newH);
|
|
||||||
|
|
||||||
ctx.restore();
|
|
||||||
};
|
|
||||||
|
|
||||||
/** 加载图片 */
|
|
||||||
const loadImage = (canvas, src) => {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
const img = canvas.createImage();
|
|
||||||
img.onload = () => resolve(img);
|
|
||||||
img.src = src;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/** 圆角矩形 */
|
|
||||||
const roundRect = (ctx, x, y, w, h, r, fillStyle) => {
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.moveTo(x + r, y);
|
|
||||||
ctx.lineTo(x + w - r, y);
|
|
||||||
ctx.arcTo(x + w, y, x + w, y + r, r);
|
|
||||||
ctx.lineTo(x + w, y + h - r);
|
|
||||||
ctx.arcTo(x + w, y + h, x + w - r, y + h, r);
|
|
||||||
ctx.lineTo(x + r, y + h);
|
|
||||||
ctx.arcTo(x, y + h, x, y + h - r, r);
|
|
||||||
ctx.lineTo(x, y + r);
|
|
||||||
ctx.arcTo(x, y, x + r, y, r);
|
|
||||||
ctx.closePath();
|
|
||||||
ctx.fillStyle = fillStyle;
|
|
||||||
ctx.fill();
|
|
||||||
};
|
|
||||||
|
|
||||||
/** 绘制标签 */
|
|
||||||
const drawTag = (ctx, text, x, y) => {
|
|
||||||
ctx.font = "22px sans-serif";
|
|
||||||
const padding = 12;
|
|
||||||
const textWidth = ctx.measureText(text).width;
|
|
||||||
roundRect(ctx, x, y, textWidth + padding * 2, 40, 20, "#fff");
|
|
||||||
ctx.fillStyle = "#333";
|
|
||||||
ctx.fillText(text, x + padding, y + 28);
|
|
||||||
return x + textWidth + padding * 2;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** 文本换行 */
|
|
||||||
const drawTextWrap = (ctx, text, x, y, maxWidth, lineHeight) => {
|
|
||||||
let line = "";
|
|
||||||
const lines = [];
|
|
||||||
for (let char of text) {
|
|
||||||
const testLine = line + char;
|
|
||||||
if (ctx.measureText(testLine).width > maxWidth) {
|
|
||||||
lines.push(line);
|
|
||||||
line = char;
|
|
||||||
} else {
|
|
||||||
line = testLine;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (line) lines.push(line);
|
|
||||||
lines.forEach((l, i) => {
|
|
||||||
ctx.fillText(l, x, y + i * lineHeight);
|
|
||||||
});
|
|
||||||
const lastLineText = lines.at(-1);
|
|
||||||
return {
|
|
||||||
left: x + ctx.measureText(lastLineText),
|
|
||||||
top: y + (lines.length - 1) * lineHeight,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Canvas
|
|
||||||
type="2d"
|
|
||||||
id="cardCanvas"
|
|
||||||
style={{
|
|
||||||
width: "600rpx",
|
|
||||||
height: "1000rpx",
|
|
||||||
// position: "absolute",
|
|
||||||
// left: "-9999px",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default forwardRef(Poster);
|
|
||||||
@@ -25,7 +25,6 @@ import GeneralNavbar from "./GeneralNavbar";
|
|||||||
import RadarChart from './Radar'
|
import RadarChart from './Radar'
|
||||||
import EmptyState from './EmptyState';
|
import EmptyState from './EmptyState';
|
||||||
import NTRPTestEntryCard from './NTRPTestEntryCard'
|
import NTRPTestEntryCard from './NTRPTestEntryCard'
|
||||||
import Poster from './Poster'
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
ActivityTypeSwitch,
|
ActivityTypeSwitch,
|
||||||
@@ -56,5 +55,4 @@ export {
|
|||||||
RadarChart,
|
RadarChart,
|
||||||
EmptyState,
|
EmptyState,
|
||||||
NTRPTestEntryCard,
|
NTRPTestEntryCard,
|
||||||
Poster,
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import Taro, {
|
|||||||
useShareAppMessage,
|
useShareAppMessage,
|
||||||
useShareTimeline,
|
useShareTimeline,
|
||||||
useDidShow,
|
useDidShow,
|
||||||
|
useLoad,
|
||||||
} from "@tarojs/taro";
|
} from "@tarojs/taro";
|
||||||
import classnames from "classnames";
|
import classnames from "classnames";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
@@ -22,7 +23,6 @@ import {
|
|||||||
NTRPEvaluatePopup,
|
NTRPEvaluatePopup,
|
||||||
GameManagePopup,
|
GameManagePopup,
|
||||||
Comments,
|
Comments,
|
||||||
Poster,
|
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
import {
|
import {
|
||||||
generateShareImage,
|
generateShareImage,
|
||||||
@@ -42,7 +42,7 @@ import { EvaluateCallback, EvaluateScene } from "@/store/evaluateStore";
|
|||||||
import img from "@/config/images";
|
import img from "@/config/images";
|
||||||
import DownloadIcon from "@/static/detail/download_icon.svg";
|
import DownloadIcon from "@/static/detail/download_icon.svg";
|
||||||
import WechatLogo from "@/static/detail/wechat_icon.svg";
|
import WechatLogo from "@/static/detail/wechat_icon.svg";
|
||||||
import WechatTimeline from "@/static/detail/wechat_timeline.svg";
|
// import WechatTimeline from "@/static/detail/wechat_timeline.svg";
|
||||||
import LinkIcon from "@/static/detail/link.svg";
|
import LinkIcon from "@/static/detail/link.svg";
|
||||||
import CrossIcon from "@/static/detail/cross.svg";
|
import CrossIcon from "@/static/detail/cross.svg";
|
||||||
import { DayOfWeekMap } from "./config";
|
import { DayOfWeekMap } from "./config";
|
||||||
@@ -51,6 +51,20 @@ import "./index.scss";
|
|||||||
|
|
||||||
dayjs.locale("zh-cn");
|
dayjs.locale("zh-cn");
|
||||||
|
|
||||||
|
const useSceneRedirect = (defaultPage: string) => {
|
||||||
|
useLoad((options) => {
|
||||||
|
if (options.scene) {
|
||||||
|
const decoded = decodeURIComponent(options.scene);
|
||||||
|
const params = Object.fromEntries(new URLSearchParams(decoded));
|
||||||
|
const query = Object.entries(params)
|
||||||
|
.map(([k, v]) => `${k}=${encodeURIComponent(v)}`)
|
||||||
|
.join("&");
|
||||||
|
|
||||||
|
Taro.redirectTo({ url: `/${defaultPage}?${query}` });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// 将·作为连接符插入到标签文本之间
|
// 将·作为连接符插入到标签文本之间
|
||||||
function insertDotInTags(tags: string[]) {
|
function insertDotInTags(tags: string[]) {
|
||||||
if (!tags) return [];
|
if (!tags) return [];
|
||||||
@@ -1365,6 +1379,8 @@ function Index() {
|
|||||||
const { fetchUserInfo } = useUserActions(); // 获取登录用户的userInfo
|
const { fetchUserInfo } = useUserActions(); // 获取登录用户的userInfo
|
||||||
const myInfo = useUserInfo();
|
const myInfo = useUserInfo();
|
||||||
|
|
||||||
|
useSceneRedirect("game_pages/detail/index");
|
||||||
|
|
||||||
const isMyOwn = userInfo.id === myInfo.id;
|
const isMyOwn = userInfo.id === myInfo.id;
|
||||||
|
|
||||||
const sharePopupRef = useRef<any>(null);
|
const sharePopupRef = useRef<any>(null);
|
||||||
|
|||||||
@@ -102,7 +102,7 @@
|
|||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
border: 1px solid #efefef;
|
border: 1px solid #efefef;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-shadow: 0 0 1px 0 rgba(0, 0, 0, 0.20), 0 8px 20px 0 rgba(0, 0, 0, 0.12);
|
box-shadow: 0 0 1px 0 rgba(0, 0, 0, 0.2), 0 8px 20px 0 rgba(0, 0, 0, 0.12);
|
||||||
|
|
||||||
.avatarUrl {
|
.avatarUrl {
|
||||||
width: calc(90px * $multiple);
|
width: calc(90px * $multiple);
|
||||||
@@ -120,8 +120,13 @@
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
aspect-ratio: 1/1;
|
aspect-ratio: 1/1;
|
||||||
border-radius: calc(20px * $multiple);
|
border-radius: calc(20px * $multiple);
|
||||||
border: 4px solid #FFF;
|
border: 4px solid #fff;
|
||||||
background: linear-gradient(0deg, rgba(89, 255, 214, 0.20) 0%, rgba(89, 255, 214, 0.20) 100%), #FFF;
|
background: linear-gradient(
|
||||||
|
0deg,
|
||||||
|
rgba(89, 255, 214, 0.2) 0%,
|
||||||
|
rgba(89, 255, 214, 0.2) 100%
|
||||||
|
),
|
||||||
|
#fff;
|
||||||
box-shadow: 0 4px 36px 0 rgba(0, 0, 0, 0.12);
|
box-shadow: 0 4px 36px 0 rgba(0, 0, 0, 0.12);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -141,10 +146,10 @@
|
|||||||
.introContainer {
|
.introContainer {
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
background: radial-gradient(227.15% 100% at 50% 0%, #BFFFEF 0%, #FFF 36.58%), #FAFAFA;
|
background: radial-gradient(227.15% 100% at 50% 0%, #bfffef 0%, #fff 36.58%),
|
||||||
|
#fafafa;
|
||||||
|
|
||||||
.result {
|
.result {
|
||||||
|
|
||||||
.avatarWrap {
|
.avatarWrap {
|
||||||
width: 200px;
|
width: 200px;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
@@ -173,8 +178,8 @@
|
|||||||
gap: 8px;
|
gap: 8px;
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
border: 1px solid rgba(0, 0, 0, 0.06);
|
border: 1px solid rgba(0, 0, 0, 0.06);
|
||||||
background: #FFF;
|
background: #fff;
|
||||||
box-shadow: 0 8px 64px 0 rgba(0, 0, 0, 0.10);
|
box-shadow: 0 8px 64px 0 rgba(0, 0, 0, 0.1);
|
||||||
|
|
||||||
.tipAndTime {
|
.tipAndTime {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -182,7 +187,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
color: rgba(0, 0, 0, 0.65);
|
color: rgba(0, 0, 0, 0.65);
|
||||||
font-feature-settings: 'liga' off, 'clig' off;
|
font-feature-settings: "liga" off, "clig" off;
|
||||||
font-family: "Noto Sans SC";
|
font-family: "Noto Sans SC";
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@@ -192,7 +197,7 @@
|
|||||||
|
|
||||||
.levelWrap {
|
.levelWrap {
|
||||||
color: #000;
|
color: #000;
|
||||||
font-feature-settings: 'liga' off, 'clig' off;
|
font-feature-settings: "liga" off, "clig" off;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
font-family: "Noto Sans SC";
|
font-family: "Noto Sans SC";
|
||||||
font-size: 32px;
|
font-size: 32px;
|
||||||
@@ -205,7 +210,7 @@
|
|||||||
gap: 10px;
|
gap: 10px;
|
||||||
|
|
||||||
.level {
|
.level {
|
||||||
color: #00E5AD;
|
color: #00e5ad;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,7 +244,7 @@
|
|||||||
gap: 10px;
|
gap: 10px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
font-feature-settings: 'liga' off, 'clig' off;
|
font-feature-settings: "liga" off, "clig" off;
|
||||||
font-family: "PingFang SC";
|
font-family: "PingFang SC";
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@@ -309,7 +314,7 @@
|
|||||||
gap: 10px;
|
gap: 10px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
font-feature-settings: 'liga' off, 'clig' off;
|
font-feature-settings: "liga" off, "clig" off;
|
||||||
font-family: "PingFang SC";
|
font-family: "PingFang SC";
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@@ -334,7 +339,8 @@
|
|||||||
.testContainer {
|
.testContainer {
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
background: radial-gradient(227.15% 100% at 50% 0%, #BFFFEF 0%, #FFF 36.58%), #FAFAFA;
|
background: radial-gradient(227.15% 100% at 50% 0%, #bfffef 0%, #fff 36.58%),
|
||||||
|
#fafafa;
|
||||||
|
|
||||||
.bar {
|
.bar {
|
||||||
margin: 12px 20px 36px;
|
margin: 12px 20px 36px;
|
||||||
@@ -406,7 +412,7 @@
|
|||||||
|
|
||||||
.optionText {
|
.optionText {
|
||||||
color: #000;
|
color: #000;
|
||||||
font-feature-settings: 'liga' off, 'clig' off;
|
font-feature-settings: "liga" off, "clig" off;
|
||||||
font-family: "PingFang SC";
|
font-family: "PingFang SC";
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@@ -440,8 +446,8 @@
|
|||||||
height: 52px;
|
height: 52px;
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
border: 1px solid rgba(0, 0, 0, 0.06);
|
border: 1px solid rgba(0, 0, 0, 0.06);
|
||||||
background: rgba(0, 0, 0, 0.20);
|
background: rgba(0, 0, 0, 0.2);
|
||||||
box-shadow: 0 8px 64px 0 rgba(0, 0, 0, 0.10);
|
box-shadow: 0 8px 64px 0 rgba(0, 0, 0, 0.1);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
.nextBtn {
|
.nextBtn {
|
||||||
@@ -458,13 +464,13 @@
|
|||||||
&.disabled {
|
&.disabled {
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
border: 1px solid rgba(0, 0, 0, 0.06);
|
border: 1px solid rgba(0, 0, 0, 0.06);
|
||||||
background: rgba(0, 0, 0, 0.20);
|
background: rgba(0, 0, 0, 0.2);
|
||||||
box-shadow: 0 8px 64px 0 rgba(0, 0, 0, 0.10);
|
box-shadow: 0 8px 64px 0 rgba(0, 0, 0, 0.1);
|
||||||
|
|
||||||
.nextBtn {
|
.nextBtn {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: rgba(0, 0, 0, 0.20);
|
background-color: rgba(0, 0, 0, 0.2);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
}
|
}
|
||||||
@@ -494,7 +500,8 @@
|
|||||||
.resultContainer {
|
.resultContainer {
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
background: radial-gradient(227.15% 100% at 50% 0%, #BFFFEF 0%, #FFF 36.58%), #FAFAFA;
|
background: radial-gradient(227.15% 100% at 50% 0%, #bfffef 0%, #fff 36.58%),
|
||||||
|
#fafafa;
|
||||||
|
|
||||||
.card {
|
.card {
|
||||||
margin: 10px 20px 0;
|
margin: 10px 20px 0;
|
||||||
@@ -508,9 +515,9 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
align-self: stretch;
|
align-self: stretch;
|
||||||
border-radius: 26px;
|
border-radius: 26px;
|
||||||
border: 4px solid #FFF;
|
border: 4px solid #fff;
|
||||||
background: linear-gradient(180deg, #BFFFEF 0%, #F2FFFC 100%), #FFF;
|
background: linear-gradient(180deg, #bfffef 0%, #f2fffc 100%), #fff;
|
||||||
box-shadow: 0 8px 64px 0 rgba(0, 0, 0, 0.10);
|
box-shadow: 0 8px 64px 0 rgba(0, 0, 0, 0.1);
|
||||||
|
|
||||||
.avatarWrap {
|
.avatarWrap {
|
||||||
padding-bottom: 20px;
|
padding-bottom: 20px;
|
||||||
@@ -538,7 +545,7 @@
|
|||||||
|
|
||||||
.levelWrap {
|
.levelWrap {
|
||||||
color: #000;
|
color: #000;
|
||||||
font-feature-settings: 'liga' off, 'clig' off;
|
font-feature-settings: "liga" off, "clig" off;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
font-family: "Noto Sans SC";
|
font-family: "Noto Sans SC";
|
||||||
font-size: 36px;
|
font-size: 36px;
|
||||||
@@ -551,7 +558,7 @@
|
|||||||
gap: 8px;
|
gap: 8px;
|
||||||
|
|
||||||
.level {
|
.level {
|
||||||
color: #00E5AD;
|
color: #00e5ad;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -576,10 +583,10 @@
|
|||||||
gap: 6px;
|
gap: 6px;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
border: 0.5px solid rgba(0, 0, 0, 0.12);
|
border: 0.5px solid rgba(0, 0, 0, 0.12);
|
||||||
background: #FFF;
|
background: #fff;
|
||||||
box-shadow: 0 8px 64px 0 rgba(0, 0, 0, 0.10);
|
box-shadow: 0 8px 64px 0 rgba(0, 0, 0, 0.1);
|
||||||
color: rgba(0, 0, 0, 0.85);
|
color: rgba(0, 0, 0, 0.85);
|
||||||
font-feature-settings: 'liga' off, 'clig' off;
|
font-feature-settings: "liga" off, "clig" off;
|
||||||
font-family: "PingFang SC";
|
font-family: "PingFang SC";
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@@ -595,7 +602,7 @@
|
|||||||
|
|
||||||
.updateTip {
|
.updateTip {
|
||||||
color: #000;
|
color: #000;
|
||||||
font-feature-settings: 'liga' off, 'clig' off;
|
font-feature-settings: "liga" off, "clig" off;
|
||||||
font-family: "PingFang SC";
|
font-family: "PingFang SC";
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@@ -606,7 +613,7 @@
|
|||||||
padding: 24px 0;
|
padding: 24px 0;
|
||||||
|
|
||||||
.grayTip {
|
.grayTip {
|
||||||
color: rgba(60, 60, 67, 0.60);
|
color: rgba(60, 60, 67, 0.6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -628,8 +635,8 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
background: #000;
|
background: #000;
|
||||||
color: #FFF;
|
color: #fff;
|
||||||
font-feature-settings: 'liga' off, 'clig' off;
|
font-feature-settings: "liga" off, "clig" off;
|
||||||
font-family: "PingFang SC";
|
font-family: "PingFang SC";
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@@ -647,15 +654,26 @@
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
|
|
||||||
.share, .saveImage {
|
.share,
|
||||||
|
.saveImage {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
border: 1px solid rgba(0, 0, 0, 0.06);
|
border: 1px solid rgba(0, 0, 0, 0.06);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
.shareBtn, .saveImageBtn {
|
.shareBtn,
|
||||||
background: #FFF;
|
.saveImageBtn {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shareBtnCover,
|
||||||
|
.saveImageBtnCover {
|
||||||
|
background: #fff;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -663,12 +681,13 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
color: #000;
|
color: #000;
|
||||||
font-feature-settings: 'liga' off, 'clig' off;
|
font-feature-settings: "liga" off, "clig" off;
|
||||||
font-family: "PingFang SC";
|
font-family: "PingFang SC";
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
line-height: normal;
|
line-height: normal;
|
||||||
|
border-radius: 16px;
|
||||||
|
|
||||||
.downloadIcon {
|
.downloadIcon {
|
||||||
width: 20px;
|
width: 20px;
|
||||||
|
|||||||
@@ -431,7 +431,10 @@ function Result() {
|
|||||||
adjustRadarLabels(
|
adjustRadarLabels(
|
||||||
Object.entries(res.data.radar_data.abilities).map(([key, value]) => [
|
Object.entries(res.data.radar_data.abilities).map(([key, value]) => [
|
||||||
key,
|
key,
|
||||||
value.current_score,
|
Math.min(
|
||||||
|
100,
|
||||||
|
Math.floor((value.current_score / value.max_score) * 100)
|
||||||
|
),
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -557,11 +560,11 @@ function Result() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
useShareAppMessage(async (res) => {
|
useShareAppMessage(async (res) => {
|
||||||
const url = await genCardImage();
|
// const url = await genCardImage();
|
||||||
console.log(res, "res");
|
console.log(res, "res");
|
||||||
return {
|
return {
|
||||||
title: "分享",
|
title: "来测一测你的NTRP等级吧",
|
||||||
imageUrl: url,
|
// imageUrl: url,
|
||||||
path: `/other_pages/ntrp-evaluate/index?stage=${StageType.INTRO}`,
|
path: `/other_pages/ntrp-evaluate/index?stage=${StageType.INTRO}`,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@@ -641,16 +644,18 @@ function Result() {
|
|||||||
className={styles.shareBtn}
|
className={styles.shareBtn}
|
||||||
openType={userInfo.id ? "share" : undefined}
|
openType={userInfo.id ? "share" : undefined}
|
||||||
onClick={handleAuth}
|
onClick={handleAuth}
|
||||||
>
|
></Button>
|
||||||
|
<View className={styles.shareBtnCover}>
|
||||||
<Image className={styles.wechatIcon} src={WechatIcon} />
|
<Image className={styles.wechatIcon} src={WechatIcon} />
|
||||||
<Text>邀请好友测试</Text>
|
<Text>邀请好友测试</Text>
|
||||||
</Button>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<View className={styles.saveImage} onClick={handleSaveImage}>
|
<View className={styles.saveImage} onClick={handleSaveImage}>
|
||||||
<Button className={styles.saveImageBtn}>
|
<Button className={styles.saveImageBtn}></Button>
|
||||||
|
<View className={styles.saveImageBtnCover}>
|
||||||
<Image className={styles.downloadIcon} src={DownloadIcon} />
|
<Image className={styles.downloadIcon} src={DownloadIcon} />
|
||||||
<Text>保存图片</Text>
|
<Text>保存图片</Text>
|
||||||
</Button>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
@@ -17,30 +17,6 @@ const mapIcon =
|
|||||||
const logoText =
|
const logoText =
|
||||||
"https://bimwe.oss-cn-shanghai.aliyuncs.com/front/ball/images/9d8cbc9d-9601-4e2d-ab23-76420a4537d6.png";
|
"https://bimwe.oss-cn-shanghai.aliyuncs.com/front/ball/images/9d8cbc9d-9601-4e2d-ab23-76420a4537d6.png";
|
||||||
|
|
||||||
/** 将 base64 图片转换为临时文件路径 */
|
|
||||||
// export function base64ToTempFilePath(base64Data: string): Promise<string> {
|
|
||||||
// return new Promise((resolve, reject) => {
|
|
||||||
// const fsm = Taro.getFileSystemManager();
|
|
||||||
// // 生成唯一文件名
|
|
||||||
// const filePath = `${Taro.env.USER_DATA_PATH}/temp_qrcode_${Date.now()}.png`;
|
|
||||||
|
|
||||||
// // 去掉 data:image/png;base64, 前缀(如果有)
|
|
||||||
// const base64 = base64Data.replace(/^data:image\/\w+;base64,/, '');
|
|
||||||
|
|
||||||
// fsm.writeFile({
|
|
||||||
// filePath,
|
|
||||||
// data: base64,
|
|
||||||
// encoding: 'base64',
|
|
||||||
// success: () => fsm.access({
|
|
||||||
// path: filePath,
|
|
||||||
// success: () => resolve(filePath),
|
|
||||||
// fail: (e) => reject(e),
|
|
||||||
// }),
|
|
||||||
// fail: reject,
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
export function base64ToTempFilePath(base64Data: string): Promise<string> {
|
export function base64ToTempFilePath(base64Data: string): Promise<string> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const fsm = Taro.getFileSystemManager();
|
const fsm = Taro.getFileSystemManager();
|
||||||
@@ -238,7 +214,6 @@ export async function generatePosterImage(data: any): Promise<string> {
|
|||||||
|
|
||||||
// 顶部图片
|
// 顶部图片
|
||||||
const mainImg = await loadImage(canvas, data.mainCoursal);
|
const mainImg = await loadImage(canvas, data.mainCoursal);
|
||||||
console.log(222);
|
|
||||||
await drawCoverImage(
|
await drawCoverImage(
|
||||||
ctx,
|
ctx,
|
||||||
canvas,
|
canvas,
|
||||||
@@ -345,7 +320,9 @@ export async function generatePosterImage(data: any): Promise<string> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const qrImg = await loadImage(canvas, data.qrCodeUrl);
|
const qrImg = await loadImage(canvas, data.qrCodeUrl);
|
||||||
ctx.drawImage(qrImg, width - 12 - 150, top - 50, 160, 160);
|
|
||||||
|
roundRectGradient(ctx, width - 12 - 150, top - 50, 140, 140, 20, "#fff", "#fff")
|
||||||
|
ctx.drawImage(qrImg, width - 12 - 145, top - 45, 130, 130);
|
||||||
|
|
||||||
left = 16;
|
left = 16;
|
||||||
top += 400 / (logoWh.width / logoWh.height) + 30;
|
top += 400 / (logoWh.width / logoWh.height) + 30;
|
||||||
|
|||||||
Reference in New Issue
Block a user