TypeScript月相组件:渐盈与渐亏阶段渲染错误问题
解决月相渲染颠倒问题
问题根源在于遮罩逻辑与相位计算的双重颠倒:
- 原mask的黑白填充逻辑搞反了,导致阴影显示区域与预期相反
visiblePortion的计算方式错误,无法正确对应渐盈/渐亏阶段的暗部范围
关键修改点
- 修正遮罩逻辑:将mask默认填充改为黑色(禁止阴影显示),path填充改为白色(允许阴影显示暗部)
- 重新计算暗部宽度:根据相位区间生成对应的暗部比例,0-0.5区间暗部从全圆缩小到消失,0.5-1区间暗部从0扩展到全圆
- 调整路径方向:渐盈阶段绘制左侧暗部路径,渐亏阶段绘制右侧暗部路径
修改后的完整代码
import React from "react"; interface MoonPhaseProps { phase: number; moonTexture?: string; rotation?: number; } const MoonPhase = ({ phase, moonTexture = "/image/moon/moon.svg", rotation = 0, }: MoonPhaseProps) => { // 确保相位在0-1范围内 const normalizedPhase = Math.max(0, Math.min(phase, 1)); // 计算暗部的宽度比例:0-0.5从1到0,0.5-1从0到1 const visiblePortion = normalizedPhase <= 0.5 ? 1 - 2 * normalizedPhase : 2 * (normalizedPhase - 0.5); const rx = 50 * visiblePortion; // 生成对应相位的路径:渐盈(左暗)/渐亏(右暗) const pathD = normalizedPhase <= 0.5 ? `M50,0 A${rx},50 0 1,1 50,100 A${rx},50 0 1,0 50,0` : `M50,0 A${rx},50 0 1,0 50,100 A${rx},50 0 1,1 50,0`; return ( <svg width="100%" viewBox="0 0 100 100" data-phase={phase} style={{ transform: `rotate(${rotation}deg)`, transition: "transform 0.3s ease-in-out", }} > <defs> <pattern id="moonTexturePattern" patternUnits="userSpaceOnUse" width="100" height="100" > <image href={moonTexture} x="0" y="0" width="100" height="100" /> </pattern> <mask id="moonMask"> {/* 默认禁止阴影显示(亮部) */} <rect x="0" y="0" width="100" height="100" fill="black" /> {/* 允许阴影显示的区域(暗部) */} <path d={pathD} fill="white" /> </mask> </defs> {/* 月亮纹理 */} <circle cx="50" cy="50" r="49" fill="url(#moonTexturePattern)" /> {/* 暗部阴影 */} <circle cx="50" cy="50" r="49" fill="rgba(0,0,0,0.7)" mask="url(#moonMask)" /> </svg> ); }; export default React.memo(MoonPhase);
验证对应关系
- 0/1:新月(全暗,阴影覆盖整个月亮)
- 0.125:渐盈蛾眉月(右侧25%亮,左侧75%暗)
- 0.25:上弦月(右侧50%亮,左侧50%暗)
- 0.375:渐盈凸月(右侧75%亮,左侧25%暗)
- 0.5:满月(全亮,无阴影)
- 0.625:渐亏凸月(左侧75%亮,右侧25%暗)
- 0.75:下弦月(左侧50%亮,右侧50%暗)
- 0.875:渐亏残月(左侧25%亮,右侧75%暗)
内容的提问来源于stack exchange,提问作者Best Codes
相关产品推荐
相关产品推荐

