Node.js中实现月相SVG图形的方法及npm包求推荐
Hey,我刚好有几个实用的方案帮你搞定这个月相图形生成的需求,既能省掉自己处理数据转图形的麻烦,也能简化满月判断的流程:
推荐的npm包与实现方案
1. moon-phase-svg
这个包完全贴合你的需求——专门用来生成月相SVG,不用自己折腾光照数据的图形化转换。它支持直接传入指定日期,输出可直接嵌入页面的SVG字符串,还能自定义大小、颜色、月相朝向等细节。
基础用法:
const moonPhaseSvg = require('moon-phase-svg'); // 传入指定日期生成SVG const svg = moonPhaseSvg(new Date('2024-05-23')); console.log(svg); // 直接得到可使用的SVG代码
更贴心的是,它内部已经封装了月相状态判断,比如满月、新月这些状态可以直接通过配置或返回值获取,不用你再去对着SunCalc的光照数据反复计算。
2. lunar-phase
如果需要更轻量化的选择,这个包可以同时提供结构化的月相数据和基础SVG生成能力。API非常简洁,返回的对象里直接包含月相名称(比如'full moon')和对应的SVG代码,判断满月简直零成本。
示例代码:
const lunarPhase = require('lunar-phase'); const phaseData = lunarPhase(new Date('2024-06-22')); console.log(phaseData.name); // 直接拿到月相名称,判断满月超简单 console.log(phaseData.svg); // 对应的月相SVG字符串
3. 基于SunCalc手动实现(自定义控细节)
如果你想继续用已经熟悉的SunCalc,其实也可以自己写个轻量的SVG生成函数。SunCalc返回的illumination对象里,phase值(0到1)可以直接用来判断月相:0/1是新月,0.25是上弦月,0.5是满月,0.75是下弦月。判断满月可以用范围匹配,比如:
const SunCalc = require('suncalc'); const illumination = SunCalc.getMoonIllumination(new Date()); // 当phase接近0.5时认定为满月,范围可以根据需求调整 const isFullMoon = Math.abs(illumination.phase - 0.5) < 0.02;
然后可以通过两个图形叠加来生成简单月相SVG,比如用圆形做月亮底色,用矩形模拟未被照亮的阴影:
简易SVG生成示例:
function generateMoonSvg(date, size = 100) { const { fraction, phase } = SunCalc.getMoonIllumination(date); const isWaxing = phase < 0.5; // 0-0.5是盈月(新月到满月),右侧亮;反之是亏月,左侧亮 // 计算照亮部分的宽度 const illuminatedWidth = fraction * size; // 确定阴影矩形的起始位置 const shadowX = isWaxing ? size - illuminatedWidth : 0; return ` <svg width="${size}" height="${size}" viewBox="0 0 ${size} ${size}"> <!-- 月亮底色 --> <circle cx="${size/2}" cy="${size/2}" r="${size/2}" fill="#f5f5f5" /> <!-- 未照亮的阴影区域 --> <rect x="${shadowX}" y="0" width="${size - illuminatedWidth}" height="${size}" fill="#2d2d2d" /> </svg> `.trim(); }
这个函数能生成基础的月相SVG,你还可以根据需求调整颜色、替换成更真实的月亮轮廓路径。
内容的提问来源于stack exchange,提问作者Dhaval Chaudhary
相关产品推荐
相关产品推荐

