Files
mama-box/topic/duiyou/index.html

779 lines
54 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<!-- 11-04 UGC 总开关关着时本页不展示,直接回首页(js/ugc.js) -->
<script src="../../js/ugc.js?v=26110417" data-guard></script>
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">
<meta name="format-detection" content="telephone=no">
<title>测一测:你家准爸爸是哪种队友?</title>
<!-- 孕期专题 · 趣味测试 2:「你家准爸爸是哪种队友?」(2026-11-02 新建)。
结构 / 交互 / 视觉完全照 ../ceshi/(妈妈类型卡 v3),只换内容与主色:主色暖橙 #F27B35、浅底 #FFF1E6(和 ceshi 的紫色区分)。
孕妈来答,描述准爸爸在孕期的表现;12 题,每题 4 个选项各对应一种队友类型。
一页三屏:开始 / 答题(一题一屏,左右滑动)/ 结果(类型卡 + 雷达 + 结合作答的解读 + 小盲区 + 沟通建议 + 转给他看的一句话 + 推荐工具 + 保存结果卡)。
按用户要求:结果页不放「复制发给 xx」类按钮,只保留「保存结果卡」。
结果存 localStorage「mmbox.duiyou.v1」(含每题作答)。插画 img/*.webp(hero + 4 种类型同一画风)。
自成一页:不引 app.js;返回走 history 或相对路径 ../../,推荐工具走 ../_shared/tools.js。
纯娱乐,不采集、不上报答题数据;不造「已有 N 人测过」数字(TESTED_COUNT=0 不显示)。 -->
<style>
:root{--c:#F27B35;--cbg:#FFF1E6;--c06:rgba(242,123,53,.06);--c10:rgba(242,123,53,.10);--c20:rgba(242,123,53,.20);--ink:#1F2329;--txt:#4E5969;--sub:#86909C;--line:#EEF0F3;--soft:#F7F8FA}
*{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent}
html,body{height:100%;overflow:hidden;background:#fff;color:var(--txt);font:15px/1.75 -apple-system,BlinkMacSystemFont,"PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif}
#scroll{position:fixed;inset:0;overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch;overscroll-behavior:none;padding-bottom:calc(24px + env(safe-area-inset-bottom))}
img{display:block;max-width:100%}
button{font:inherit;border:0;background:none;color:inherit;cursor:pointer}
.ic{width:20px;height:20px;flex:none;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.hide{position:absolute;width:0;height:0;overflow:hidden}
[hidden]{display:none !important}
.num{font-variant-numeric:tabular-nums}
mark{background:linear-gradient(transparent 62%,var(--c20) 0);color:inherit;padding:0 1px}
/* 顶栏 */
.bar{position:sticky;top:0;z-index:20;display:flex;align-items:center;gap:4px;height:48px;padding:0 8px;padding-top:env(safe-area-inset-top);background:transparent;border-bottom:1px solid transparent;transition:background .2s,border-color .2s}
.bar.sh{background:#fff;border-bottom-color:var(--line)}
.bar .back{width:36px;height:36px;border-radius:50%;display:grid;place-items:center;color:var(--ink)}
.bar .back .ic{width:22px;height:22px}
.bar .t{font-weight:600;font-size:16px;color:var(--ink)}
/* 三屏 */
.view{display:none}
.view.on{display:block;animation:vin .35s ease both}
@keyframes vin{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
.wrap{padding:0 20px}
.btn{display:flex;align-items:center;justify-content:center;gap:6px;width:100%;height:46px;border-radius:99px;font-size:16px;font-weight:700;transition:transform .15s,opacity .15s}
.btn.pri{background:var(--c);color:#fff;box-shadow:0 6px 16px rgba(242,123,53,.28)}
.btn.sec{background:#fff;color:var(--c);border:1px solid var(--c)}
.btn:active,.tap:active{transform:scale(.98)}
/* 区块标题:小号序号 + 标题 */
.sh2{display:flex;align-items:baseline;gap:8px;margin-bottom:14px}
.sh2 i{font-style:normal;font-size:13px;font-weight:800;color:var(--c);letter-spacing:.5px}
.sh2 b{font-size:18px;font-weight:800;color:var(--ink);line-height:1.4}
.sh2 span{margin-left:auto;font-size:12.5px;color:var(--sub)}
/* ---------- ① 开始 ---------- */
#vStart{margin-top:-48px}
.hero{position:relative;overflow:hidden;min-height:430px;padding:72px 20px 0;background:linear-gradient(160deg,var(--cbg) 0%,#fff 72%)}
.hero .o1,.hero .o2{position:absolute;border-radius:50%;background:var(--c10);pointer-events:none}
.hero .o1{width:260px;height:260px;right:-90px;top:-70px}
.hero .o2{width:150px;height:150px;left:-60px;bottom:40px;background:var(--c06)}
.hero .eb{position:relative;display:inline-flex;align-items:center;gap:6px;height:26px;padding:0 12px;border-radius:99px;background:#fff;color:var(--c);font-size:12.5px;font-weight:700;letter-spacing:.5px;box-shadow:0 2px 8px var(--c10)}
.hero h1{position:relative;margin-top:16px;font-size:30px;font-weight:800;line-height:1.32;color:var(--ink);letter-spacing:.5px}
.hero .meta{position:relative;display:flex;flex-direction:column;gap:8px;margin-top:18px;width:150px}
.hero .meta span{display:flex;align-items:center;gap:6px;font-size:13.5px;color:var(--txt);line-height:1.4}
.hero .meta .ic{width:18px;height:18px;color:var(--c)}
.hero .meta b{color:var(--ink);font-weight:800}
.hero .pic{position:absolute;right:-18px;bottom:0;width:min(228px,calc(100vw - 162px));height:min(228px,calc(100vw - 162px));object-fit:cover;object-position:center 30%;border-radius:28px 0 0 0;box-shadow:0 8px 24px var(--c10)}
.types{margin-top:28px}
.tgrid{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.tcard{display:flex;align-items:center;gap:10px;padding:10px 12px;border-radius:18px;background:var(--soft)}
.tcard img{flex:none;width:46px;height:46px;border-radius:50%;object-fit:cover;object-position:center 22%;border:2px solid #fff;box-shadow:0 2px 8px var(--c10)}
.tcard b{display:block;font-size:14.5px;color:var(--ink);line-height:1.35}
.tcard small{display:block;font-size:12px;color:var(--sub);line-height:1.4}
.startbox{margin-top:28px;text-align:center}
.startbox .note{margin-top:10px;font-size:12.5px;color:var(--sub)}
/* ---------- ② 答题 ---------- */
#vQuiz{padding-top:4px}
.qtop{display:flex;align-items:center;justify-content:space-between;height:34px}
.qtop button{display:inline-flex;align-items:center;gap:2px;font-size:13.5px;color:var(--sub);padding:4px 8px 4px 0}
.qtop button .ic{width:16px;height:16px}
.qtop button:disabled{visibility:hidden}
.qtop .no{font-size:13px;color:var(--sub)}
.qtop .no b{font-size:18px;color:var(--c);font-weight:800}
.feet{display:flex;justify-content:space-between;align-items:center;height:30px;margin-top:4px;padding:0 2px}
.feet svg{width:15px;height:15px;fill:#FCD9C2;transition:fill .3s,transform .3s}
.feet svg:nth-child(odd){transform:translateY(-4px) rotate(-12deg)}
.feet svg:nth-child(even){transform:translateY(4px) rotate(12deg) scaleX(-1)}
.feet svg.done{fill:var(--c)}
.feet svg.cur{fill:var(--c)}
.feet svg.cur:nth-child(odd){transform:translateY(-4px) rotate(-12deg) scale(1.35)}
.feet svg.cur:nth-child(even){transform:translateY(4px) rotate(12deg) scaleX(-1) scale(1.35)}
.stage{margin-top:14px;transition:opacity .22s ease,transform .22s ease}
.stage.outL{opacity:0;transform:translateX(-36px)}
.stage.outR{opacity:0;transform:translateX(36px)}
.stage.inR{opacity:0;transform:translateX(36px);transition:none}
.stage.inL{opacity:0;transform:translateX(-36px);transition:none}
.qcard{position:relative;overflow:hidden;padding:20px 20px 18px;border-radius:24px;background:linear-gradient(160deg,var(--cbg),#fff 78%);box-shadow:0 8px 24px var(--c10)}
.qcard:after{content:"";position:absolute;width:120px;height:120px;right:-40px;top:-40px;border-radius:50%;background:var(--c10)}
.qcard .hd{position:relative;display:flex;align-items:center;justify-content:space-between}
.qcard .qi{width:56px;height:56px;border-radius:18px;display:grid;place-items:center;background:#fff;color:var(--c);box-shadow:0 4px 12px var(--c10)}
.qcard .qi .ic{width:30px;height:30px;stroke-width:1.6}
.qcard .cat{position:relative;z-index:1;height:24px;padding:0 10px;border-radius:99px;background:#fff;color:var(--c);font-size:12px;font-weight:700;line-height:24px}
.qcard h2{position:relative;margin-top:16px;font-size:21px;font-weight:800;line-height:1.45;color:var(--ink);min-height:61px;text-wrap:balance}
.opts{display:flex;flex-direction:column;gap:10px;margin-top:16px}
.opt{position:relative;display:flex;align-items:center;gap:12px;width:100%;min-height:56px;padding:11px 46px 11px 14px;border-radius:18px;background:#fff;border:1.5px solid var(--line);text-align:left;font-size:15.5px;line-height:1.45;color:var(--ink);transition:border-color .2s,background .2s,transform .15s}
.opt:active{transform:scale(.98)}
.opt .l{flex:none;width:26px;height:26px;border-radius:9px;display:grid;place-items:center;background:var(--soft);color:var(--sub);font-size:13px;font-weight:800;transition:background .2s,color .2s}
.opt .ck{position:absolute;right:14px;top:50%;width:22px;height:22px;margin-top:-11px;border-radius:50%;background:var(--c);color:#fff;display:grid;place-items:center;transform:scale(0);transition:transform .25s cubic-bezier(.3,1.6,.5,1)}
.opt .ck .ic{width:14px;height:14px;stroke-width:2.6}
.opt.sel{border-color:var(--c);background:#FFFAF6;font-weight:600}
.opt.sel .l{background:var(--c);color:#fff}
.opt.sel .ck{transform:scale(1)}
.qtip{margin-top:16px;text-align:center;font-size:12.5px;color:var(--sub)}
/* ---------- ③ 结果 ---------- */
#vResult{padding-top:6px}
.rcard{position:relative;overflow:hidden;padding:22px 20px 18px;border-radius:28px;background:linear-gradient(170deg,#FFE4D1 0%,#FFF4EB 44%,#fff 100%);box-shadow:0 8px 24px var(--c10);text-align:center}
.rcard .o1,.rcard .o2{position:absolute;border-radius:50%;pointer-events:none}
.rcard .o1{width:220px;height:220px;right:-80px;top:-60px;background:rgba(255,255,255,.55)}
.rcard .o2{width:140px;height:140px;left:-50px;top:150px;background:var(--c06)}
.rcard .top{position:relative;display:flex;justify-content:space-between;align-items:center;font-size:12px;line-height:24px}
.rcard .top b{padding:0 10px;border-radius:99px;background:#fff;color:var(--c);font-weight:700}
.rcard .top span{color:var(--sub)}
.rcard .ava{position:relative;width:172px;height:172px;margin:14px auto 0;border-radius:32px;overflow:hidden;border:5px solid #fff;box-shadow:0 8px 24px var(--c10)}
.rcard .ava img{width:100%;height:100%;object-fit:cover;object-position:center 30%}
.rcard .you{position:relative;margin-top:14px;font-size:13px;color:var(--sub);letter-spacing:2px}
.rcard h1{position:relative;font-size:28px;font-weight:800;line-height:1.3;color:var(--ink)}
.rcard .slo{position:relative;margin-top:6px;font-size:14.5px;color:var(--txt);line-height:1.6}
.rtags{position:relative;display:flex;justify-content:center;gap:8px;margin-top:14px}
.rtags span{height:30px;padding:0 12px;border-radius:99px;background:#fff;color:var(--c);font-size:13.5px;font-weight:700;line-height:30px;white-space:nowrap;box-shadow:0 2px 8px var(--c10)}
.dims{position:relative;display:flex;align-items:center;gap:12px;margin-top:18px;padding:14px 14px 14px 8px;border-radius:20px;background:rgba(255,255,255,.85);text-align:left}
.dims svg{flex:none;width:146px;height:128px}
.dl{flex:1;min-width:0;display:flex;flex-direction:column;gap:9px}
.dr{display:grid;grid-template-columns:1fr auto;align-items:center;row-gap:3px;font-size:12.5px;color:var(--txt);line-height:1.3}
.dr .p{font-weight:700;color:var(--ink)}
.dr .tr{grid-column:1/3;height:5px;border-radius:5px;background:#FFEDE1;overflow:hidden}
.dr .tr i{display:block;height:100%;width:0;border-radius:5px;background:#F9C29E;transition:width .8s cubic-bezier(.3,.7,.2,1)}
.dr.me{color:var(--c);font-weight:700}
.dr.me .p{color:var(--c)}
.dr.me .tr i{background:var(--c)}
.rcard .brand{position:relative;margin-top:14px;font-size:11.5px;color:var(--sub);letter-spacing:.5px}
.racts{display:flex;gap:10px;margin-top:16px}
.racts .btn{flex:1;font-size:15px}
.blk{margin-top:36px}
.read{padding:18px;border-radius:24px;background:var(--soft)}
.read p{font-size:15px;line-height:1.8;color:var(--txt)}
.read p+p{margin-top:10px}
.read b{color:var(--ink)}
.read q{quotes:"「" "」";color:var(--c);font-weight:700}
.tips{display:flex;flex-direction:column;gap:10px}
.tp{display:flex;gap:14px;align-items:flex-start;padding:14px 16px;border-radius:18px;background:#fff;border:1px solid var(--line)}
.tp .n{flex:none;width:30px;font-size:30px;font-weight:800;line-height:1;color:transparent;-webkit-text-stroke:1.4px var(--c);font-variant-numeric:tabular-nums}
.tp p{font-size:14.5px;line-height:1.65;color:var(--ink)}
.mate{display:flex;align-items:center;gap:14px;padding:14px 16px;border-radius:24px;background:linear-gradient(110deg,var(--cbg),#fff 80%)}
.mate img{flex:none;width:60px;height:60px;border-radius:50%;object-fit:cover;object-position:center 22%;border:3px solid #fff;box-shadow:0 4px 12px var(--c10)}
.mate small{display:block;font-size:12px;color:var(--sub);line-height:1.5}
.mate b{display:block;font-size:16px;color:var(--ink);line-height:1.4}
.mate p{margin-top:2px;font-size:13.5px;color:var(--txt);line-height:1.55}
#tools{margin-top:36px !important}
.again{margin-top:24px}
.foot{margin:28px 20px 0;font-size:12px;color:var(--sub);text-align:center}
.toast{position:fixed;left:50%;bottom:calc(80px + env(safe-area-inset-bottom));transform:translate(-50%,8px);max-width:300px;padding:10px 16px;border-radius:12px;background:rgba(31,35,41,.88);color:#fff;font-size:13.5px;line-height:1.6;text-align:center;opacity:0;pointer-events:none;transition:opacity .2s,transform .2s;z-index:60}
.toast.on{opacity:1;transform:translate(-50%,0)}
/* 保存结果卡弹层 */
.mask{position:fixed;inset:0;z-index:50;display:none;flex-direction:column;align-items:center;justify-content:center;padding:24px 28px calc(24px + env(safe-area-inset-bottom));background:rgba(40,22,10,.82)}
.mask.on{display:flex;animation:vin .25s ease both}
.mask img{max-width:100%;max-height:calc(100% - 96px);border-radius:16px;box-shadow:0 12px 32px rgba(0,0,0,.25);-webkit-touch-callout:default;user-select:auto}
.mask p{margin-top:14px;color:#fff;font-size:14.5px;font-weight:600;display:flex;align-items:center;gap:6px}
.mask .row{display:flex;gap:16px;margin-top:10px}
.mask .row button,.mask .row a{height:34px;padding:0 18px;border-radius:99px;border:1px solid rgba(255,255,255,.6);color:#fff;font-size:13.5px;line-height:32px;text-decoration:none}
.fade{opacity:0;transform:translateY(12px);transition:opacity .45s ease,transform .45s ease}
.fade.in{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){.fade,.stage,.view.on,.mask.on{opacity:1;transform:none;transition:none;animation:none}}
</style>
</head>
<body>
<!-- 单色线性图标(每题一个场景图标 q-*) -->
<svg class="hide" aria-hidden="true" xmlns="http://www.w3.org/2000/svg">
<symbol id="i-back" viewBox="0 0 24 24"><path d="M15 5l-7 7 7 7"/></symbol>
<symbol id="i-arrow" viewBox="0 0 24 24"><path d="M5 12h13M13 6.5l5.5 5.5-5.5 5.5"/></symbol>
<symbol id="i-check" viewBox="0 0 24 24"><path d="M5 12.5l4.5 4.5L19 7.5"/></symbol>
<symbol id="i-clock" viewBox="0 0 24 24"><circle cx="12" cy="12" r="8.5"/><path d="M12 7.5V12l3 2"/></symbol>
<symbol id="i-list" viewBox="0 0 24 24"><path d="M9 6.5h10M9 12h10M9 17.5h10M4.5 6.5h.01M4.5 12h.01M4.5 17.5h.01"/></symbol>
<symbol id="i-lock" viewBox="0 0 24 24"><rect x="5" y="10.5" width="14" height="10" rx="3"/><path d="M8.5 10.5V8a3.5 3.5 0 0 1 7 0v2.5"/></symbol>
<symbol id="i-down" viewBox="0 0 24 24"><path d="M12 4v11M7.5 11l4.5 4.5 4.5-4.5M5 19.5h14"/></symbol>
<symbol id="i-refresh" viewBox="0 0 24 24"><path d="M20 12a8 8 0 1 1-2.4-5.7M20 4v4.5h-4.5"/></symbol>
<symbol id="i-hand" viewBox="0 0 24 24"><path d="M9 11V5.5a1.5 1.5 0 0 1 3 0V10M12 9.5V4.5a1.5 1.5 0 0 1 3 0V10M15 9.5V6a1.5 1.5 0 0 1 3 0v8a6.5 6.5 0 0 1-6.5 6.5h-.6a6 6 0 0 1-4.6-2.2L4 15.5a1.6 1.6 0 0 1 2.4-2.1L9 15.5V11"/></symbol>
<symbol id="i-foot" viewBox="0 0 24 24"><path d="M12 9c3 0 4.6 2.7 4.6 6.3S14.8 22 12 22s-4.6-3.1-4.6-6.7S9 9 12 9z"/><circle cx="7.6" cy="6.6" r="1.6"/><circle cx="10.6" cy="4.4" r="1.75"/><circle cx="14" cy="4.6" r="1.6"/><circle cx="16.8" cy="6.8" r="1.35"/></symbol>
<!-- 题目场景 -->
<symbol id="q-test" viewBox="0 0 24 24"><rect x="9" y="2.5" width="6" height="19" rx="3"/><path d="M9 9h6M9 15.5h6M11 11.5v2M13 11.5v2"/></symbol>
<symbol id="q-board" viewBox="0 0 24 24"><rect x="5" y="4.5" width="14" height="17" rx="2.5"/><path d="M9 3h6v3H9zM8.5 11l1.5 1.5 3-3M8.5 16.5h7"/></symbol>
<symbol id="q-wait" viewBox="0 0 24 24"><path d="M7 3h10M7 21h10M8 3c0 4.5 4 5.5 4 9s-4 4.5-4 9M16 3c0 4.5-4 5.5-4 9s4 4.5 4 9M10 18.5h4"/></symbol>
<symbol id="q-moon" viewBox="0 0 24 24"><path d="M19.5 14.5A8 8 0 1 1 9.5 4.5a6.5 6.5 0 0 0 10 10z"/><path d="M16 4v3M14.5 5.5h3"/></symbol>
<symbol id="q-scale" viewBox="0 0 24 24"><rect x="3.5" y="4" width="17" height="16" rx="4"/><path d="M8 11a4 4 0 0 1 8 0M12 11l2-2.2"/></symbol>
<symbol id="q-phone" viewBox="0 0 24 24"><rect x="6" y="2.5" width="12" height="19" rx="3"/><path d="M10.5 18.5h3M12 7v4.5M12 14h.01"/></symbol>
<symbol id="q-bowl" viewBox="0 0 24 24"><path d="M3.5 11.5h17a8.5 8.5 0 0 1-17 0zM9 20h6M14 8.5l5-5M17 8.5l3-3"/></symbol>
<symbol id="q-pot" viewBox="0 0 24 24"><path d="M4.5 10h15v6a4.5 4.5 0 0 1-4.5 4.5H9A4.5 4.5 0 0 1 4.5 16zM2.5 12h2M19.5 12h2M9 3.5c-.8 1 .8 2 0 3M12 3c-.8 1 .8 2 0 3M15 3.5c-.8 1 .8 2 0 3"/></symbol>
<symbol id="q-rain" viewBox="0 0 24 24"><path d="M7 15.5a4 4 0 0 1-.4-8A5.5 5.5 0 0 1 17.2 8a3.8 3.8 0 0 1-.2 7.5z"/><path d="M8.5 18.5l-.8 2M12.5 18.5l-.8 2M16.5 18.5l-.8 2"/></symbol>
<symbol id="q-chat" viewBox="0 0 24 24"><path d="M4 5.5h11a2 2 0 0 1 2 2V13a2 2 0 0 1-2 2H9l-4 3.5V15H4a2 2 0 0 1-2-2V7.5a2 2 0 0 1 2-2z"/><path d="M17 9h3a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-1v2.5L16 18h-2"/></symbol>
<symbol id="q-heart" viewBox="0 0 24 24"><path d="M12 20s-7.5-4.6-7.5-10A4.3 4.3 0 0 1 12 7.5 4.3 4.3 0 0 1 19.5 10c0 5.4-7.5 10-7.5 10z"/></symbol>
<symbol id="q-family" viewBox="0 0 24 24"><circle cx="8" cy="7" r="2.8"/><circle cx="16.5" cy="8" r="2.3"/><path d="M3 20v-1.5A5 5 0 0 1 8 13.5a5 5 0 0 1 5 5V20M13.5 14.2a4.2 4.2 0 0 1 7 3.1V20"/></symbol>
<symbol id="q-bag" viewBox="0 0 24 24"><rect x="3.5" y="8" width="17" height="12.5" rx="3"/><path d="M8.5 8V6a3.5 3.5 0 0 1 7 0v2M3.5 13h17M11 13v2h2v-2"/></symbol>
<symbol id="q-cal" viewBox="0 0 24 24"><rect x="3.5" y="5" width="17" height="15.5" rx="3"/><path d="M3.5 10h17M8 3v4M16 3v4M14 15.2l1.4 1.4 2.6-2.6"/></symbol>
<symbol id="q-camera" viewBox="0 0 24 24"><path d="M4.5 7.5h3l1.5-2.5h6l1.5 2.5h3a2 2 0 0 1 2 2V18a2 2 0 0 1-2 2h-15a2 2 0 0 1-2-2V9.5a2 2 0 0 1 2-2z"/><circle cx="12" cy="13.5" r="3.5"/></symbol>
<symbol id="q-baby" viewBox="0 0 24 24"><circle cx="12" cy="12.5" r="8.5"/><path d="M9.2 11.2h.01M14.8 11.2h.01M10 16a2.6 2.6 0 0 1 4 0M12 4c-1.2 0-1.6 1.2-.8 2"/></symbol>
</svg>
<div id="scroll">
<header class="bar" id="bar">
<button class="back" id="back" aria-label="返回"><svg class="ic"><use href="#i-back" xlink:href="#i-back"/></svg></button>
<span class="t">孕期专题</span>
</header>
<!-- ① 开始 -->
<main class="view" id="vStart">
<section class="hero">
<i class="o1"></i><i class="o2"></i>
<span class="eb">孕期趣味测试 · DAD TYPE</span>
<h1>测一测<br>你家准爸爸是<br><mark>哪种队友</mark>?</h1>
<div class="meta">
<span><svg class="ic"><use href="#i-list" xlink:href="#i-list"/></svg><b class="num">12</b>题 · 约<b class="num">2</b>分钟</span>
<span><svg class="ic"><use href="#i-lock" xlink:href="#i-lock"/></svg>只在本机算,不上传</span>
<span id="tested" hidden><svg class="ic"><use href="#q-heart" xlink:href="#q-heart"/></svg>已有<b class="num" id="testedN"></b>位妈妈测过</span>
</div>
<img class="pic" src="img/hero.webp" alt="准爸爸陪着孕妈,手轻轻放在肚子上">
</section>
<div class="wrap">
<section class="types fade">
<div class="sh2"><i>4 TYPES</i><b>4 种队友,他是哪一种?</b></div>
<div class="tgrid" id="tgrid"></div>
</section>
<div class="startbox fade">
<button class="btn pri" id="startBtn">开始测试<svg class="ic"><use href="#i-arrow" xlink:href="#i-arrow"/></svg></button>
<p class="note">由妈妈来答:想想他平时的样子,凭第一感觉选</p>
</div>
</div>
</main>
<!-- ② 答题 -->
<main class="view wrap" id="vQuiz">
<div class="qtop">
<button id="prevBtn"><svg class="ic"><use href="#i-back" xlink:href="#i-back"/></svg>上一题</button>
<span class="no num"><b id="qNo">1</b> / <span id="qTotal">12</span></span>
</div>
<div class="feet" id="feet" aria-hidden="true"></div>
<div class="stage" id="stage">
<div class="qcard">
<div class="hd">
<span class="qi"><svg class="ic"><use id="qIc" href="#q-test" xlink:href="#q-test"/></svg></span>
<span class="cat" id="qCat"></span>
</div>
<h2 id="qTitle"></h2>
</div>
<div class="opts" id="qOpts"></div>
</div>
<p class="qtip">选完自动进入下一题</p>
</main>
<!-- ③ 结果 -->
<main class="view wrap" id="vResult">
<article class="rcard" id="rCard">
<i class="o1"></i><i class="o2"></i>
<div class="top"><b>我家队友类型卡</b><span id="rLast"></span></div>
<div class="ava"><img id="rImg" src="" alt=""></div>
<p class="you">我家准爸爸是</p>
<h1><mark id="rName"></mark></h1>
<p class="slo" id="rLine"></p>
<div class="rtags" id="rTags"></div>
<div class="dims">
<svg id="rRadar" viewBox="-16 -2 168 146" role="img" aria-label="4 个维度占比雷达图"></svg>
<div class="dl" id="rDims"></div>
</div>
<p class="brand">兜爸心选 · 孕期专题 · 你家准爸爸是哪种队友</p>
</article>
<div class="racts">
<button class="btn pri" id="saveBtn"><svg class="ic"><use href="#i-down" xlink:href="#i-down"/></svg>保存结果卡</button>
</div>
<section class="blk fade">
<div class="sh2"><i>01</i><b>他是这样的队友</b></div>
<div class="read" id="rRead"></div>
</section>
<section class="blk fade">
<div class="sh2"><i>02</i><b>可能的小盲区</b></div>
<div class="read" id="rBlind"></div>
</section>
<section class="blk fade">
<div class="sh2"><i>03</i><b>给你的沟通小建议</b></div>
<div class="tips" id="rTips"></div>
</section>
<section class="blk fade">
<div class="sh2"><i>04</i><b>可以转给他看的一句话</b></div>
<div class="mate" id="rMate"></div>
</section>
<div id="tools" class="fade"></div>
<button class="btn sec again" id="againBtn"><svg class="ic"><use href="#i-refresh" xlink:href="#i-refresh"/></svg>重新测试</button>
</main>
<p class="foot">趣味测试,仅供娱乐;每位准爸爸都在学着当爸爸</p>
</div>
<div class="mask" id="mask">
<img id="maskImg" alt="我家队友类型卡">
<p><svg class="ic"><use href="#i-hand" xlink:href="#i-hand"/></svg>长按图片,保存到相册</p>
<div class="row"><a id="dlBtn" download="队友类型卡.png" hidden>下载图片</a><button id="maskClose">关闭</button></div>
</div>
<div class="toast" id="toast"></div>
<script src="../_shared/tools.js"></script>
<script>
(function () {
'use strict';
var $ = function (s) { return document.querySelector(s); };
var sc = $('#scroll');
var KEY = 'mmbox.duiyou.v1';
var TESTED_COUNT = 0; /* 「已有 N 位妈妈测过」:只有接上真实统计后才填,0 = 不显示(不造数字) */
var XL = 'http://www.w3.org/1999/xlink';
function useRef(el, id) { el.setAttribute('href', '#' + id); el.setAttributeNS(XL, 'xlink:href', '#' + id); }
function esc(s) { return String(s).replace(/[&<>"]/g, function (c) { return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;' }[c]; }); }
var openid = (function () {
var m = (location.hash + '&' + location.search).match(/[#?&]openid=([^&#]+)/);
return m ? decodeURIComponent(m[1]) : '';
})();
/* 返回:从首页点进来就 back;直接打开(分享 / 刷新)就回同目录的首页,身份 hash 原样带回 */
$('#back').addEventListener('click', function () {
if (document.referrer && document.referrer.indexOf(location.host) >= 0 && history.length > 1) history.back();
else location.href = '../../' + location.search + location.hash;
});
sc.addEventListener('scroll', function () { $('#bar').classList.toggle('sh', sc.scrollTop > 4); }, { passive: true });
/* ================= 4 个维度 = 4 种队友类型 =================
* ORDER 顺序 = 雷达图顺时针(上/右/下/左)。
* dim:维度名;good:闪光点;blind:可能的小盲区;low:他在某维度占比最低时给的一句(落在「小盲区」里);
* tips:给妈妈的沟通小建议(3 条);toHim:可以转给他看的一句话;tools:适合两人一起用的工具。
* 语气:温柔、有趣、不说教、不制造对立 —— 每一型都是「好队友」,只是方式不同。 */
var TYPES = {
guan: { name: '贴身管家型', dim: '生活照料', ax: '照料', img: 'img/guan.webp', alt: '准爸爸给孕妈垫靠枕、端来热汤',
line: '你刚皱眉,温水已经递到手边', tags: ['手脚勤快', '细节控', '行动派'],
desc: '他的爱都落在具体的事上:吃的、穿的、靠的、带的,样样提前替你想到。',
good: '靠谱、踏实、执行力强,有他在,生活上的小麻烦基本轮不到你操心。',
blind: '忙着把事情做好,偶尔会忘了停下来问一句「你心里怎么样」;也容易什么都自己揽,把自己累坏了还不说。',
side: '他也在用自己的方式靠近你。',
low: '可以拉他一起做做这件事,让他知道你同样需要。',
tips: ['他做了什么,具体夸出来:「今天那碗汤刚刚好」,比一句「辛苦了」更能让他开心。', '想被陪的时候直接说「今晚不用收拾,陪我坐会儿」,他会很乐意把手里的活放下。', '家务可以分一点出去,或者轮流来,别让他一个人扛成「全能管家」。'],
toHim: '谢谢你把日子照顾得这么妥帖。偶尔也停下来抱抱我,你不用什么都做完,我一样很安心。',
tools: [
{ id: 'daichanqingdan', why: '待产包交给他打勾,一样不落' },
{ id: 'yunqinengbuchi', why: '给你做饭前先查一查能不能吃' },
{ id: 'chanjianrili', why: '产检日子同步给他,提前请好假' } ] },
xue: { name: '学霸攻略型', dim: '做功课', ax: '功课', img: 'img/xue.webp', alt: '准爸爸戴着眼镜认真看孕育书做笔记',
line: '孕期知识他比你还熟,攻略做了一大本', tags: ['爱学习', '有规划', '遇事冷静'],
desc: '遇到新情况,他第一反应是查资料、问医生、排计划,把未知变成心里有数。',
good: '冷静、可靠、会找靠谱信息,关键时刻他是那个不慌的人。',
blind: '有时太讲道理:你只想被抱一下,他在给你讲激素原理;资料看多了,也可能自己偷偷焦虑。',
side: '他理性的外壳下,藏着不少柔软。',
low: '可以邀请他一起,他学得快,一点就通。',
tips: ['想被安慰时先说一句「现在不用分析,抱抱我就好」,他会立刻切换模式。', '把他做的功课变成两个人的事:一起看产检报告、一起上孕妇课,他会很有成就感。', '他转来的科普看到有用的就回个「学到了」,这是他最喜欢的反馈。'],
toHim: '你查的每一份资料我都看到了,有你在我很踏实。有时候我不需要答案,只需要你在旁边。',
tools: [
{ id: 'chanjianrili', why: '产检节点一次排好,他最爱' },
{ id: 'yunqitizhong', why: '体重曲线一起看,涨多涨少有数' },
{ id: 'taierguzhong', why: '对照 B 超数据,看宝宝长得好不好' } ] },
nuan: { name: '暖心陪伴型', dim: '情绪陪伴', ax: '陪伴', img: 'img/nuan.webp', alt: '准爸爸搂着孕妈,靠在窗边',
line: '他未必样样精通,但总在你身边', tags: ['会倾听', '情绪稳定', '有仪式感'],
desc: '你开心时他陪着笑,低落时他先抱抱你,情绪价值一直在线。',
good: '温柔、耐心、共情力强,跟他在一起,再难熬的孕期也有人一起扛。',
blind: '情绪上永远在线,具体事务偶尔要你提醒;遇到要拍板的事,他可能更习惯听你的。',
side: '温柔之外,他也有能干的一面。',
low: '可以交给他一两件具体的小任务,他会做得很用心。',
tips: ['具体的事直接点名:「周六你负责把待产包装好」,清楚的任务他会做得很好。', '他的陪伴别当成理所当然,偶尔说一句「有你在真好」,他能开心一整天。', '他也会累、也会紧张,找个晚上换你听他说说心里话。'],
toHim: '谢谢你一直陪着我,每次难受的时候有你在,就没那么难了。我们一起,慢慢等宝宝来。',
tools: [
{ id: 'taidong', why: '睡前一起数胎动,跟宝宝打招呼' },
{ id: 'yundujinian', why: '孕肚照存起来,以后给宝宝看' },
{ id: 'chanjianrili', why: '产检日子提醒他,一起去' } ] },
man: { name: '慢热成长型', dim: '慢慢成长', ax: '成长', img: 'img/man.webp', alt: '准爸爸坐在地上认真组装婴儿床',
line: '入戏慢一点,但每一步都在追上来', tags: ['潜力股', '肯学', '越来越好'],
desc: '他还在慢慢找「当爸爸」的感觉,但你说的每件事,他都放在心上、认真去做。',
good: '真诚、肯学、不装懂,教一次就会,而且一次比一次熟练。',
blind: '很多准爸爸的「爸爸感」要到看见宝宝才真正到来,所以他现在可能还没意识到你需要什么,不是不在乎。',
side: '他已经在悄悄进步了。',
low: '可以带着他做一次,他会记住的。',
tips: ['需要什么就说具体:「半夜我吐的时候,帮我倒杯温水」比「你多关心我」好接得多。', '带他去一次产检、摸一次胎动,让他亲眼看见宝宝,「爸爸感」会来得快很多。', '他每进步一点就夸一点,你的肯定是他最好的加速器。'],
toHim: '我知道你在认真学着当爸爸,慢一点没关系,我们都是第一次。你每一点进步我都看得见。',
tools: [
{ id: 'taidong', why: '让他摸一摸,亲身感受宝宝在动' },
{ id: 'daichanqingdan', why: '照着清单买,新手也不会漏' },
{ id: 'chanjianrili', why: '产检提醒同步给他,一起去' } ] }
};
var ORDER = ['guan', 'xue', 'nuan', 'man'];
/* ================= 12 道题 · 计分表 =================
* 孕妈来答,描述准爸爸的表现。每个选项 = [维度, 文案],选中即该维度 +1,共 12 分;选项顺序已人工打散。
* c:题目所属场景(解读里引用);s:场景短语(「说到 X,你选了…」);ic:题目场景图标。 */
var QS = [
{ c: '身体与产检', ic: 'q-board', s: '陪你产检', q: '要去做产检的那天,他通常是?', o: [
['guan', '提前排好号,水和小零食都备好'], ['xue', '带着问题清单,比你还认真听'], ['nuan', '一路牵着你,等结果时陪你聊天'], ['man', '请好假跟着去,边走流程边学'] ] },
{ c: '身体与产检', ic: 'q-moon', s: '半夜孕吐', q: '半夜你吐得难受,他会?', o: [
['nuan', '坐起来拍拍背,陪你到缓过来'], ['guan', '马上端温水、递纸巾、收拾干净'], ['man', '被你叫醒,赶紧问「我能做点啥」'], ['xue', '第二天查好缓解孕吐的办法发给你'] ] },
{ c: '待产准备', ic: 'q-bag', s: '准备待产包', q: '说到准备待产包,他的风格是?', o: [
['xue', '对比好几份清单,整理成表格'], ['man', '你列好清单,他照着一样样买齐'], ['nuan', '陪你逛母婴店,挑小衣服挑到傻笑'], ['guan', '默默打包好,连你的发圈都放了'] ] },
{ c: '情绪与家人', ic: 'q-family', s: '长辈意见和你不一样', q: '长辈坚持「孕妇不能 XX」,和你想法不一样时,他会?', o: [
['nuan', '先站你这边,再私下跟长辈聊'], ['xue', '翻出科普资料,耐心跟长辈解释'], ['guan', '两边照顾,把长辈心意换个方式办'], ['man', '一开始有点懵,你提一句就去沟通'] ] },
{ c: '感受宝宝', ic: 'q-baby', s: '第一次叫他摸胎动', q: '第一次感觉到胎动,叫他来摸,他?', o: [
['man', '摸了半天没感觉,下次还主动来等'], ['nuan', '把脸贴在肚子上,跟宝宝说悄悄话'], ['guan', '先扶你躺舒服,垫好靠枕一起等'], ['xue', '问你几点动的、动了几下,记下来'] ] },
{ c: '情绪与家人', ic: 'q-rain', s: '你莫名低落', q: '你莫名低落、想哭的时候,他会?', o: [
['guan', '出门买回你最想吃的那一口'], ['xue', '告诉你激素波动很正常,帮你理理'], ['nuan', '什么也不说,先抱抱你,听你讲'], ['man', '有点手足无措,但会笨笨地逗你笑'] ] },
{ c: '日常生活', ic: 'q-pot', s: '孕期的家务', q: '怀孕以后,家里的家务?', o: [
['guan', '基本被他包了,做饭拖地样样来'], ['nuan', '做完饭还会陪你散步消消食'], ['man', '你说一声就去做,越来越不用提醒'], ['xue', '列了张「孕妇别碰」家务清单'] ] },
{ c: '日常生活', ic: 'q-phone', s: '孕期知识', q: '关于孕期知识,他平时?', o: [
['xue', '关注好几个科普号,随时划重点'], ['man', '你转给他的文章,会点开认真看完'], ['guan', '研究孕妇餐,变着花样给你做饭'], ['nuan', '每晚睡前给宝宝讲故事、放音乐'] ] },
{ c: '身体与产检', ic: 'q-heart', s: '腰酸、半夜腿抽筋', q: '你腰酸背痛、半夜腿抽筋时,他?', o: [
['nuan', '边按边陪你聊天,直到你睡着'], ['man', '一开始不会按,看了视频学着来'], ['xue', '查清原因,提醒你补钙、睡前拉伸'], ['guan', '二话不说起来,帮你揉腿、热敷'] ] },
{ c: '感受宝宝', ic: 'q-chat', s: '给宝宝起名字', q: '聊到给宝宝起名字,他?', o: [
['xue', '查字典、看寓意,列了候选名单'], ['guan', '名字交给你,他先把月子安排好'], ['man', '嘴上说「还早」,偷偷想了好几个'], ['nuan', '起了一堆小名,每个都很有爱'] ] },
{ c: '待产准备', ic: 'q-cal', s: '离预产期还剩一个月', q: '离预产期还剩一个月,他在?', o: [
['man', '「爸爸感」上线,追着问要准备啥'], ['guan', '待产包放门口,车加满油随时出发'], ['nuan', '每天准时回家,说要多陪陪你们'], ['xue', '踩点去医院的路线,摸清入院流程'] ] },
{ c: '日常生活', ic: 'q-camera', s: '难得的周末', q: '难得的周末,他最可能?', o: [
['nuan', '陪你拍孕肚照,说要留给宝宝看'], ['xue', '拉你一起上孕妇学校的课'], ['man', '被喊去装婴儿床,装完超有成就感'], ['guan', '大扫除,再给你做一桌好菜'] ] }
];
$('#qTotal').textContent = QS.length;
/* 开始页:4 种类型小卡 + 测过人数(仅真实数据) */
$('#tgrid').innerHTML = ORDER.map(function (k) {
var t = TYPES[k];
return '<div class="tcard"><img src="' + t.img + '" alt=""><span><b>' + t.name + '</b><small>' + t.tags[0] + '</small></span></div>';
}).join('');
if (TESTED_COUNT > 0) { $('#testedN').textContent = TESTED_COUNT.toLocaleString('zh-CN'); $('#tested').hidden = false; }
/* 进场动画:按顺序 60ms 错开 */
var views = { start: $('#vStart'), quiz: $('#vQuiz'), result: $('#vResult') };
var io = 'IntersectionObserver' in window ? new IntersectionObserver(function (es) {
var n = 0;
es.forEach(function (e) {
if (!e.isIntersecting) return;
var el = e.target; io.unobserve(el);
setTimeout(function () { el.classList.add('in'); }, 60 * n++);
});
}, { root: sc, threshold: .08 }) : null;
/* 11-03 用户:「重新测试后退回首页,再进来还是结果页」→ 记住最后停在哪(开始 / 第几题 / 结果),再进来回到那里 */
function pos(v) {
if (v) pos.v = v;
try { localStorage.setItem(KEY + '.pos', JSON.stringify({ v: pos.v, cur: cur, ans: ans })); } catch (e) {}
}
function resume() {
var p = null; try { p = JSON.parse(localStorage.getItem(KEY + '.pos') || 'null'); } catch (e) {}
if (!p) return false; /* 旧用户没有记录:照原来的(有结果看结果) */
if (p.v === 'start') { show('start'); return true; }
if (p.v === 'quiz' && Array.isArray(p.ans)) { cur = Math.max(0, Math.min(+p.cur || 0, QS.length - 1)); ans = p.ans.slice(0, QS.length); paint(); show('quiz'); return true; }
return false;
}
function show(name) {
pos(name);
Object.keys(views).forEach(function (k) { views[k].classList.toggle('on', k === name); });
sc.scrollTop = 0;
[].forEach.call(views[name].querySelectorAll('.fade'), function (el) {
el.classList.remove('in');
if (io) { io.unobserve(el); io.observe(el); } else el.classList.add('in');
});
}
/* ================= 答题 ================= */
var cur = 0, ans = [], busy = false;
var stage = $('#stage');
$('#feet').innerHTML = QS.map(function () { return '<svg viewBox="0 0 24 24"><use href="#i-foot" xlink:href="#i-foot"/></svg>'; }).join('');
var feet = document.querySelectorAll('#feet svg');
function paint() {
var q = QS[cur];
$('#qNo').textContent = cur + 1;
[].forEach.call(feet, function (f, i) { f.setAttribute('class', i < cur ? 'done' : i === cur ? 'cur' : ''); });
useRef($('#qIc'), q.ic);
$('#qCat').textContent = q.c;
$('#qTitle').textContent = q.q;
$('#qOpts').innerHTML = q.o.map(function (o, i) {
return '<button class="opt' + (ans[cur] === i ? ' sel' : '') + '" data-i="' + i + '"><span class="l">' + 'ABCD'[i] + '</span><span>' + esc(o[1]) +
'</span><span class="ck"><svg class="ic"><use href="#i-check" xlink:href="#i-check"/></svg></span></button>';
}).join('');
$('#prevBtn').disabled = cur === 0;
if (pos.v === 'quiz') pos();
}
/* 左右滑动:前进 → 当前向左滑出、新题从右滑入;上一题反过来 */
function swap(dir, after) {
busy = true;
stage.classList.add(dir > 0 ? 'outL' : 'outR');
setTimeout(function () {
after();
stage.classList.remove('outL', 'outR');
stage.classList.add(dir > 0 ? 'inR' : 'inL');
void stage.offsetWidth;
stage.classList.remove('inR', 'inL');
setTimeout(function () { busy = false; }, 220);
}, 220);
}
$('#qOpts').addEventListener('click', function (e) {
var b = e.target.closest('.opt'); if (!b || busy) return;
busy = true;
ans[cur] = +b.dataset.i;
[].forEach.call(document.querySelectorAll('#qOpts .opt'), function (x) { x.classList.toggle('sel', x === b); });
setTimeout(function () {
if (cur < QS.length - 1) swap(1, function () { cur++; paint(); });
else { busy = false; finish(); }
}, 380);
});
$('#prevBtn').addEventListener('click', function () {
if (busy || cur === 0) return;
swap(-1, function () { cur--; paint(); });
});
function startQuiz() {
cur = 0; ans = []; busy = false;
stage.classList.remove('outL', 'outR', 'inL', 'inR');
paint();
show('quiz');
}
$('#startBtn').addEventListener('click', startQuiz);
$('#againBtn').addEventListener('click', startQuiz);
/* ================= 计分 ================= */
function score(answers) {
var s = { guan: 0, xue: 0, nuan: 0, man: 0 };
answers.forEach(function (i, qi) { s[QS[qi].o[i][0]]++; });
/* 最高分为主类型;并列时取「最近一次选过」的那个(越靠后的题越接近真实状态) */
var max = Math.max.apply(null, ORDER.map(function (k) { return s[k]; }));
var tied = ORDER.filter(function (k) { return s[k] === max; });
var top = tied[0];
if (tied.length > 1) for (var qi = answers.length - 1; qi >= 0; qi--) {
var t = QS[qi].o[answers[qi]][0];
if (tied.indexOf(t) >= 0) { top = t; break; }
}
return { s: s, top: top };
}
function pcts(s, top) {
var total = 0; ORDER.forEach(function (k) { total += s[k]; }); total = total || 1;
var p = {}; ORDER.forEach(function (k) { p[k] = Math.round(s[k] / total * 100); });
var diff = 100; ORDER.forEach(function (k) { diff -= p[k]; });
p[top] += diff; /* 四舍五入补差,合计 100% */
return p;
}
function finish() {
var r = score(ans);
var rec = { type: r.top, scores: r.s, ans: ans.slice(), at: Date.now() };
try { localStorage.setItem(KEY, JSON.stringify(rec)); } catch (e) {}
render(rec, false);
}
/* ================= 解读:引用作答 ================= */
function reading(rec, p) {
var t = TYPES[rec.type], a = rec.ans;
var picks = function (k) { var r = []; a.forEach(function (i, qi) { if (QS[qi].o[i][0] === k) r.push(qi); }); return r; };
var mine = picks(rec.type);
/* 主类型最集中的场景 */
var byCat = {};
QS.forEach(function (q, qi) { var c = byCat[q.c] || (byCat[q.c] = { n: 0, hit: [] }); c.n++; if (QS[qi].o[a[qi]][0] === rec.type) c.hit.push(qi); });
var best = null;
Object.keys(byCat).forEach(function (c) {
var x = byCat[c]; if (!x.hit.length) return;
var sc_ = x.hit.length / x.n + x.hit.length * .01;
if (!best || sc_ > best.sc) best = { c: c, sc: sc_, x: x };
});
var ex = QS[best.x.hit[best.x.hit.length - 1]];
var exOpt = ex.o[a[QS.indexOf(ex)]][1];
var N = QS.length;
var html = '<p>' + N + ' 道题里,你有 <b class="num">' + mine.length + '</b> 次选了「' + t.dim + '」的答案。' + esc(t.desc) + '</p>';
html += '<p>' + (best.x.n === 1 ? '比如在「' + best.c + '」这道题里' : best.x.hit.length === best.x.n ? '在「' + best.c + '」的 ' + best.x.n + ' 道题里,你每次都这样选' : '尤其在「' + best.c + '」的题里,你 ' + best.x.n + ' 次有 ' + best.x.hit.length + ' 次这样选') +
(best.x.n === 1 ? ':说到' : ':比如说到') + ex.s + ',你选了<q>' + esc(exOpt) + '</q>。</p>';
html += '<p><b>他的闪光点:</b>' + esc(t.good) + '</p>';
/* 第二维度 */
var rest = ORDER.filter(function (k) { return k !== rec.type; }).sort(function (x, y) { return rec.scores[y] - rec.scores[x]; });
var sec = rest[0];
if (rec.scores[sec] > 0) {
var sp = picks(sec), sq = QS[sp[sp.length - 1]];
html += '<p>他的另一面是「' + TYPES[sec].dim + '」(<span class="num">' + p[sec] + '%</span>):说到' + sq.s + ',你选了<q>' + esc(sq.o[a[QS.indexOf(sq)]][1]) + '</q>,' + TYPES[sec].side + '</p>';
} else {
html += '<p>' + N + ' 道题你全选了同一类,他是非常纯粹的' + t.name + '队友。</p>';
}
return html;
}
function blind(rec, p) {
var t = TYPES[rec.type];
var low = ORDER.filter(function (k) { return k !== rec.type; }).sort(function (x, y) { return rec.scores[x] - rec.scores[y]; })[0];
return '<p>' + esc(t.blind) + '</p><p>「' + TYPES[low].dim + '」在他身上目前只占 <span class="num">' + p[low] + '%</span>,' + TYPES[low].low + '</p>';
}
/* ================= 雷达图(SVG 手写,单系列) ================= */
function radarPts(p, cx, cy, R, M) {
/* 上、右、下、左 */
var d = [[0, -1], [1, 0], [0, 1], [-1, 0]];
return ORDER.map(function (k, i) { var r = Math.max(p[k] / M, .06) * R; return [cx + d[i][0] * r, cy + d[i][1] * r]; });
}
function radarScale(p) { var m = 0; ORDER.forEach(function (k) { m = Math.max(m, p[k]); }); return Math.max(50, Math.ceil(m / 10) * 10); }
function radarSVG(p, top) {
var cx = 68, cy = 68, R = 44, M = radarScale(p), g = '';
[1 / 3, 2 / 3, 1].forEach(function (f) {
var r = R * f; g += '<polygon points="' + [cx, cy - r, cx + r, cy, cx, cy + r, cx - r, cy].join(',') + '" fill="none" stroke="#FCD9C2" stroke-width="1"/>';
});
g += '<path d="M' + cx + ' ' + (cy - R) + 'V' + (cy + R) + 'M' + (cx - R) + ' ' + cy + 'H' + (cx + R) + '" stroke="#FCD9C2" stroke-width="1"/>';
var pts = radarPts(p, cx, cy, R, M);
g += '<polygon points="' + pts.map(function (x) { return x.join(','); }).join(' ') + '" fill="rgba(242,123,53,.18)" stroke="#F27B35" stroke-width="2" stroke-linejoin="round"/>';
pts.forEach(function (x, i) { g += '<circle cx="' + x[0] + '" cy="' + x[1] + '" r="' + (ORDER[i] === top ? 4.5 : 3.2) + '" fill="#F27B35" stroke="#fff" stroke-width="1.5"/>'; });
var L = [[cx, 12, 'middle'], [cx + R + 6, cy + 4, 'start'], [cx, cy + R + 18, 'middle'], [cx - R - 6, cy + 4, 'end']];
ORDER.forEach(function (k, i) {
g += '<text x="' + L[i][0] + '" y="' + L[i][1] + '" text-anchor="' + L[i][2] + '" font-size="11" font-weight="' + (k === top ? 800 : 500) + '" fill="' + (k === top ? '#F27B35' : '#86909C') + '">' + TYPES[k].ax + '</text>';
});
return g;
}
/* ================= 渲染结果 ================= */
var curRec = null, curP = null, wk = 0;
function render(rec, fromCache) {
var t = TYPES[rec.type], p = pcts(rec.scores, rec.type);
curRec = rec; curP = p;
$('#rImg').src = t.img; $('#rImg').alt = t.alt;
$('#rName').textContent = t.name + '爸爸';
$('#rLine').textContent = t.line;
var d = new Date(rec.at || Date.now());
$('#rLast').textContent = (fromCache ? '上次测试 · ' : '') + (d.getMonth() + 1) + '月' + d.getDate() + '日';
$('#rTags').innerHTML = t.tags.map(function (a) { return '<span>' + esc(a) + '</span>'; }).join('');
$('#rRadar').innerHTML = radarSVG(p, rec.type);
var sorted = ORDER.slice().sort(function (x, y) { return (y === rec.type) - (x === rec.type) || p[y] - p[x]; });
$('#rDims').innerHTML = sorted.map(function (k) {
return '<div class="dr' + (k === rec.type ? ' me' : '') + '"><span>' + TYPES[k].dim + '</span><span class="p num">' + p[k] + '%</span><span class="tr"><i data-w="' + p[k] + '"></i></span></div>';
}).join('');
$('#rRead').innerHTML = reading(rec, p);
$('#rBlind').innerHTML = blind(rec, p);
$('#rTips').innerHTML = t.tips.map(function (x, i) { return '<div class="tp"><span class="n">' + (i + 1) + '</span><p>' + esc(x) + '</p></div>'; }).join('');
$('#rMate').innerHTML = '<img src="' + t.img + '" alt=""><span><small>截图或念给他听,都可以</small><b>致' + t.name + '的你</b><p>' + esc(t.toHim) + '</p></span>';
renderTools();
show('result');
setTimeout(function () { [].forEach.call(document.querySelectorAll('#rDims i'), function (b) { b.style.width = b.dataset.w + '%'; }); }, 250);
}
function renderTools() {
if (!curRec || !window.TopicTools) return;
var el = $('#tools'); el.className = 'fade in';
TopicTools.render(el, TYPES[curRec.type].tools, { title: '适合和他一起用', color: '#F27B35', bg: '#FFF1E6', wk: wk });
}
/* 孕周:只用来给推荐工具打「孕N周开放」标签 */
if (openid) {
fetch('/api/mp/public/mama-box/pregnancy?openid=' + encodeURIComponent(openid))
.then(function (r) { return r.ok ? r.json() : null; })
.then(function (j) {
var p = j && j.code === 200 && j.result;
if (p && !p.postpartum && !p.empty && p.week != null) { wk = +p.week || 0; renderTools(); }
}).catch(function () {});
}
/* ================= 提示(用户要求结果页不放「复制发给 xx」类按钮) ================= */
var tt;
function toast(msg) {
var el = $('#toast'); el.textContent = msg; el.classList.add('on');
clearTimeout(tt); tt = setTimeout(function () { el.classList.remove('on'); }, 2400);
}
/* ================= 保存结果卡:canvas 画图 → <img> 长按保存 ================= */
var FONT = '-apple-system,BlinkMacSystemFont,"PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif';
function rr(ctx, x, y, w, h, r) {
ctx.beginPath(); ctx.moveTo(x + r, y); ctx.arcTo(x + w, y, x + w, y + h, r); ctx.arcTo(x + w, y + h, x, y + h, r);
ctx.arcTo(x, y + h, x, y, r); ctx.arcTo(x, y, x + w, y, r); ctx.closePath();
}
function loadImg(src) { return new Promise(function (ok, no) { var im = new Image(); im.onload = function () { ok(im); }; im.onerror = no; im.src = src; }); }
function drawCard(im) {
var t = TYPES[curRec.type], p = curP, W = 750, H = 1200;
var cv = document.createElement('canvas'); cv.width = W; cv.height = H;
var ctx = cv.getContext('2d');
var g = ctx.createLinearGradient(0, 0, W * .3, H);
g.addColorStop(0, '#FFE4D1'); g.addColorStop(.45, '#FFF4EB'); g.addColorStop(1, '#FFFFFF');
ctx.fillStyle = g; ctx.fillRect(0, 0, W, H);
ctx.fillStyle = 'rgba(255,255,255,.55)'; ctx.beginPath(); ctx.arc(660, 90, 230, 0, 7); ctx.fill();
ctx.fillStyle = 'rgba(242,123,53,.06)'; ctx.beginPath(); ctx.arc(40, 470, 150, 0, 7); ctx.fill();
ctx.textAlign = 'center'; ctx.textBaseline = 'alphabetic';
/* 顶部胶囊 */
ctx.font = '700 24px ' + FONT;
var lb = '我家队友类型卡', lw = ctx.measureText(lb).width + 44;
ctx.fillStyle = '#fff'; rr(ctx, (W - lw) / 2, 52, lw, 48, 24); ctx.fill();
ctx.fillStyle = '#F27B35'; ctx.fillText(lb, W / 2, 84);
/* 插画 */
var S = 320, ix = (W - S) / 2, iy = 132;
ctx.save(); ctx.shadowColor = 'rgba(242,123,53,.18)'; ctx.shadowBlur = 36; ctx.shadowOffsetY = 12;
ctx.fillStyle = '#fff'; rr(ctx, ix - 10, iy - 10, S + 20, S + 20, 60); ctx.fill(); ctx.restore();
ctx.save(); rr(ctx, ix, iy, S, S, 52); ctx.clip();
var sw = im.naturalWidth, sh = im.naturalHeight, side = Math.min(sw, sh);
ctx.drawImage(im, (sw - side) / 2, (sh - side) * .3, side, side, ix, iy, S, S); ctx.restore();
/* 类型名 */
ctx.fillStyle = '#86909C'; ctx.font = '400 26px ' + FONT; ctx.fillText('我家准爸爸是', W / 2, 520);
ctx.font = '800 60px ' + FONT;
var nm = t.name + '爸爸', nw = ctx.measureText(nm).width;
ctx.fillStyle = 'rgba(242,123,53,.20)'; ctx.fillRect((W - nw) / 2 - 4, 566, nw + 8, 24);
ctx.fillStyle = '#1F2329'; ctx.fillText(nm, W / 2, 588);
ctx.fillStyle = '#4E5969'; ctx.font = '400 28px ' + FONT; ctx.fillText(t.line, W / 2, 640);
/* 关键词 */
ctx.font = '700 26px ' + FONT;
var ws = t.tags.map(function (s) { return ctx.measureText(s).width + 44; }), gap = 16;
var tx = (W - ws.reduce(function (a, b) { return a + b; }, 0) - gap * 2) / 2;
t.tags.forEach(function (s, i) {
ctx.save(); ctx.shadowColor = 'rgba(242,123,53,.12)'; ctx.shadowBlur = 14; ctx.shadowOffsetY = 4;
ctx.fillStyle = '#fff'; rr(ctx, tx, 680, ws[i], 56, 28); ctx.fill(); ctx.restore();
ctx.fillStyle = '#F27B35'; ctx.fillText(s, tx + ws[i] / 2, 717); tx += ws[i] + gap;
});
/* 维度面板 */
ctx.fillStyle = 'rgba(255,255,255,.9)'; rr(ctx, 40, 776, 670, 300, 36); ctx.fill();
var cx = 205, cy = 926, R = 88, M = radarScale(p);
ctx.strokeStyle = '#FCD9C2'; ctx.lineWidth = 2;
[1 / 3, 2 / 3, 1].forEach(function (f) { var r = R * f; ctx.beginPath(); ctx.moveTo(cx, cy - r); ctx.lineTo(cx + r, cy); ctx.lineTo(cx, cy + r); ctx.lineTo(cx - r, cy); ctx.closePath(); ctx.stroke(); });
ctx.beginPath(); ctx.moveTo(cx, cy - R); ctx.lineTo(cx, cy + R); ctx.moveTo(cx - R, cy); ctx.lineTo(cx + R, cy); ctx.stroke();
var pts = radarPts(p, cx, cy, R, M);
ctx.beginPath(); pts.forEach(function (x, i) { i ? ctx.lineTo(x[0], x[1]) : ctx.moveTo(x[0], x[1]); }); ctx.closePath();
ctx.fillStyle = 'rgba(242,123,53,.18)'; ctx.fill(); ctx.strokeStyle = '#F27B35'; ctx.lineWidth = 4; ctx.lineJoin = 'round'; ctx.stroke();
pts.forEach(function (x, i) { ctx.beginPath(); ctx.arc(x[0], x[1], ORDER[i] === curRec.type ? 9 : 6.5, 0, 7); ctx.fillStyle = '#F27B35'; ctx.fill(); ctx.lineWidth = 3; ctx.strokeStyle = '#fff'; ctx.stroke(); });
var L = [[cx, cy - R - 16, 'center'], [cx + R + 12, cy + 8, 'left'], [cx, cy + R + 34, 'center'], [cx - R - 12, cy + 8, 'right']];
ORDER.forEach(function (k, i) {
ctx.textAlign = L[i][2]; ctx.font = (k === curRec.type ? '800' : '500') + ' 22px ' + FONT;
ctx.fillStyle = k === curRec.type ? '#F27B35' : '#86909C'; ctx.fillText(TYPES[k].ax, L[i][0], L[i][1]);
});
var sorted = ORDER.slice().sort(function (x, y) { return (y === curRec.type) - (x === curRec.type) || p[y] - p[x]; });
sorted.forEach(function (k, i) {
var y = 838 + i * 64, me = k === curRec.type;
ctx.textAlign = 'left'; ctx.font = (me ? '700' : '400') + ' 25px ' + FONT; ctx.fillStyle = me ? '#F27B35' : '#4E5969'; ctx.fillText(TYPES[k].dim, 388, y + 10);
ctx.textAlign = 'right'; ctx.font = '700 25px ' + FONT; ctx.fillStyle = me ? '#F27B35' : '#1F2329'; ctx.fillText(p[k] + '%', 674, y + 10);
ctx.fillStyle = '#FFEDE1'; rr(ctx, 388, y + 24, 286, 10, 5); ctx.fill();
ctx.fillStyle = me ? '#F27B35' : '#F9C29E'; rr(ctx, 388, y + 24, Math.max(10, 286 * p[k] / 100), 10, 5); ctx.fill();
});
/* 底部 */
ctx.textAlign = 'center';
ctx.fillStyle = '#1F2329'; ctx.font = '700 26px ' + FONT; ctx.fillText('测一测:你家准爸爸是哪种队友?', W / 2, 1128);
ctx.fillStyle = '#86909C'; ctx.font = '400 21px ' + FONT; ctx.fillText('兜爸心选 · 孕期专题 · 趣味测试,仅供娱乐', W / 2, 1164);
return cv.toDataURL('image/png');
}
var isWx = /MicroMessenger/i.test(navigator.userAgent);
$('#saveBtn').addEventListener('click', function () {
if (!curRec) return;
toast('正在生成结果卡…');
loadImg(TYPES[curRec.type].img).then(function (im) {
var url = drawCard(im);
$('#maskImg').src = url;
var dl = $('#dlBtn'); dl.href = url; dl.hidden = isWx;
$('#toast').classList.remove('on');
$('#mask').classList.add('on');
}).catch(function () { toast('生成失败,截个图保存也可以'); });
});
$('#maskClose').addEventListener('click', function () { $('#mask').classList.remove('on'); });
$('#mask').addEventListener('click', function (e) { if (e.target === this) this.classList.remove('on'); });
/* 入口:有上次结果直接看结果,否则开始页 */
var saved = null;
try { saved = JSON.parse(localStorage.getItem(KEY) || 'null'); } catch (e) {}
if (resume()) ;
else if (saved && TYPES[saved.type] && saved.scores && saved.ans && saved.ans.length === QS.length) render(saved, true);
else show('start');
/* 禁止下拉回弹:固定外壳 + 容器滚动 + 到顶/到底时拦 touchmove */
var y0 = 0;
sc.addEventListener('touchstart', function (e) { y0 = e.touches[0].clientY; }, { passive: true });
sc.addEventListener('touchmove', function (e) {
var dy = e.touches[0].clientY - y0;
if ((sc.scrollTop <= 0 && dy > 0) || (sc.scrollTop + sc.clientHeight >= sc.scrollHeight - 1 && dy < 0)) e.preventDefault();
}, { passive: false });
document.addEventListener('touchmove', function (e) { if (!sc.contains(e.target)) e.preventDefault(); }, { passive: false });
})();
</script>
</body>
</html>