diff --git a/src/components/Picker/index.module.scss b/src/components/Picker/index.module.scss index 2b2d946..8d83607 100644 --- a/src/components/Picker/index.module.scss +++ b/src/components/Picker/index.module.scss @@ -1,4 +1,39 @@ .picker-container { + position: relative; + + // 使用包装元素的伪元素创建渐变遮罩 + &::before { + content: ""; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 20%; + background: linear-gradient( + to bottom, + #fafafa, + transparent + ); + pointer-events: none; + z-index: 9999; + } + + &::after { + content: ""; + position: absolute; + bottom: 0; + left: 0; + right: 0; + height: 20%; + background: linear-gradient( + to top, + #fafafa, + transparent + ); + pointer-events: none; + z-index: 9999; + } + :global { .nut-popup-round { position: relative !important; @@ -7,7 +42,7 @@ display: none !important; } - .nut-picker { + .nut-picker { &::after { content: ""; position: absolute; @@ -16,7 +51,7 @@ right: 16px !important; width: calc(100% - 32px); height: 48px; - background: rgba(0, 0, 0, 0.02); + background: rgba(22, 24, 35, 0.05); transform: translateY(-50%); border-radius: 4px; pointer-events: none; diff --git a/src/components/Radar/index.tsx b/src/components/Radar/index.tsx index 4237510..ca71305 100644 --- a/src/components/Radar/index.tsx +++ b/src/components/Radar/index.tsx @@ -38,13 +38,13 @@ const RadarChart: React.FC = forwardRef((props, ref) => { canvas.width = res[0].width * dpr; canvas.height = res[0].height * dpr; ctx.scale(dpr, dpr); - + // 启用抗锯齿,消除锯齿 ctx.imageSmoothingEnabled = true; - ctx.imageSmoothingQuality = 'high'; + ctx.imageSmoothingQuality = "high"; // 设置线条端点样式为圆形,减少锯齿 - ctx.lineCap = 'round'; - ctx.lineJoin = 'round'; + ctx.lineCap = "round"; + ctx.lineJoin = "round"; // === 绘制圆形网格 === for (let i = levels; i >= 1; i--) { @@ -52,10 +52,10 @@ const RadarChart: React.FC = forwardRef((props, ref) => { ctx.beginPath(); ctx.arc(center.x, center.y, r, 0, Math.PI * 2); if (i % 2 === 1) { - ctx.fillStyle = "#fff"; + ctx.fillStyle = "rgba(255, 255, 255, 0.4)"; ctx.fill(); } else { - ctx.fillStyle = "#CAFCF0"; + ctx.fillStyle = "rgba(149, 249, 225, 0.4)"; ctx.fill(); } // 根据层级设置不同的线条颜色,中间圆圈使用更浅的颜色 @@ -70,7 +70,7 @@ const RadarChart: React.FC = forwardRef((props, ref) => { ctx.strokeStyle = "#D5D5D5"; } // 设置线条宽度为1px,确保清晰 - ctx.lineWidth = 1; + ctx.lineWidth = 0.5; ctx.stroke(); } diff --git a/src/other_pages/ntrp-evaluate/index.module.scss b/src/other_pages/ntrp-evaluate/index.module.scss index e83d71e..7b5ac7c 100644 --- a/src/other_pages/ntrp-evaluate/index.module.scss +++ b/src/other_pages/ntrp-evaluate/index.module.scss @@ -546,7 +546,8 @@ align-self: stretch; border-radius: 26px; border: 4px solid #fff; - background: linear-gradient(180deg, #bfffef 0%, #f2fffc 100%), #fff; + // background: linear-gradient(180deg, #bfffef 0%, #f2fffc 100%), #fff; + background-size: contain; box-shadow: 0 8px 64px 0 rgba(0, 0, 0, 0.1); .avatarWrap { diff --git a/src/other_pages/ntrp-evaluate/index.tsx b/src/other_pages/ntrp-evaluate/index.tsx index acd3c06..ed05cab 100644 --- a/src/other_pages/ntrp-evaluate/index.tsx +++ b/src/other_pages/ntrp-evaluate/index.tsx @@ -602,10 +602,10 @@ function Result() { ); } } - + // 使用 RadarV2 的 generateFullImage 方法生成完整图片 const userNickname = (userInfo as any)?.nickname; - const titleText = userNickname + const titleText = userNickname ? `${userNickname}的 NTRP 测试结果为` : "你的 NTRP 测试结果为"; const imageUrl = await radarV2Ref.current?.generateFullImage({ @@ -658,6 +658,7 @@ function Result() { try { const url = await genCardImage(); Taro.saveImageToPhotosAlbum({ filePath: url }); + Taro.showToast({ title: "保存成功" }); } catch (e) { Taro.showToast({ title: "图片保存失败", icon: "none" }); } @@ -691,7 +692,12 @@ function Result() { return ( - + - {(userInfo as any)?.nickname + {(userInfo as any)?.nickname ? `${(userInfo as any).nickname}的 NTRP 测试结果为` : "你的 NTRP 测试结果为"} @@ -776,13 +782,24 @@ function Result() { {/* 隐藏的 RadarV2 用于生成完整图片,不显示在界面上 */} - - + => { // 绘制SVG路径到Canvas const drawSVGPathToCanvas = (ctx: any) => { // 设置绘制样式 - ctx.setStrokeStyle('#48D800'); + ctx.setStrokeStyle('#00E5AD'); ctx.setLineWidth(scale * 3 * dpr); ctx.setLineCap('round'); ctx.setLineJoin('round'); @@ -248,7 +248,7 @@ const drawSVGPathToCanvas = (ctx: any) => { ctx.save(); // 移动到指定位置并缩放 - ctx.translate(scale * 210 * dpr, scale * 90 * dpr); + ctx.translate(scale * 200 * dpr, scale * 90 * dpr); const scaleValue = 0.8 ctx.scale(scaleValue, scaleValue); @@ -490,8 +490,8 @@ const drawShareCard = async (ctx: any, data: ShareCardData, offscreen: any): Pro // 绘制背景 - 渐变色 已完成 const gradient = ctx.createLinearGradient(0, 0, 0, canvasHeightPx) - gradient.addColorStop(0, '#D8FFE5') - gradient.addColorStop(1, '#F9FFFB') + gradient.addColorStop(0, '#BFFFEF') + gradient.addColorStop(1, '#F2FFFC') ctx.setFillStyle(gradient) ctx.fillRect(0, 0, canvasWidthPx, canvasHeightPx) console.log('背景绘制完成') @@ -543,9 +543,9 @@ const drawShareCard = async (ctx: any, data: ShareCardData, offscreen: any): Pro drawBoldText(ctx, '邀你加入', inviteX, inviteY, inviteFontSize, '#000000', "Noto Sans SC") // 绘制"球局"特殊样式 - const qiuJuX = inviteX + ctx.measureText('邀你加入').width + 5 * dpr + const qiuJuX = inviteX + ctx.measureText('邀你加入').width + 4 * dpr const qiuJuFontSize = scale * 44 * dpr - drawBoldText(ctx, '球局', qiuJuX, inviteY, qiuJuFontSize, '#48D800', '"Noto Sans SC"') + drawBoldText(ctx, '球局', qiuJuX, inviteY, qiuJuFontSize, '#00E5AD', '"Noto Sans SC"') // 测试绘制网络图片 drawSVGPathToCanvas(ctx) @@ -602,20 +602,29 @@ const drawShareCard = async (ctx: any, data: ShareCardData, offscreen: any): Pro // 绘制"单打"标签 const danDaX = scale * 100 const danDaY = scale * 196 - const danDaWidth = scale * 76 * dpr const danDaHeight = scale * 40 * dpr const danDaRadius = scale * 20 * dpr const danDaFontSize = scale * 22 * dpr + // 根据内容动态计算标签宽度(左右内边距) + const danDaPaddingX = scale * 16 * dpr + ctx.setFontSize(danDaFontSize) + const danDaTextWidth = ctx.measureText(data.gameType).width + const danDaWidth = danDaTextWidth + danDaPaddingX * 2 drawLabel(ctx, danDaX, danDaY, danDaWidth, danDaHeight, danDaRadius, data.gameType, danDaFontSize) - // 绘制技能等级标签 - const skillX = scale * 190 + // 绘制技能等级标签(基于“单打”标签实际宽度后移) + const labelGap = scale * 16 // 两个标签之间的间距(不乘 dpr,保持视觉间距) + const skillX = danDaX + danDaWidth + labelGap const skillY = scale * 196 - const skillWidth = scale * 180 * dpr const skillHeight = scale * 40 * dpr const skillRadius = scale * 20 * dpr const skillFontSize = scale * 22 * dpr + // 根据内容动态计算技能标签宽度 + const skillPaddingX = scale * 20 * dpr + ctx.setFontSize(skillFontSize) + const skillTextWidth = ctx.measureText(data.skillLevel).width + const skillWidth = skillTextWidth + skillPaddingX * 2 drawLabel(ctx, skillX, skillY, skillWidth, skillHeight, skillRadius, data.skillLevel, skillFontSize) @@ -627,7 +636,7 @@ const drawShareCard = async (ctx: any, data: ShareCardData, offscreen: any): Pro ctx.drawImage(calendarPath, iconX, timeInfoY, iconSize, iconSize) // 绘制日期(绿色) - drawText(ctx, data.gameDate, dateX, timeInfoY + 8, 300, timeInfoFontSize, '#4CAF50') + drawText(ctx, data.gameDate, dateX, timeInfoY + 8, 300, timeInfoFontSize, '#00E5AD') // 绘制时间(黑色) const timeX = textX + ctx.measureText(data.gameDate).width + 10 * dpr