GITHUB 日历效果
使用PHP SVG实现效果
中文化、月份线条区分
实现代码:
<?php date_default_timezone_set("PRC"); error_reporting(E_ALL & ~E_NOTICE); set_time_limit(30); header('Content-Type:image/svg+xml; charset=utf-8'); header('Content-Encoding:gzip'); $dt = $_GET['dt'] ?: date('Y-m-d'); $today = strtotime($dt); // 颜色 $colors = ['#ddd']; for ($i=1; $i<=100; $i++) { $colors[] = 'rgb(0,' . (255 - $i*2) . ',0)'; } // 计算最近一年日期 $day_list = []; if (date('w', $today) == 0) { $day = $today - (52 * 7 - 1) * 24*3600; } else { $day = $today - (51 * 7 + date('w', $today) - 1) * 24*3600; } while ($day <= $today) { $day_list[] = [ 'month' => date('m', $day), 'date' => date('Y-m-d', $day), 'week' => intval(date('w', $day)) ?: 7, 'count' => max(0, rand(-100, 100)), // 日期的数量 ]; $day += 24*3600; } // 创建SVG图片 $svg = '<svg version="1.1" width="810" height="128" viewBox="0 0 810 128" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">'; $svg .= '<g transform="translate(25, 20)">'; $svg .= '<g transform="translate(0, 0)">'; $week = 0; $month_list = []; $last_month = ''; const RS = 15; for ($i=0; $i<count($day_list); $i++) { $r = $day_list[$i]; if ($r['month'] != @$day_list[$i-1]['month'] ?: '') { // 计算月份 $pre = $day_list[$i-1]; $month_list[] = [ 'week' => $r['week'] == 1 ? ($week - 1) : $week, 'name' => intval($r['month']) . ' 月', ]; // 绘制月份分割线 if ($r['week'] == 1) { if ($i > 0) { $svg .= '<rect width="1" height="117" x="' . ($week * RS - 2) . '" y="-15" fill="#66f" />'; } } else { $y = $pre['week'] * RS - 2; $svg .= '<rect width="1" height="' . ($y+RS) . '" x="' . (($week + 1) * RS - 2) . '" y="-15" fill="#66f" />'; $svg .= '<rect width="16" height="1" x="' . ($week * RS - 2) . '" y="' . $y . '" fill="#66f" />'; $svg .= '<rect width="1" height="' . (105-$y) . '" x="' . ($week * RS - 2) . '" y="' . $y . '" fill="#66f" />'; } } // 绘制日期色块 $svg .= '<rect width="12" height="12" rx="2" ry="2" x="' . $week * RS . '" y="' . ($r['week'] - 1) * RS . '" fill="' . $colors[$r['count']] . '" />'; if ($r['week'] == 7) { $week++; $svg .= '<g transform="translate(' . $week * RS . ', 0)">'; $svg .= '</g>'; } } $svg .= '</g>'; // 绘制月份 $svg .= '<g transform="translate(25, 0)">'; foreach ($month_list as $r) { $first = $r['week'] == -1 && $month_list[1]['week'] > 2; if (($r['week'] !== -1 && $r['week'] < 51) || $first) { $svg .= '<text text-anchor="start" font-size="10" dx="' . ($r['week'] * RS - 5) . '" dy="-5" >' . $r['name'] . '</text>'; } } $svg .= '</g>'; // 绘制星期标识 $svg .= '<g transform="translate(-17, 10)">'; $svg .= '<text text-anchor="start" font-size="10" dx="0" dy="0" >一</text>'; $svg .= '<text text-anchor="start" font-size="10" dx="0" dy="15">二</text>'; $svg .= '<text text-anchor="start" font-size="10" dx="0" dy="30">三</text>'; $svg .= '<text text-anchor="start" font-size="10" dx="0" dy="45">四</text>'; $svg .= '<text text-anchor="start" font-size="10" dx="0" dy="60">五</text>'; $svg .= '<text text-anchor="start" font-size="10" dx="0" dy="75">六</text>'; $svg .= '<text text-anchor="start" font-size="10" dx="0" dy="90">日</text>'; $svg .= '</g>'; $svg .= '</g>'; $svg .= '</svg>'; $svg = gzencode($svg, 9); echo $svg;