-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* test(api/moon.svg): theme-shadow 추가 * test(svg.ts): 이미지 path 통합 * test: theme 선택 UI 추가 * style: input 스타일 추가 * delete: 테스트용 이미지 파일 삭제 * theme를 위한 type 추가 * theme type 기반 디렉토리 구조로 변경 * 브라우저에서 theme를 이용하도록 변경 * shadow 테마 뼈대 코드 추가 * theme 이름 변경 및 shadow 테마에 해당하는 svg 그려주는 로직 추가 * theme에 default 값 추가 Co-authored-by: Minung Han <hmu332233@gmail.com> * Basic 테마 이름 수정 * <select> className 수정 Co-authored-by: Minung Han <hmu332233@gmail.com>
- Loading branch information
Showing
9 changed files
with
190 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,25 @@ | ||
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction | ||
import type { NextApiRequest, NextApiResponse } from 'next'; | ||
|
||
import { getMoonPhases } from '../../../server/utils/moon'; | ||
import { createMoon } from '../../../server/utils/svg'; | ||
import type { Theme } from 'server/theme/types'; | ||
|
||
import createMoonFuncMap from 'server/theme'; | ||
import { isTheme } from 'server/utils/type'; | ||
|
||
export default async function handler( | ||
req: NextApiRequest, | ||
res: NextApiResponse, | ||
) { | ||
const { date, size = '100', round } = req.query; | ||
const { date, size = '100', theme = 'basic' } = req.query; | ||
|
||
if (!isTheme(theme)) { | ||
return res.status(200).end(''); | ||
} | ||
|
||
const { k, isWaxing } = await getMoonPhases( | ||
date ? new Date(date as string) : undefined, | ||
); | ||
const moonSvg = createMoon(k, isWaxing, size as string, round === 'true'); | ||
const createMoon = createMoonFuncMap[theme as Theme]; | ||
const moonSvg = await createMoon(date as string, size as string); | ||
|
||
res.setHeader('Content-Type', 'image/svg+xml'); | ||
res.setHeader('Cache-Control', 's-maxage=3600, max-age=3600'); | ||
|
||
res.status(200).end(moonSvg); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import type { CreateMoonFunc } from './types'; | ||
import { getMoonPhases } from '../utils/moon'; | ||
|
||
const createMoon: CreateMoonFunc = async (date: string, size: string) => { | ||
const { k, isWaxing } = await getMoonPhases( | ||
date ? new Date(date as string) : undefined, | ||
); | ||
|
||
let percent = k * 100; | ||
|
||
if (percent < 1) { | ||
const path = `<path d="m 160 10 a 20 20 0 1 1 0 300 a 20 20 0 1 1 0 -300" style="fill: #000; stroke:black; stroke-width:2" />`; | ||
return `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="${size}" height="${size}" viewBox="0 0 320 320">${path}</svg>`; | ||
} | ||
|
||
if (percent < 5) { | ||
percent = 5; | ||
} | ||
|
||
let rx1; | ||
let ry1; | ||
let flag1; | ||
let rx2; | ||
let ry2; | ||
let flag2; | ||
|
||
if (isWaxing) { | ||
rx1 = 20; | ||
ry1 = 20; | ||
rx2 = Math.abs(((percent - 50) / 5) * 2); | ||
ry2 = 20; | ||
flag1 = 1; | ||
flag2 = percent < 50 ? 0 : 1; | ||
} else { | ||
rx1 = Math.abs(((percent - 50) / 5) * 2); | ||
ry1 = 20; | ||
rx2 = 20; | ||
ry2 = 20; | ||
flag1 = percent < 50 ? 0 : 1; | ||
flag2 = 1; | ||
} | ||
|
||
const background = | ||
'<path d="m 160 10 a 20 20 0 1 1 0 300 a 20 20 0 1 1 0 -300" style="fill: #000; stroke:black; stroke-width:2" />'; | ||
const path = `<path d="m 160 10 a ${rx1} ${ry1} 0 1 ${flag1} 0 300 a ${rx2} ${ry2} 0 1 ${flag2} 0 -300" style="fill: #FEFCD7; stroke:black; stroke-width:4" />`; | ||
|
||
return `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="${size}" height="${size}" viewBox="0 0 320 320">${background}${path}</svg>`; | ||
}; | ||
|
||
// isWaxing percent < 50 | ||
// a20 / a20 -> 0 / 1 / 0 | ||
// isWaxing percent > 50 | ||
// a20 / a0 -> 20 / 1 / 1 | ||
|
||
// !isWaxing percent < 50 | ||
// a20 -> 0 / a20 / 0 / 1 | ||
// !isWaxing percent > 50 | ||
// a0 -> 20 / a20 / 1 / 1 | ||
|
||
export default createMoon; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import type { CreateMoonFuncMap } from './types'; | ||
|
||
import basic from './basic'; | ||
import ray from './ray'; | ||
|
||
const createMoonFuncMap: CreateMoonFuncMap = { | ||
basic, | ||
ray, | ||
}; | ||
|
||
export default createMoonFuncMap; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import type { CreateMoonFunc } from './types'; | ||
import { getMoonPhases } from '../utils/moon'; | ||
|
||
const createMoon: CreateMoonFunc = async (date: string, size: string) => { | ||
const { k, isWaxing } = await getMoonPhases( | ||
date ? new Date(date as string) : undefined, | ||
); | ||
|
||
let percent = k * 100; | ||
|
||
if (percent < 1) { | ||
const path = `<path d="m 160 10 a 20 20 0 1 1 0 300 a 20 20 0 1 1 0 -300" style="fill: #000; stroke:black; stroke-width:2" />`; | ||
return `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="${size}" height="${size}" viewBox="0 0 320 320">${path}</svg>`; | ||
} | ||
|
||
if (percent < 5) { | ||
percent = 5; | ||
} | ||
|
||
let rx1; | ||
let ry1; | ||
let flag1; | ||
let rx2; | ||
let ry2; | ||
let flag2; | ||
|
||
if (isWaxing) { | ||
rx1 = 20; | ||
ry1 = 20; | ||
rx2 = Math.abs(((percent - 50) / 5) * 2); | ||
ry2 = 20; | ||
flag1 = 1; | ||
flag2 = percent < 50 ? 0 : 1; | ||
} else { | ||
rx1 = Math.abs(((percent - 50) / 5) * 2); | ||
ry1 = 20; | ||
rx2 = 20; | ||
ry2 = 20; | ||
flag1 = percent < 50 ? 0 : 1; | ||
flag2 = 1; | ||
} | ||
|
||
const color = '#FEFCD7'; | ||
const strokeColor = 'rgba(239, 234, 143)'; | ||
const shadow = `<g className="moon-shadow" xmlns="http://www.w3.org/2000/svg" transform="translate(4, 316) scale(0.240, -0.240)" fill="rgba(239, 234, 143, 0.40)" stroke="none"> | ||
<path d="M511 1275 c-178 -39 -348 -172 -429 -336 -127 -256 -81 -540 118 -739 251 -252 649 -252 900 0 252 251 252 649 0 900 -155 156 -375 221 -589 175z m60 -119 c10 -27 17 -33 38 -32 14 0 31 7 36 14 9 11 16 11 41 0 27 -11 29 -15 17 -27 -8 -7 -23 -11 -34 -8 -10 3 -19 1 -19 -4 0 -17 73 -42 118 -40 25 1 42 -3 42 -10 0 -6 6 -9 13 -6 7 3 23 -6 36 -19 13 -13 33 -24 45 -24 11 -1 44 -9 71 -19 43 -15 53 -16 71 -4 30 19 45 -3 51 -75 3 -31 9 -60 14 -63 5 -3 10 -30 12 -60 1 -42 -1 -54 -13 -54 -11 0 -14 10 -13 39 3 37 2 38 -26 33 -22 -5 -36 0 -56 17 -15 13 -25 28 -21 34 3 6 -3 13 -14 17 -11 3 -20 11 -20 16 0 6 -15 9 -32 7 -40 -4 -47 -27 -22 -74 16 -30 23 -34 59 -34 37 0 42 -3 56 -37 20 -46 8 -65 -33 -51 -28 10 -32 17 -29 50 2 14 -5 17 -37 14 -46 -4 -75 14 -66 39 7 16 3 17 -34 12 -23 -3 -44 -1 -47 4 -3 4 -12 6 -20 2 -9 -3 -15 1 -15 10 0 9 -8 22 -19 29 -10 7 -19 17 -19 23 -1 15 -20 18 -19 3 1 -44 -6 -69 -27 -89 -20 -20 -22 -26 -12 -43 7 -12 12 -27 11 -33 -2 -7 -3 -17 -4 -22 0 -5 -20 -11 -43 -15 -31 -5 -39 -9 -28 -16 12 -7 12 -12 -3 -28 -23 -25 -21 -32 6 -32 12 0 28 -9 35 -20 7 -12 16 -18 21 -15 12 7 33 -21 31 -42 -4 -33 0 -40 25 -51 14 -6 25 -20 25 -30 0 -31 -24 -72 -42 -72 -10 0 -18 -4 -18 -10 0 -5 -11 -10 -25 -10 -14 0 -25 -2 -25 -4 0 -2 -3 -12 -7 -22 -4 -11 -3 -15 5 -10 6 3 13 2 17 -4 3 -6 -1 -13 -9 -16 -9 -3 -16 -12 -16 -20 0 -8 -5 -14 -10 -14 -13 0 -29 40 -23 56 2 7 -1 15 -8 20 -9 5 -10 2 -6 -9 4 -10 2 -17 -5 -17 -6 0 -8 -11 -4 -30 3 -16 2 -30 -2 -31 -4 0 -20 -2 -36 -4 -34 -5 -85 22 -88 45 0 8 -2 21 -2 29 -1 8 -8 16 -16 19 -8 3 -12 1 -8 -3 4 -4 -4 -19 -18 -34 -23 -24 -26 -25 -35 -8 -7 11 -17 16 -29 12 -15 -5 -57 9 -102 33 -3 2 -4 -7 -1 -19 5 -16 3 -20 -6 -14 -7 4 -11 16 -8 26 3 10 -1 23 -9 30 -8 6 -14 17 -14 24 0 6 -9 20 -20 30 -11 10 -20 15 -20 12 0 -20 -45 35 -67 82 -24 49 -25 61 -20 155 5 104 42 241 65 241 6 0 27 19 47 43 38 44 75 59 55 23 -5 -11 -16 -26 -22 -33 -22 -24 -48 -78 -37 -78 5 0 12 7 15 15 5 12 9 13 20 4 12 -10 13 -9 8 5 -5 12 6 29 35 57 22 22 41 44 41 50 0 5 11 14 25 19 14 5 25 14 25 19 0 12 152 3 165 -10 11 -11 36 -12 34 -1 -4 21 3 33 24 43 23 10 23 12 9 44 -13 27 -20 33 -41 30 -14 -2 -29 -4 -34 -4 -4 -1 -12 -13 -17 -27 -8 -19 -16 -25 -30 -21 -38 10 -108 -13 -137 -46 -31 -34 -63 -47 -63 -24 0 8 8 21 18 31 27 24 132 76 154 76 11 0 16 5 13 10 -3 6 2 10 11 10 10 0 25 6 33 14 16 14 66 34 88 35 6 1 17 -14 24 -33z m392 -51 c47 -30 57 -85 16 -85 -50 0 -107 56 -90 88 12 23 37 22 74 -3z m105 -92 c-5 -23 -23 -20 -26 4 -3 18 0 21 13 17 9 -4 15 -13 13 -21z m-503 -803 c3 -6 -5 -10 -19 -10 -14 0 -28 5 -31 10 -3 6 5 10 19 10 14 0 28 -4 31 -10z | ||
M505 904 c-12 -18 -14 -29 -6 -37 15 -15 41 10 41 39 0 31 -14 30 -35 -2z | ||
M373 713 c-27 -5 -30 -19 -5 -27 9 -3 0 -4 -20 -3 -42 3 -42 3 -28 -24 15 -26 53 -24 87 6 15 13 22 25 16 25 -7 0 -13 7 -13 15 0 8 -3 14 -7 14 -5 -1 -18 -4 -30 -6z | ||
M265 581 c-9 -16 6 -41 26 -41 19 0 25 17 11 35 -10 14 -30 17 -37 6z | ||
M530 539 c0 -5 7 -9 15 -9 8 0 15 -4 15 -10 0 -5 7 -10 16 -10 13 0 14 3 5 14 -14 17 -51 28 -51 15z | ||
"/></g>`; | ||
|
||
const path = `<path d="m 160 10 a ${rx1} ${ry1} 0 1 ${flag1} 0 300 a ${rx2} ${ry2} 0 1 ${flag2} 0 -300" style="fill: ${color}; stroke:${strokeColor}; stroke-width:4" />`; | ||
return `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="${size}" height="${size}" viewBox="0 0 320 320">${path}${shadow}</svg>`; | ||
}; | ||
|
||
export default createMoon; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
export const THEMES = ['basic', 'ray'] as const; | ||
export type Theme = typeof THEMES[number]; | ||
export type CreateMoonFunc = (date: string, size: string) => Promise<string>; | ||
export type CreateMoonFuncMap = { | ||
[key in Theme]: CreateMoonFunc; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import { THEMES } from 'server/theme/types'; | ||
|
||
export const isTheme = (theme: any) => THEMES.includes(theme); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
45a9344
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
svg-moon – ./
svg-moon-git-main-hmu332233.vercel.app
moon-phase.vercel.app
svg-moon-hmu332233.vercel.app
moon-svg.minung.dev