From dc089567dc9b467d083bacaa0dc763709a689f98 Mon Sep 17 00:00:00 2001 From: ymk Date: Fri, 15 Aug 2025 16:32:23 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=97=A0=E8=83=8C=E6=99=AF?= =?UTF-8?q?=E3=80=81=E9=A2=9C=E8=89=B2=E5=9B=BE=E7=89=87=E6=B7=B7=E5=90=88?= =?UTF-8?q?=E8=83=8C=E6=99=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/FullEditor.tsx | 1 - src/components/common/BackgroundSelector.tsx | 124 ++++++++++++------- src/components/common/PreviewToolbar.tsx | 7 +- src/components/common/ThreeTools.ts | 17 +-- 4 files changed, 94 insertions(+), 55 deletions(-) diff --git a/src/components/FullEditor.tsx b/src/components/FullEditor.tsx index 7350ff2..c1da4f3 100644 --- a/src/components/FullEditor.tsx +++ b/src/components/FullEditor.tsx @@ -17,7 +17,6 @@ export default function Page({ textProp, backgroundProp }: { textProp: TextProp const t = useTranslations("TextEditor"); backgroundProp = backgroundProp || { - type: "color", color: "#c4b1b1", image: null, } satisfies BackgroundProp; diff --git a/src/components/common/BackgroundSelector.tsx b/src/components/common/BackgroundSelector.tsx index dba7676..df0ca30 100644 --- a/src/components/common/BackgroundSelector.tsx +++ b/src/components/common/BackgroundSelector.tsx @@ -1,9 +1,10 @@ -import { Box, Text, Flex, Heading, Section, Radio, RadioGroup } from "@radix-ui/themes"; +'use client' +import { Box, Checkbox, Flex, Heading } from "@radix-ui/themes"; import { useTranslations } from "next-intl"; +import { useState } from "react"; export type BackgroundType = "color" | "image"; export interface BackgroundProp { - type: BackgroundType; - color: string; + color: string | null; image: string | null; } export default function BackgroundSelector({ @@ -14,13 +15,53 @@ export default function BackgroundSelector({ setBackground: (bg: BackgroundProp) => void; }) { const t = useTranslations("BackgoundSetting"); + const types: BackgroundType[] = []; + + if (background.color) { + types.push("color"); + } + + if (background.image) { + types.push("image"); + } + + const [backgroundType, setBackgroundType] = useState(types); + const [color, setColor] = useState(background.color); + const [image, setImage] = useState(background.image); + + const handleBackgroundTypeChange = (value: BackgroundType) => { + let newTypes: BackgroundType[]; + if (backgroundType.includes(value)) { + backgroundType.splice(backgroundType.indexOf(value), 1); + newTypes = backgroundType; + } else { + newTypes = [...backgroundType, value]; + } + + setBackgroundType(newTypes); + + if (newTypes.includes("color")) { + background.color = color; + } else { + background.color = null; + } + if (newTypes.includes("image")) { + background.image = image; + } else { + background.image = null; + } + + setBackground({ ...background }); + } const handleColorChange = (e: React.ChangeEvent) => { - setBackground({ - type: "color", - color: e.target.value, - image: background.image, - }); + setColor(e.target.value); + if (backgroundType.includes("color")) { + setBackground({ + ...background, + color: e.target.value, + }); + } }; const handleImageUpload = (e: React.ChangeEvent) => { @@ -29,11 +70,13 @@ export default function BackgroundSelector({ const reader = new FileReader(); reader.onload = (event) => { const result = event.target?.result as string; - setBackground({ - type: "image", - image: result, - color: background.color, - }); + setImage(result); + if (backgroundType.includes("image")) { + setBackground({ + ...background, + image: result, + }); + } }; reader.readAsDataURL(file); } @@ -42,52 +85,47 @@ export default function BackgroundSelector({ return ( {t("title")} - - - setBackground({ ...background, type: value as BackgroundType })}> - {t("colorOption")} - {t("imageOption")} - - - - - - {background.type === "color" && ( - + + + handleBackgroundTypeChange("color")} className="cursor-pointer" /> + {t("colorOption")} + - - + className="w-1/2 h-10 rounded-md cursor-pointer pl-4" + />)} + - )} - - {background.type === "image" && ( - + handleBackgroundTypeChange("image")} className="cursor-pointer" /> + {t("imageOption")} + + - )} - + /> + + + ); } diff --git a/src/components/common/PreviewToolbar.tsx b/src/components/common/PreviewToolbar.tsx index 76190ec..72fefd0 100644 --- a/src/components/common/PreviewToolbar.tsx +++ b/src/components/common/PreviewToolbar.tsx @@ -122,7 +122,7 @@ export default function PreviewToolbar({ const handleShare = () => { setShareError(null); setShareLink(null); - if (background.type == "image" && background.image) { + if (background.image) { setShareError(t("shareErrorNotSupportDesc")); return; } @@ -173,8 +173,8 @@ export default function PreviewToolbar({ {t("share")} {!shareError ? ( - {t("shareSuccessDesc")} !
diff --git a/src/components/common/ThreeTools.ts b/src/components/common/ThreeTools.ts index d80c14a..e178006 100644 --- a/src/components/common/ThreeTools.ts +++ b/src/components/common/ThreeTools.ts @@ -213,19 +213,22 @@ function setGradient( if (dir == "l2r") { const maxX = geo.boundingBox!.max.x; const minX = geo.boundingBox!.min.x; + const color = new THREE.Color(); for (let i = 0; i < position.count; i++) { const x = position.getX(i); const t = (x - minX) / (maxX - minX); // 归一化 - const color = new THREE.Color().lerpColors(startColor, endColor, t); + color.lerpColors(startColor, endColor, t); colorss.push(color.r, color.g, color.b); } } else if (dir == "t2b") { const maxY = geo.boundingBox!.max.y; const minY = geo.boundingBox!.min.y; + const color = new THREE.Color(); + for (let i = 0; i < position.count; i++) { const y = position.getY(i); const t = (y - minY) / (maxY - minY); // 归一化 - const color = new THREE.Color().lerpColors(startColor, endColor, 1.0 - t); + color.lerpColors(startColor, endColor, 1.0 - t); colorss.push(color.r, color.g, color.b); } } @@ -292,11 +295,11 @@ async function loadFont(textProps: TextProp) { } export function updateBackground(bg: BackgroundProp) { - if (bg.type === "color") { - scene.background = new THREE.Color(bg.color); - } else { - scene.background = null; - } + // if (bg.color) { + // scene.background = new THREE.Color(bg.color); + // } else { + // scene.background = null; + // } } // function createGradientTexture(colors: string[]) {