|
@@ -292,6 +292,38 @@
|
|
|
|
|
|
|
|
<!-- 背部中线参考 -->
|
|
<!-- 背部中线参考 -->
|
|
|
<line :x1="SVG_C7_X" :y1="SVG_C7_Y - 20" :x2="SVG_C7_X" :y2="SVG_S4_Y" stroke="rgba(99,102,241,0.35)" stroke-width="2" stroke-dasharray="8 6" stroke-linecap="round" />
|
|
<line :x1="SVG_C7_X" :y1="SVG_C7_Y - 20" :x2="SVG_C7_X" :y2="SVG_S4_Y" stroke="rgba(99,102,241,0.35)" stroke-width="2" stroke-dasharray="8 6" stroke-linecap="round" />
|
|
|
|
|
+ <g v-if="currentShoulderWidthMm">
|
|
|
|
|
+ <line
|
|
|
|
|
+ :x1="currentShoulderStartX"
|
|
|
|
|
+ :y1="SVG_SHOULDER_Y"
|
|
|
|
|
+ :x2="currentShoulderEndX"
|
|
|
|
|
+ :y2="SVG_SHOULDER_Y"
|
|
|
|
|
+ stroke="rgba(249,115,22,0.9)"
|
|
|
|
|
+ stroke-width="3"
|
|
|
|
|
+ stroke-linecap="round"
|
|
|
|
|
+ />
|
|
|
|
|
+ <line
|
|
|
|
|
+ :x1="currentShoulderStartX"
|
|
|
|
|
+ :y1="SVG_SHOULDER_Y - 8"
|
|
|
|
|
+ :x2="currentShoulderStartX"
|
|
|
|
|
+ :y2="SVG_SHOULDER_Y + 8"
|
|
|
|
|
+ stroke="rgba(249,115,22,0.9)"
|
|
|
|
|
+ stroke-width="2"
|
|
|
|
|
+ stroke-linecap="round"
|
|
|
|
|
+ />
|
|
|
|
|
+ <line
|
|
|
|
|
+ :x1="currentShoulderEndX"
|
|
|
|
|
+ :y1="SVG_SHOULDER_Y - 8"
|
|
|
|
|
+ :x2="currentShoulderEndX"
|
|
|
|
|
+ :y2="SVG_SHOULDER_Y + 8"
|
|
|
|
|
+ stroke="rgba(249,115,22,0.9)"
|
|
|
|
|
+ stroke-width="2"
|
|
|
|
|
+ stroke-linecap="round"
|
|
|
|
|
+ />
|
|
|
|
|
+ <text :x="SVG_C7_X" :y="SVG_SHOULDER_Y - 12" text-anchor="middle" font-size="10" fill="#c2410c" font-weight="700" font-family="system-ui, sans-serif">
|
|
|
|
|
+ 肩宽 {{ fmtNum(currentShoulderWidthCm) }} cm
|
|
|
|
|
+ </text>
|
|
|
|
|
+ </g>
|
|
|
<line
|
|
<line
|
|
|
:x1="SVG_C7_X + 18"
|
|
:x1="SVG_C7_X + 18"
|
|
|
:y1="SVG_C7_Y"
|
|
:y1="SVG_C7_Y"
|
|
@@ -479,6 +511,7 @@ const showBodyPhoto = false
|
|
|
const SVG_C7_X = 200
|
|
const SVG_C7_X = 200
|
|
|
// 参考经络示意图:大椎位于颈后下缘、后正中线处,视觉上略低于头颈连接点
|
|
// 参考经络示意图:大椎位于颈后下缘、后正中线处,视觉上略低于头颈连接点
|
|
|
const SVG_C7_Y = 112
|
|
const SVG_C7_Y = 112
|
|
|
|
|
+const SVG_SHOULDER_Y = SVG_C7_Y + 44
|
|
|
const SVG_S4_Y = 520
|
|
const SVG_S4_Y = 520
|
|
|
const DEFAULT_SPINE_LENGTH_MM = 450
|
|
const DEFAULT_SPINE_LENGTH_MM = 450
|
|
|
const MAX_VISUAL_SPINE_LENGTH_MM = 600
|
|
const MAX_VISUAL_SPINE_LENGTH_MM = 600
|
|
@@ -502,6 +535,21 @@ const visualScale = (SVG_S4_Y - SVG_C7_Y) / MAX_VISUAL_SPINE_LENGTH_MM
|
|
|
const currentSpineEndY = computed(() =>
|
|
const currentSpineEndY = computed(() =>
|
|
|
Math.min(SVG_S4_Y, SVG_C7_Y + currentSpineLengthMm.value * visualScale)
|
|
Math.min(SVG_S4_Y, SVG_C7_Y + currentSpineLengthMm.value * visualScale)
|
|
|
)
|
|
)
|
|
|
|
|
+const currentShoulderWidthMm = computed(() => {
|
|
|
|
|
+ const shoulderWidthCm = Number(pushData.value?.bodyData?.shoulderWidth ?? bodyForm.shoulderWidth)
|
|
|
|
|
+ return Number.isFinite(shoulderWidthCm) && shoulderWidthCm > 0
|
|
|
|
|
+ ? shoulderWidthCm * 10
|
|
|
|
|
+ : null
|
|
|
|
|
+})
|
|
|
|
|
+const currentShoulderWidthCm = computed(() =>
|
|
|
|
|
+ currentShoulderWidthMm.value ? currentShoulderWidthMm.value / 10 : null
|
|
|
|
|
+)
|
|
|
|
|
+const currentShoulderStartX = computed(() =>
|
|
|
|
|
+ currentShoulderWidthMm.value ? bodyToSvgX(-currentShoulderWidthMm.value / 2) : SVG_C7_X
|
|
|
|
|
+)
|
|
|
|
|
+const currentShoulderEndX = computed(() =>
|
|
|
|
|
+ currentShoulderWidthMm.value ? bodyToSvgX(currentShoulderWidthMm.value / 2) : SVG_C7_X
|
|
|
|
|
+)
|
|
|
|
|
|
|
|
function bodyToSvg(offsetXmm, offsetYmm) {
|
|
function bodyToSvg(offsetXmm, offsetYmm) {
|
|
|
return {
|
|
return {
|