diff --git a/client/public/assets/casper-custom/sticker/charge-max.png b/client/public/assets/casper-custom/sticker/charge-max.png
deleted file mode 100644
index 4e5e13a8..00000000
Binary files a/client/public/assets/casper-custom/sticker/charge-max.png and /dev/null differ
diff --git a/client/public/assets/casper-custom/sticker/charge-max.svg b/client/public/assets/casper-custom/sticker/charge-max.svg
new file mode 100644
index 00000000..5635c085
--- /dev/null
+++ b/client/public/assets/casper-custom/sticker/charge-max.svg
@@ -0,0 +1,8 @@
+
diff --git a/client/public/assets/casper-custom/sticker/charge-none.png b/client/public/assets/casper-custom/sticker/charge-none.png
deleted file mode 100644
index 9da6e528..00000000
Binary files a/client/public/assets/casper-custom/sticker/charge-none.png and /dev/null differ
diff --git a/client/public/assets/casper-custom/sticker/charge-none.svg b/client/public/assets/casper-custom/sticker/charge-none.svg
new file mode 100644
index 00000000..f77b3507
--- /dev/null
+++ b/client/public/assets/casper-custom/sticker/charge-none.svg
@@ -0,0 +1,22 @@
+
diff --git a/client/public/assets/casper-custom/sticker/electric.png b/client/public/assets/casper-custom/sticker/electric.png
deleted file mode 100644
index 1f770fa7..00000000
Binary files a/client/public/assets/casper-custom/sticker/electric.png and /dev/null differ
diff --git a/client/public/assets/casper-custom/sticker/electric.svg b/client/public/assets/casper-custom/sticker/electric.svg
new file mode 100644
index 00000000..7effe3b5
--- /dev/null
+++ b/client/public/assets/casper-custom/sticker/electric.svg
@@ -0,0 +1,462 @@
+
diff --git a/client/public/assets/casper-custom/sticker/lovely.png b/client/public/assets/casper-custom/sticker/lovely.png
deleted file mode 100644
index 0c8213d7..00000000
Binary files a/client/public/assets/casper-custom/sticker/lovely.png and /dev/null differ
diff --git a/client/public/assets/casper-custom/sticker/lovely.svg b/client/public/assets/casper-custom/sticker/lovely.svg
new file mode 100644
index 00000000..a9868378
--- /dev/null
+++ b/client/public/assets/casper-custom/sticker/lovely.svg
@@ -0,0 +1,716 @@
+
diff --git a/client/public/assets/casper-custom/sticker/twinkle.png b/client/public/assets/casper-custom/sticker/twinkle.png
deleted file mode 100644
index 1cadd1ce..00000000
Binary files a/client/public/assets/casper-custom/sticker/twinkle.png and /dev/null differ
diff --git a/client/public/assets/casper-custom/sticker/twinkle.svg b/client/public/assets/casper-custom/sticker/twinkle.svg
new file mode 100644
index 00000000..e7eb5f0c
--- /dev/null
+++ b/client/public/assets/casper-custom/sticker/twinkle.svg
@@ -0,0 +1,1081 @@
+
diff --git a/client/src/constants/CasperCustom/casper.ts b/client/src/constants/CasperCustom/casper.ts
index 6194326d..0adfae47 100644
--- a/client/src/constants/CasperCustom/casper.ts
+++ b/client/src/constants/CasperCustom/casper.ts
@@ -1,3 +1,5 @@
+import { ColorOptionType, StickerOptionType } from "@/types/casperCustom";
+
export const CUSTOM_OPTION = {
EYES: "eyes",
EYES_DIRECTION: "eyesDirection",
@@ -47,7 +49,7 @@ export const COLOR_OPTION = {
R_AMBER: "#FFD96B",
R_YELLOW: "#FEFF78",
} as const;
-const STICKER_OPTION = {
+export const STICKER_OPTION = {
ELECTRIC: "electric",
CHARGE_MAX: "charge-max",
CHARGE_NONE: "charge-none",
@@ -80,6 +82,43 @@ export const COLOR_BACKGROUND_MAP = [
COLOR_OPTION.R_LIGHTBLUE,
] as const;
+export const STICKER_COLOR_MAP = {
+ [STICKER_OPTION.CHARGE_MAX]: {
+ default: "#515867",
+ exception: "#333741",
+ },
+ [STICKER_OPTION.CHARGE_NONE]: {
+ default: "#5CDD6A",
+ exception: "#FEFF78",
+ },
+ [STICKER_OPTION.ELECTRIC]: {
+ default: "#FEFF78",
+ exception: "#FEFF78",
+ },
+ [STICKER_OPTION.LOVELY]: {
+ default: "#FF6EB0",
+ exception: "#11CCF2",
+ },
+ [STICKER_OPTION.TWINKLE]: {
+ default: "#11CCF2",
+ exception: "#FEFF78",
+ },
+} as const;
+
+export const COLOR_STICKER_EXCEPTION: Partial> = {
+ [COLOR_OPTION.C_SILVER]: STICKER_OPTION.CHARGE_MAX,
+ [COLOR_OPTION.R_PURPLE]: STICKER_OPTION.CHARGE_MAX,
+ [COLOR_OPTION.R_ORANGE]: STICKER_OPTION.CHARGE_NONE,
+ [COLOR_OPTION.R_INDIGO]: STICKER_OPTION.CHARGE_NONE,
+ [COLOR_OPTION.R_LIGHTBLUE]: STICKER_OPTION.LOVELY,
+ [COLOR_OPTION.R_AMBER]: STICKER_OPTION.LOVELY,
+ [COLOR_OPTION.R_MAGENTA]: STICKER_OPTION.TWINKLE,
+ [COLOR_OPTION.R_YELLOW]: STICKER_OPTION.TWINKLE,
+ [COLOR_OPTION.C_BLACK]: STICKER_OPTION.TWINKLE,
+ [COLOR_OPTION.R_DEEPPURPLE]: STICKER_OPTION.TWINKLE,
+ [COLOR_OPTION.C_ORANGE]: STICKER_OPTION.TWINKLE,
+};
+
export const CASPER_Z_INDEX = {
CASPER: 2,
UNDER_CASPER: 1,
diff --git a/client/src/features/CasperCustom/CasperCard/CasperCardFrontUI.tsx b/client/src/features/CasperCustom/CasperCard/CasperCardFrontUI.tsx
index b4a242e1..bef524d2 100644
--- a/client/src/features/CasperCustom/CasperCard/CasperCardFrontUI.tsx
+++ b/client/src/features/CasperCustom/CasperCard/CasperCardFrontUI.tsx
@@ -8,11 +8,14 @@ import {
CASPER_SIZE_OPTION,
CASPER_Z_INDEX,
COLOR_BACKGROUND_MAP,
+ COLOR_STICKER_EXCEPTION,
CUSTOM_OPTION,
+ STICKER_COLOR_MAP,
} from "@/constants/CasperCustom/casper";
import { SelectedCasperIdxType } from "@/types/casperCustom";
import { getCasperEyesComponent } from "@/utils/CasperCustom/getCasperEyesComponent";
import { getCasperMouthComponent } from "@/utils/CasperCustom/getCasperMouthComponent";
+import { getCasperStickerComponent } from "@/utils/CasperCustom/getCasperStickerComponent";
import CasperEyesLayout from "/public/assets/casper-custom/eyes/layout.svg?react";
import CasperFace from "/public/assets/casper-custom/face.svg?react";
@@ -67,6 +70,10 @@ function CasperCardFrontUI({
CASPER_OPTION[CUSTOM_OPTION.EYES_DIRECTION][selectedEyesDirectionIdx];
const selectedMouth = CASPER_OPTION[CUSTOM_OPTION.MOUTH][selectedMouthIdx];
const selectedColor = CASPER_OPTION[CUSTOM_OPTION.COLOR][selectedColorIdx];
+ const selectedSticker =
+ selectedStickerIdx !== null
+ ? CASPER_OPTION[CUSTOM_OPTION.STICKER][selectedStickerIdx]
+ : null;
const { CARD_WIDTH, CARD_HEIGHT } = CASPER_CARD_SIZE[size];
const {
@@ -85,6 +92,20 @@ function CasperCardFrontUI({
selectedEyesDirection.id
);
const CasperMouthSvgComponent = getCasperMouthComponent(selectedMouth.id);
+ const CasperStickerSvgComponent = getCasperStickerComponent(
+ selectedSticker !== null ? selectedSticker.id : null
+ );
+
+ const getStickerColor = () => {
+ if (!selectedSticker) {
+ return "";
+ }
+
+ const isException = COLOR_STICKER_EXCEPTION[selectedColor.id] === selectedSticker.id;
+ return isException
+ ? STICKER_COLOR_MAP[selectedSticker.id].exception
+ : STICKER_COLOR_MAP[selectedSticker.id].default;
+ };
return (
- {CasperEyesSvgComponent && (
-
- )}
- {CasperMouthSvgComponent && (
-
- )}
+
+
- {selectedStickerIdx !== null && (
-
)}
diff --git a/client/src/types/casperCustom.ts b/client/src/types/casperCustom.ts
index e5fac514..945e4369 100644
--- a/client/src/types/casperCustom.ts
+++ b/client/src/types/casperCustom.ts
@@ -1,5 +1,18 @@
import { Dispatch } from "react";
-import { CUSTOM_OPTION } from "@/constants/CasperCustom/casper";
+import {
+ COLOR_OPTION,
+ CUSTOM_OPTION,
+ EYES_OPTION,
+ MOUTH_OPTION,
+ POSITION_OPTION,
+ STICKER_OPTION,
+} from "@/constants/CasperCustom/casper";
+
+export type ColorOptionType = (typeof COLOR_OPTION)[keyof typeof COLOR_OPTION];
+export type StickerOptionType = (typeof STICKER_OPTION)[keyof typeof STICKER_OPTION];
+export type EyesOptionType = (typeof EYES_OPTION)[keyof typeof EYES_OPTION];
+export type EyesDirectionOptionType = (typeof POSITION_OPTION)[keyof typeof POSITION_OPTION];
+export type MouthOptionType = (typeof MOUTH_OPTION)[keyof typeof MOUTH_OPTION];
export type CustomOptionType = (typeof CUSTOM_OPTION)[keyof typeof CUSTOM_OPTION];
type CasperFaceKeys = Exclude;
diff --git a/client/src/utils/CasperCustom/getCasperEyesComponent.tsx b/client/src/utils/CasperCustom/getCasperEyesComponent.tsx
index bf1fbdb8..a0338402 100644
--- a/client/src/utils/CasperCustom/getCasperEyesComponent.tsx
+++ b/client/src/utils/CasperCustom/getCasperEyesComponent.tsx
@@ -1,4 +1,4 @@
-import { EYES_OPTION, POSITION_OPTION } from "@/constants/CasperCustom/casper";
+import { EyesDirectionOptionType, EyesOptionType } from "@/types/casperCustom";
import Alloy15Center from "/public/assets/casper-custom/eyes/15inch-alloy-center.svg?react";
import Alloy15Left from "/public/assets/casper-custom/eyes/15inch-alloy-left.svg?react";
import Alloy15Right from "/public/assets/casper-custom/eyes/15inch-alloy-right.svg?react";
@@ -24,13 +24,7 @@ import VacantCenter from "/public/assets/casper-custom/eyes/vacant-center.svg?re
import VacantLeft from "/public/assets/casper-custom/eyes/vacant-left.svg?react";
import VacantRight from "/public/assets/casper-custom/eyes/vacant-right.svg?react";
-type EyesOptionType = (typeof EYES_OPTION)[keyof typeof EYES_OPTION];
-type EyesDirectionOptionType = (typeof POSITION_OPTION)[keyof typeof POSITION_OPTION];
-
-const EYES_COMPONENT_MAP: Record<
- string,
- React.ComponentType> | null
-> = {
+const EYES_COMPONENT_MAP: Record>> = {
"15inch-alloy-center": Alloy15Center,
"15inch-alloy-left": Alloy15Left,
"15inch-alloy-right": Alloy15Right,
@@ -60,7 +54,7 @@ const EYES_COMPONENT_MAP: Record<
export function getCasperEyesComponent(
eyesOption: EyesOptionType,
eyesDirectionOption: EyesDirectionOptionType
-): React.ComponentType> | null {
+): React.ComponentType> {
const componentKey = `${eyesOption}-${eyesDirectionOption}`;
return EYES_COMPONENT_MAP[componentKey];
}
diff --git a/client/src/utils/CasperCustom/getCasperMouthComponent.tsx b/client/src/utils/CasperCustom/getCasperMouthComponent.tsx
index cd56ac04..85a31df6 100644
--- a/client/src/utils/CasperCustom/getCasperMouthComponent.tsx
+++ b/client/src/utils/CasperCustom/getCasperMouthComponent.tsx
@@ -1,23 +1,20 @@
-import { MOUTH_OPTION } from "@/constants/CasperCustom/casper";
+import { MouthOptionType } from "@/types/casperCustom";
import Cloudy from "/public/assets/casper-custom/mouth/cloudy.svg?react";
import Expressionsless from "/public/assets/casper-custom/mouth/expressionless.svg?react";
import Laugh from "/public/assets/casper-custom/mouth/laugh.svg?react";
import Mocking from "/public/assets/casper-custom/mouth/mocking.svg?react";
import Smile from "/public/assets/casper-custom/mouth/smile.svg?react";
-type MouthOptionType = (typeof MOUTH_OPTION)[keyof typeof MOUTH_OPTION];
-
-const mouthComponentMap: Record> | null> =
- {
- cloudy: Cloudy,
- expressionless: Expressionsless,
- laugh: Laugh,
- mocking: Mocking,
- smile: Smile,
- };
+const mouthComponentMap: Record>> = {
+ cloudy: Cloudy,
+ expressionless: Expressionsless,
+ laugh: Laugh,
+ mocking: Mocking,
+ smile: Smile,
+};
export function getCasperMouthComponent(
mouth: MouthOptionType
-): React.ComponentType> | null {
+): React.ComponentType> {
return mouthComponentMap[mouth];
}
diff --git a/client/src/utils/CasperCustom/getCasperStickerComponent.tsx b/client/src/utils/CasperCustom/getCasperStickerComponent.tsx
new file mode 100644
index 00000000..3e1732d1
--- /dev/null
+++ b/client/src/utils/CasperCustom/getCasperStickerComponent.tsx
@@ -0,0 +1,26 @@
+import { StickerOptionType } from "@/types/casperCustom";
+import ChargeMax from "/public/assets/casper-custom/sticker/charge-max.svg?react";
+import ChargeNone from "/public/assets/casper-custom/sticker/charge-none.svg?react";
+import Electric from "/public/assets/casper-custom/sticker/electric.svg?react";
+import Lovely from "/public/assets/casper-custom/sticker/lovely.svg?react";
+import Twinkle from "/public/assets/casper-custom/sticker/twinkle.svg?react";
+
+const STICKER_COMPONENT_MAP: Record<
+ string,
+ React.ComponentType> | null
+> = {
+ "charge-max": ChargeMax,
+ "charge-none": ChargeNone,
+ electric: Electric,
+ lovely: Lovely,
+ twinkle: Twinkle,
+};
+
+export function getCasperStickerComponent(
+ sticker: StickerOptionType | null
+): React.ComponentType> | null {
+ if (sticker === null) {
+ return null;
+ }
+ return STICKER_COMPONENT_MAP[sticker];
+}