diff --git a/app/(admin)/settings/agent-workflow/agent-workflow-settings-client.tsx b/app/(admin)/settings/agent-workflow/agent-workflow-settings-client.tsx
index a1180df0f..02e3727a9 100644
--- a/app/(admin)/settings/agent-workflow/agent-workflow-settings-client.tsx
+++ b/app/(admin)/settings/agent-workflow/agent-workflow-settings-client.tsx
@@ -1798,7 +1798,7 @@ export function AgentWorkflowSettingsClient({
onChange={(e) =>
setShowcaseConfig((prev) => ({ ...prev, subtitle: e.target.value }))
}
- placeholder="第一步:风格选择 第二步:生图模式"
+ placeholder="选择生图模式、查询商品图、完成风格配置并实时查看结果"
/>
diff --git a/components/agents/AgentWorkflowParticleScatter.tsx b/components/agents/AgentWorkflowParticleScatter.tsx
index 5d0dd9d69..6243dfcd1 100644
--- a/components/agents/AgentWorkflowParticleScatter.tsx
+++ b/components/agents/AgentWorkflowParticleScatter.tsx
@@ -6,12 +6,16 @@ type AgentWorkflowParticleScatterProps = {
className?: string;
particleSize?: number;
particleCount?: number;
+ sceneScale?: number;
+ viewportScale?: number;
};
export function AgentWorkflowParticleScatter({
className,
particleSize,
particleCount,
+ sceneScale,
+ viewportScale = 1,
}: AgentWorkflowParticleScatterProps) {
const searchParams = new URLSearchParams();
if (typeof particleSize === "number" && Number.isFinite(particleSize) && particleSize > 0) {
@@ -20,9 +24,17 @@ export function AgentWorkflowParticleScatter({
if (typeof particleCount === "number" && Number.isFinite(particleCount) && particleCount > 0) {
searchParams.set("particleCount", String(Math.round(particleCount)));
}
+ if (typeof sceneScale === "number" && Number.isFinite(sceneScale) && sceneScale > 0) {
+ searchParams.set("sceneScale", String(sceneScale));
+ }
const src = searchParams.size
? `/particle-scatter-effect.html?${searchParams.toString()}`
: "/particle-scatter-effect.html";
+ const safeViewportScale =
+ typeof viewportScale === "number" && Number.isFinite(viewportScale) && viewportScale > 0
+ ? viewportScale
+ : 1;
+ const overflowOffsetPercent = ((safeViewportScale - 1) / 2) * 100;
return (
diff --git a/components/agents/AgentWorkflowShowcaseBanner.tsx b/components/agents/AgentWorkflowShowcaseBanner.tsx
index 6840e587a..2c986fc14 100644
--- a/components/agents/AgentWorkflowShowcaseBanner.tsx
+++ b/components/agents/AgentWorkflowShowcaseBanner.tsx
@@ -46,12 +46,11 @@ export function AgentWorkflowShowcaseBanner({
>
-
-
-
+
+
+
{resolved.title}
diff --git a/lib/agents/workflow-showcase-config.ts b/lib/agents/workflow-showcase-config.ts
index 0a86f508c..870e3515c 100644
--- a/lib/agents/workflow-showcase-config.ts
+++ b/lib/agents/workflow-showcase-config.ts
@@ -1,11 +1,14 @@
import type { AgentWorkflowShowcaseConfig } from "@/types/agent";
export const AGENT_WORKFLOW_SHOWCASE_CONFIG_KEY = "agent_workflow_showcase_config";
+const LEGACY_AGENT_WORKFLOW_SHOWCASE_SUBTITLE = "第一步:风格选择第二步:生图模式";
+const DEFAULT_AGENT_WORKFLOW_SHOWCASE_SUBTITLE =
+ "选择生图模式、查询商品图、完成风格配置并实时查看结果";
export const defaultAgentWorkflowShowcaseConfig: AgentWorkflowShowcaseConfig = {
enabled: true,
title: "三倍速出片,电影级质感",
- subtitle: "第一步:风格选择 第二步:生图模式",
+ subtitle: DEFAULT_AGENT_WORKFLOW_SHOWCASE_SUBTITLE,
actionText: "我要创作",
videoUrl: "",
posterUrl: "",
@@ -17,6 +20,18 @@ function sanitizeText(value: unknown, maxLength: number) {
return String(value || "").trim().slice(0, maxLength);
}
+function normalizeShowcaseSubtitle(value: string) {
+ const normalized = String(value || "").trim();
+ if (!normalized) {
+ return defaultAgentWorkflowShowcaseConfig.subtitle;
+ }
+ const compact = normalized.replace(/\s+/g, "");
+ if (compact === LEGACY_AGENT_WORKFLOW_SHOWCASE_SUBTITLE) {
+ return DEFAULT_AGENT_WORKFLOW_SHOWCASE_SUBTITLE;
+ }
+ return normalized;
+}
+
export function normalizeAgentWorkflowShowcaseConfig(
value: unknown
): AgentWorkflowShowcaseConfig {
@@ -33,8 +48,7 @@ export function normalizeAgentWorkflowShowcaseConfig(
: defaultAgentWorkflowShowcaseConfig.enabled,
title:
sanitizeText(raw.title, 200) || defaultAgentWorkflowShowcaseConfig.title,
- subtitle:
- sanitizeText(raw.subtitle, 300) || defaultAgentWorkflowShowcaseConfig.subtitle,
+ subtitle: normalizeShowcaseSubtitle(sanitizeText(raw.subtitle, 300)),
actionText:
sanitizeText(raw.actionText, 48) || defaultAgentWorkflowShowcaseConfig.actionText,
videoUrl: sanitizeText(raw.videoUrl, 2000),
diff --git a/public/particle-scatter-effect.html b/public/particle-scatter-effect.html
index f2b3d9f38..e7579bfba 100644
--- a/public/particle-scatter-effect.html
+++ b/public/particle-scatter-effect.html
@@ -20,6 +20,7 @@
effectMode: 1,
particleSize: 191,
particleCount: 60000,
+ sceneScale: 1,
uploadedImage: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAyAAAAMgCAYAAADbcAZoAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3BpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDkuMS1jMDAyIDc5LmExY2QxMmY0MSwgMjAyNC8xMS8wOC0xNjowOToyMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDowODJGMTk3QTI1QjgxMUYwQkU3OEY1OEExNTUzMDRCNSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpCOUVCQUJGQTFDOTkxMUYxQThBM0VCOEU0MkIxNzEyRiIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpCOUVCQUJGOTFDOTkxMUYxQThBM0VCOEU0MkIxNzEyRiIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjUuMSAoTWFjaW50b3NoKSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjZkOTA5MGM2LWQ3MGQtNGE0NC1hNzM1LTFjMWZmN2QwMTQ0YyIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowODJGMTk3QTI1QjgxMUYwQkU3OEY1OEExNTUzMDRCNSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Ph5sOxgAACDsSURBVHja7N15sJ1lfQfwcwxgCKJiQUBIcrOBxC0UtUWhhgoJEEJAFChaHYgiKlortco4uFCnrWIVC1gZ6wzaFgk7yl6FIEiCyCJLQZLcJQsgoOwYAsnt73hpCnpDzrnPPe/6+cw8vPkP5nuZN/nm9zzv0xwcHGwAAABk4SUiAAAAFBAAAEABAQAAUEAAAAAFBAAAQAEBAAAUEAAAQAEBAABQQAAAAAUEAABAAQEAABQQAABAAQEAAFBAAAAABQQAAEABAQAAFBAAAEABAQAAUEAAAAAFBAAAQAEBAAAUEAAAQAEBAABQQAAAAAUEAABAAQEAABQQAABAAQEAAFBAAAAABQQAAEABAQAAFBAAAAAFBAAAUEAAAAAFBAAAQAEBAAAUEAAAAAUEAABQQAAAAAUEAABAAQEAABQQAAAABQQAAFBAAAAABQQAAEABAQAAFBAAAAAFBAAAUEAAAAAFBAAAQAEBAAAUEAAAAAUEAABQQAAAAAUEAABAAQEAABQQAAAABQQAAFBAAAAAFBAAAEABAQAAFBAAAAAFBAAAUEAAAAAUEAAAQAEBAAAUEAAAAAUEAABQQAAAABQQAABAAQEAABQQAAAABQQAAFBAAAAAFBAAAEABAQAAFBAAAAAFBAAAUEAAAAAUEAAAQAEBAAAUEAAAAAUEAABQQAAAABQQAABAAQEAABQQEQAAAAoIAACggAAAACggAACAAgIAAKCAAAAACggAAKCAAAAAKCAAAIACAgAAoIAAAAAKCAAAoIAAAAAoIAAAgAICAACggAAAAAoIAACggAAAACggAACAAgIAAKCAAAAACggAAKCAAAAAKCAAAIACAgAAoIAAAAAKCAAAoIAAAAAoIAAAgAICAACggAAAAAoIAACAAgIAACggAACAAgIAAKCAAAAACggAAIACAgAAKCAAAIACAgAAoIAAAAAKCAAAgAICAAAoIAAAgAICAACggAAAAAoIAACAAgIAACggAACAAgIAANA1m4iAFGPPffgdUgCAeln97q2ukQIKCHlZKAIAqJ2mCBgpW7AAAAAFBAAAUEAAAABGzBkQEg2KAACAtpmAAAAACggAAKCAAAAAKCAAAIACAgAAoIAAAAAKCAAAUGHuASFNUwQAALTPBAQAAFBAAACA6rEFi0SDIgAAoG0mIAAAgAICAAAoIAAAAAoIAACggAAAACggAABA9nyGlyQuQgcAoBMmIAAAgAICAABUjy1YpLEHCwAABYTsDIoAAIC22YIFAAAoIAAAgAICAACggAAAAAoIAACAAgIAACggAACAAgIAAKCAAAAACggAAMAf20QEJGkOygAAgLaZgAAAAAoIAACggAAAACggAACAAgIAAKCAAAAACggAAKCAAAAAKCAAAECJuAmdJM2Gm9ABAGifCQgAAJAZExDSNEUAAED7TEAAAAAFBAAAUEAAAAAUEAAAQAEBAABQQAAAAAUEAACoMPeAkMhN6AAAtM8EBAAAUEAAAAAFBAAAYMScASFNUwQAALTPBAQAAFBAAAAABQQAAEABAQAAFBAAAID1fAWLRG5CBwCgfSYgAACAAgIAACggAAAAI+YMCElchA4AgAKCBgIAQCHZggUAACggAACAAgIAAKCAAAAAxecQOonchA4AQPtMQAAAAAUEAABQQAAAABQQAABAAQEAAFBAAACA7PkML2maIgAAoH0mIAAAgAICAABUjy1YJHITOgAA7TMBAQAAFBAAAEABAQAAUEAAAAAFBAAAQAEBAACy5zO8JHEROgAACggaCAAACghV5CJCAADa5wwIAACggAAAAAoIAACAAgIAACggAAAACggAAKCAAAAACggAAIACAgAAlIib0EnTdBM6AADtMwEBAAAUEAAAQAEBAABQQAAAAAUEAABAAQEAABQQAABAAQEAAFBAAACAEnETOonchA4AgAJCRppNGQAA0D5bsAAAAAUEAABQQAAAABQQAABAAQEAAFBAAAAABQQAAKgw94CQyEWEAAC0zwQEAABQQAAAgOqxBYs0TREAANA+ExAAAEABAQAAFBAAAAAFBAAAUEAAAADW8xUsErmIEACA9pmAAAAACggAAKCAAAAAjJgzIKRxEzoAAAoI+gcAAEVkCxYAAKCAAAAACggAAMCIOQNCIhcRAgDQPhMQAABAAQEAABQQAAAABQQAAFBAAAAA1vMVLNK4Ch0AgA6YgAAAAAoIAABQPbZgkchFhHT1f67HxAAjsmmscWIAFBCA9i1/bPakHjFA515+Rd9B8bhAEkAR2YIFAAAoIAAAgAICAACggAAAAAoIAADAer6CRRo3oQN4NwMoIPg9DsC7GUABoYJcRAjg3QzQPmdAAAAABQQAAFBAAAAAFBAAAEABAQAAUEAAAAAFBAAAUEAAAADSuYiQNE2XXQF4NwO0zwQEAABQQAAAAAUEAABAAQEAABQQAAAABQQAAFBAAAAABQQAACCdiwhJ5LIrAO9mAAWErDRFAODdDKCA4Pc4AO9mgAJyBgQAAFBAAAAABQQAAEABAQAAFBAAAID1fAWLRL41D+DdDNA+ExAAAEABAQAAqscWLNK47QrAuxmgAyYgAACAAgIAACggAAAACggAAKCAAAAArOcrWCRy2RWAdzNA+0xAAAAABQQAAFBAAAAARswZENK4bRfAuxmgAyYgAABAZkxASOIv2QC8mwE6YQICAAAoIAAAQPXYgkUil10BeDcDtM8EBAAAUEAAAAAFBAAAQAEBAACKzyF00vjYPIB3M0AHTEAAAAAFBAAAqB5bsEjkW/MA3s0A7TMBAQAAFBAAAEABAQAAUEAAAAAFBAAAQAEBAACy5zO8pHHbLoB3M0AHTEAAAIDMmICQyGVXAN7NAAoIGTHlB/BuBuiELVgAAIACAgAAKCAAAAAKCAAAoIAAAAAoIAAAQPZ8hpc0Td+aB/BuBmifCQgAAKCAAAAACggAAIACAgAAKCAAAAAKCAAAoIAAAAAKCAAAQDoXEZLIZVcA3s0ACghZaYoAwLsZoH22YAEAAAoIAABQPbZgkcSUH8C7GaATJiAAAIACAgAAKCAAAAAj5gwIiXxrHsC7GaB9JiAAAIACAgAAVI8tWKTxrUcA72aADpiAAAAACggAAKCAAAAAKCAAAIACAgAAsJ6vYJHIZVcA3s0A7TMBAQAAFBAAAKB6bMEijcuuALybATpgAgIAACggAACAAgIAADBizoCQxDZjAO9mAAWEDPnWPIB3M0D7bMECAAAUEAAAQAEBAABQQAAAgOJzCJ00PrUC4N0M0AETEAAAQAEBAAAUEAAAgBFzBoRELrsC8G4GaJ8JCAAAoIAAAAAKCAAAgAICAAAoIAAAAOv5ChZp3LYL4N0M0AETEAAAIDMmICTyrXkA72aA9pmAAAAAmTEBIYltxgDezQCdMAEBAAAUEAAAQAEBAABQQAAAAAUEAABgPV/BIk3Tt+YBvJsB2mcCAgAAKCAAAIACAgAAoIAAAAAKCAAAgAICAAAoIAAAgAICAACQzkWEpHHZFYB3M0AHTEAAAAAFBAAAUEAAAAAUEAAAoPgcQidJUwQA3s0AHTABAQAAFBAAAKB6bMEikW/NA3g3A7TPBAQAAMiMCQhpnHQE8G4G6IAJCAAAoIAAAAAKCAAAgAICAAAoIAAAAOv5ChaJfGsewLsZoH0mIAAAgAICAAAoIAAAACPmDAhp3LYL4N0M0AETEAAAQAEBAAAUEAAAgBFzBoQkTd+aB/BuBuiACQgAAKCAAAAACggAAIACAgAAFJ9D6KRx2RWAdzNAB0xAAAAABQQAAFBAAAAARswZEBK57ArAuxmgfSYgAACAAgIAACggAAAACggAAKCAAAAArOcrWKRx2y6AdzNAB0xAAACAzJiAkMi35gG8mwHaZwICAAAoIAAAQPXYgkUS5xwBCvlufrkUgKIyAQEAv78DeEEBAAAKCAAAgAICAAAUn0PopGn61jyAdzNA+0xAAAAABQQAAFBAAAAAFBAAAEABAQCyt5kIAAUEAMjKOBEACggAAKCAiAAAAMiKiwhJ47IrgCK+m18uBKCoTEAAwO/vAF5QAACAAgIAFN+mIgCKyhkQoKjGbnfzopliKLVb7//T3R8RQy62EAGggAB0ZttYV4uh1PaKtVAMACggjJqmCAC8mwE64AwIAN3ylAhys6UIgKIyASGRe0CADVojgtzezWNkABSVCQgAAJAZExDS2GgMUMR38zghAEVlAgIA1bOZCAAFBADIigkIoIAAAJkxAQEUEAAgMyYggAICAGTGBAQoLF/BIpF7QAAK+G42AQEKywQEgG55TAS5MQEBFBAAamedCHKzhQgABQQAyMqmIgCKyhkQ0rgJHaCI72YTEKCwTEAA6JZnRZAbf8EIKCAA1M4TIsje9rf+zPQDUEAAgMz4AhaggABQS2tEkItXiAAoMntESeQiQmB4983Y4ykp5PJefpkMAAWEyvIRLIDCvZfdgg4Umi1YAHSD7Vf5cQgdUEAAqJ3fiSA3zoAACggAkBkTEKDQnAEhjUMgwPBWiyC397ICAhSaCQgACki1OIQOKCAAQGZeKQKgyGzBIpF7QIBhPSmC3N7LtmABhWYCAkA3PC2C3NiCBSggANTOYyLIjZvQAQUEgNpxD0h+nAEBFBAAascWLAUEQAEBIDOPiEABARiOr2CRxkWEwPBMQPJ7L28lBKDITEAA6AZnQPJjAgIoIADUjq9g5eA1t13b+n19S0kARWYLFolcRAgMyxasfN7Jph9A4ZmAANANbkLPhwICKCAA1NITIlBAABQQALJiC5YCAjAsZ0BI4iu8wAY8KoJc3skKCFB4JiAAdIOLCPPhDhBAAQFAASEzfyICoOhswSKNPViAAlKkd/LWQgAUECrOPSDAsB4WQS7v5G1kABSdLVgAjLZ1q97wjsfFkItXiwBQQACoG9uv8mMLFqCAAKCAoIAAKCAAKCDVs60IAAUEAAWErtvh9mvGxmMLSQAKCAAKCFlwBwiggACggJAZ268ABQSAWnpIBLlwAB0oBRcRkqbpIkLgjzwgglzexwoIUAomIACMtvtEkIsdRQAoIADU0YMiyMV2IgAUEADq6F4R5OI1IgAUEADqyAQkH7ZgAQoIALWzVgHJjS1YgAICQO08uOr1M30eLx87iAAoA5/hJUlTBMAL3S+C7O14x8JXxvt4rCQABYQa8BedwAv8WgS5vIsdQAdKwxYsABSQ8nMAHSgNExDS2IMFvJBLCPN5FzuADpSGCQgAo2lABLmwBQtQQACopRUiyMUEEQAKCAAKCFnpEQGggACggKCAACggAHTJkytft9dvxaCAACggAGShVwTZ2/HOq18dj80lAZSFz/CSyEWEgAKS83vYAXSgVExAAFBAyq1HBIACAoACggICMAxbsEjjJnTg/y0TQS7vYQUEKBUTEABGyz0iyIUCAiggANTOM7H6xaCAACggAGThnpXT/3KtGLK14/9c1doIO0USgAICQN0sEUEuxscaKwagTBxCJ5F7QIDfu0sEubyDp8kAKBsTEABGw50iyMXOIgAUEADq6HYR5MIEBCgdW7BI4hoQIDwb624x5PIO3kkKQNmYgACQ6p4V09+5Rgy5sAULKB0TENIYgQC2X+Vi/F0/2dQt6EAZmYAAkOomEeRiUqwxYgAUEAAUELJg+xWggABQS7eIIBevFQFQRs6AkMhFhFBzfSt22fthMeTy/n2DDIAyMgEBIMUNIsiNAgIoIADUzmIRZG/8XT9uHT7fRRKAAgKAAkIWWjegv1QMgAICQJ083XAAPS+vFwGggABQN79YscvebkBXQAA64itYpHETOtTZQhHk9u59oxCAsjIBAUABKR9fwAIUEABqZW2sRWLI3vi7fzwuHpMlAZSVLVgkchEh1NSNK167z5NiyOW9+7qGv0AESswLDICRuFIEuXmLCAAFBAAFhKy8WQSAAgJAnTzacAGhAgKggACQkatWvHaftWLI3vi7/3vzeEyXBKCAAFAnPxJBbnaNNUYMQJn5ChZJ3EMItdP69N0lYsjtnWv7FaCA4HdDoFYWLd95nwfEkNs7VwEBFBDqzj0gUDMXiSDXd+5uMgDKzhkQADpxngjyMeFXV24Zj10kASggANTFzct3nrVMDLl5a8PGV0ABAaBGzhFBrvYQAaCAAFAnC0SQq7eLAFBAAKiLny3feVafGPIx4VdXtu7+eJskAAUEgLo4QwS5mhFrCzEACggAdbC64fxH3pz/ABQQAGrj/OU7z3pUDAoIwGhwESFpmi4ihBr4jghyf9fuKQSgKkxAAHgxdy3fafZCMeRnwj1XTInHtpIAFBAA6uB0EeTuL0QAKCAA1MGTsb4nhtztIwJAAQGgDs5YvtPsR8SQnwn3XNGMx96SABQQAKqu9YWJk8WQuzfG2kYMgAICQNVduHyn2UvFkDvbrwAFBIBa+KoICmGWCAAFBICq+8nynWYvFkO+JtxzxdiGCwiBCnIRIYlcRAgV9GURFOL9+rb4x+ZyABQQeJ6mCKBqfjqw074LxVCI96vzH4ACAhoIVN7nRVCY9+u+QgCqyBkQAP7PFQPT9r1GDPmbuOTy8fGYIQlAAQGgyo4XQWHMFQGggABQZWcOTNv3FjEUxjwRAAoIAFW1umH6URgTl1y+ZTxmSgJQQACoqpMGpu27XAyF0Tp8vpkYAAUEgCpaGesrYiiUA0UAVJnP8JLIRYRQcn87MG2/J8VQDBOXXDYmHnMkAVSZCQhAfV0e5eNcMRTKnrG2EgOggABQNU/HOlYMhXOICICqswWLNG5Ch7I6YWDqfsvEUBwTl142Jt6p75EEUHUmIAD1c2Osr4uhcGbG2lYMgAICQJWsiXXUwNT91oqicP5KBIACAkDVfCHKxx1iKJaJSy/bNB7vkgSggABQJT+N9VUxFFLr8kFfvwIUEAAq47FY7x+Yut86URTSYSIA6sJXsEjkIkIoiQ8PTN1/QAzFM3HppZvH4yBJAHVhAgJQfadH+ThLDIV1YKwtxAAoIABUwS9jfVIMhTZfBIACAkAVPB7rsIGp+68WRTFNXHrpxHjsLQmgTpwBIYmL0KHQ3tc/df9fiaHQ79AjvUoBBQQ0EKiCL/dP2f+HYiiunmWXviTeoUdKAqgbW7AAqufiWF8QQ+G1tl5NEAOggABQZq1bzo/on7K/+z6K74MiABQQAMrsgVgHRPl4XBTF1rPs0q3jMU8SQB05A0Kiwe/JAArhpbF+HevgnmWXSKP4Wl8m+4EYgDpqDg66yRqgzKJwjIvHj2PtLo3SeHv/lDnXiwGoI1uwAMpdPsbE40zlo1RuUT4ABQSAsjq14SxB2ZwiAkABAaB0epZdckI8jpFEqTzUcPYDUEAAKGH5+Jt4nCiJ0vlu/5Q5q8UA1JmvYAGUrXz0XnJUo9k4WRKl80zD9isAExCAkpWPQ+PxHUmU0g/6J89ZJQZAAQGgLOXjwHj8p3d3aZ0kAgBbsABKUj4ubpWPc2NtKo1Suqx/8gF3iAHA36IBKB9k4V9EADDETegAygfddUP/5AP+XAwAQ0xAAIpbPg5TPirhSyIAUEAAil4+PhCPM5WP0rs11uViAFBAAIpcPj4SjzO8oyvhS/2TD7DXGUABAShs+Tg+Ht+SRCXcFusiMQC8kM/wAhSjeDTj8bVYn5JGZXzB9ANAAQEonEl9F2/SbDa+G798vzQq48aG6QeAAgJQvPLxo3HxOCfW/tKolM/1TZpr+gEwDPeAAORXPrZuDP0t+dukUSnXRPmYKQaA4ZmAAORTPibH47JYO0mjcj4rAoAN8xUsgOzLx1vjsVj5qKTz+ybNXSwGAAUEoCjl48B4LIy1jTQq55lYnxEDgAICUJTy8Yl4XBBrc2lU0ml9k+YuFQPAi3MGBKD7xWNMPP411kelUVkPxzpRDAAKCEDe5eMV8VgQa7Y0Ku3EvklzHxYDgAICkGf56InHJbGmS6PS7ox1qhgA2uMMCEB3ysee8fi58lELn+ibNPdZMQC0xwQEYLTLR/8PP9RoNk6LX24qjcpb0Ndz4FViAFBAAPIoHq3D5t+I9XFp1MITsY4TA4ACApBH+XhVPM6O9U5p1MaJfT0HrhIDgAICkHX5eGNj6H6PydKojVsbQ9MuADrkEDpAWvk4PB6LlI9aWRfrQ309Bzp4DjACJiAAIyserffnV2J9Shq1880oH78QA4ACApBV+dimMXTeY6Y0amd5rBPEAKCAAGRVPt4Sj/NijZdGLbW2Xj0pBoCRcwYEoP3ycWQ8rlU+auvbUT6uFANAGhMQgI0Wj4s2i8fJsT4ijdrqj/VpMQAoIADdLh/bN4a2XO0ujVo7qq9n3hNiAFBAALpXPgYumtloNs6KX24rjVr7Zt/EeVeLAUABAeiKyQMXNePx2fjHlxvOytXd7a3/F8QAoIAAdKt8vCoe3481Rxq193SsI3onzlstCgAFBKAb5aP1id3W/R490iD8XZSPO8QAMLpsLQAYKh+tL1xdp3zwnEtjnSYGgNHXHBwclAJQ5+LxsnicHusIafCcVbFm9E6c95AoAEafLVhAncvH9HicE2u6NHjO2liHKx8A3WMLFlDX8tGaePxc+eAPHB/l4zoxAHSPCQhQs+Jx4Uvj8Y2GW835YxfH+poYALrLGRCgTuVjWmNoy9WbpMEf6Iv15t6JB/1WFADdZQsWUJfycXg8blY+GMZTsQ5SPgCyYQsWUO3isfzCsfE4udFsfFgabMBRvRMOuk0MAAoIQGr5sOWKjTkpyscCMQBkxxYsoKrlw5YrNubKWMeLASBbDqEDVSseQ1uuGrZc8aLujrV774SDHhEFQLZswQKqVD5suaIdv4k1R/kAyIctWEBVysd7G7ZcsXHPxDo4ykevKADyYQIClL14bB6PU2LNlwZt+GCUj2vFAKCAAIygfFwwPR6tLxi9Xhq04Yu9Ew7+vhgA8uUQOlDW8nFkPE6NNU4atOHfo3x8SAwA+TMBAcpWPF4Wj2/Heq80aNMlsY4RA0AxmIAAZSofM+Jxdqxp0qBNN8aa2Tvh4KdEAVAMvoIFlKV8fCwei5UPOnBX4/ef21U+AIrEBAQodvFYccFW8fhOrEOkQQcGYu3RO/7glaIAKBZnQIDCmrLigj9rNhpnxS97pEEHHoi19zLlA0ABAWizeETvaBwX65+8p+jQo8+Vj6WiAFBAANopH1vHo3VXw37SoEOPxZod5eN2UQAUl0PoQNEcpHwwAo/HmhXl4wZRABSbQ+hA4UxZcf65DYfOad/vYh2wbPy7rhIFQPGZgABFND9WrxhQPgAUEICuiz9Mtg4SHxprjTRQPgAUEIAsSshNjaEvYcFwWgfO5ygfAOXjDAhQaM6DsIHyMSvKhwPnACVkAgIUnfMgPN8jygdAuZmAAIU3ZeX5u8Xj+libSaPWfh1rn2U7vss9HwAlZgICFF78gdN5EPpj7aF8AJSfCQhQGlNWOg9SU3fG2jfKx0pRAJSfCQhQJs6D1M/PY+2lfABUhwkIUCpTVp7nPEh9XBHr3ct2POQJUQBUhwkIUCrxh1HnQerhjFhzlQ8ABQSgCCXk1HicJ4nK+sdYR8XP+RlRAFTPJiIASqp1HmTXWJNFURnrYh0bxePfRAFQXc6AAKXlPEilPBnr8CgfF4sCoNpswQJKy3mQymh94WpP5QOgHkxAgNKbsvI894OU1y2xDojyca8oAOrBBASoAveDlNOPGkOTD+UDoEZMQIBKmLLKeZCS+edYn1u2wyHrRAGggACUtYQcG49TJFFoq2PNj+JxpigAFBCA0pu66lznQYqrtdVq3tId3v0LUQDUlzMgQNU4D1JMi2O9WfkAQAEBKiX+gPtoPA6NtUYahXF6rHfEz+Y+UQBgCxZQSVNXnes8SP6ejvWxKB7fFQUACghQhxLiPEh+VrSyj/JxoygAeD5bsIAqcx4kHz+JtZvyAYACAtSK8yCZa43UT4w1O7J/UBwADMcWLKDynAfJxG9iHRHF40pRAKCAAEqI8yDdtCjWoVE+VooCgI2xBQuoC+dBuuOkxtAndpUPANpiAgLUxtR7z9ktHtfH2kwayVpnPN6/9DXvuVwUAHTCBASojfjD8k3xOE4Sya6KNUP5AEABAdh4CTk1HudJYkTWxjoh1qzI8V5xADASm4gAqKHWeZBdY00WRdv6Yr0visf1ogAghQkIUDvxh2j3g3TmvxpDW66UDwCSOYQO1NbUe89xP8iLaxW1j0bxOFMUACggAKNTQtwPMrxrY/11lI8BUQAwmmzBAurO/SAv1NqW9plYeykfAHSDCQhQe+4HWe+2xtDU4zb/VwDQLSYgQO25H6SxLtZXYr1V+QCg20xAAJ5T0/MgS2MdGcXjOv8HAJAFExCA9Qbnx+qN1ajBin8MfjPWm5QPALJkAgLwPFPvO7sO50H6Y31g6faH/tRPHICsmYAAPE/8obzq50G+FesNygcAeTEBARjG1PvOrtp5kNZZj6OjeFztpwtAnkxAAIbRbDTmx+ptDv26zGtdrK/HepPyAUAhfo81AQEY3rTynwe5M9b8JdsfeoOfJgBFYQICsAFLynse5NlYX4q1m/IBQNGYgABsxLRynQdZFOvoKB53+MkBUEQmIAAbNz9Wb8H/Gx+PdWysPZQPAIrMBASgDQU/D/LDWB+L4rHSTwoABQSgOiWkNWE4pUD/SffG+ngUj/P9dABQQAAqWUIWFOE8yNrnitDnl2x/2ON+KgCUySYiAOhI6zzIrrEm5/TvXxzrmCgev/SjAKCMHEIH6ED8wf/ReBwaa03G/+qHYx0d6+3KBwBlZgsWwAhMu39BludBzoj16SXbHfaQ5AFQQADqW0K6fR6kdZP5MVE8rpM2AFVhCxbAyHXrfpCnYv19rBnKBwBVYwICkGDa/QtG+36QC2N9IorHCukCoIAAMFwJGY3zIPfE+mQUj8skCoACAsDGSshIz4M8EesfYp0c5WONJAGoOveAAIyOkdwP8h+xPhPF4z7xAVAXJiAAo6SD8yA3xzo2isciqQFQN76CBTBKolDc1GgMHhersYH1YKyjY71F+QCgrkxAAEbZtPvP+sPzIGtjnRbri0u2O/xhCQFQZ86AAIy+558Hubrx+8/qHn6HWADABASgK6bdf9bW8dgyikefNABAAQEAAHLgEDoAAKCAAAAACggAAIACAgAAKCAAAAAKCAAAoIAAAAAKCAAAgAICAAAoIAAAAAoIAACggAAAAAoIAACAAgIAACggAAAACggAAFAE/yvAADwfH6yfcKiYAAAAAElFTkSuQmCC',
shape: "default",
interactionMode: "auto",
@@ -29,16 +30,21 @@
const urlParams = new URLSearchParams(window.location.search);
const particleSizeOverride = Number(urlParams.get("particleSize"));
const particleCountOverride = Number(urlParams.get("particleCount"));
+ const sceneScaleOverride = Number(urlParams.get("sceneScale"));
if (Number.isFinite(particleSizeOverride) && particleSizeOverride > 0) {
CONFIG.particleSize = particleSizeOverride;
}
if (Number.isFinite(particleCountOverride) && particleCountOverride > 0) {
CONFIG.particleCount = Math.floor(particleCountOverride);
}
+ if (Number.isFinite(sceneScaleOverride) && sceneScaleOverride > 0) {
+ CONFIG.sceneScale = sceneScaleOverride;
+ }
} catch (error) {}
let uploadedImage = CONFIG.uploadedImage;
let particleSize = CONFIG.particleSize;
const PARTICLE_COUNT = CONFIG.particleCount;
+ const SCENE_SCALE = CONFIG.sceneScale;
let sceneData = null;
let currentEffect = CONFIG.effect;
let currentShape = CONFIG.shape;
@@ -102,9 +108,9 @@
const angle = Math.random() * Math.PI * 2;
const radiusBase = 0.4 + Math.pow(Math.abs(t), 2.4);
const radius = radiusBase * (0.75 + Math.random() * 0.55);
- let x = radius * Math.cos(angle) * 2.9;
- let z = radius * Math.sin(angle) * 2.9;
- let y = t * 7.5;
+ let x = radius * Math.cos(angle) * 2.9 * SCENE_SCALE;
+ let z = radius * Math.sin(angle) * 2.9 * SCENE_SCALE;
+ let y = t * 7.5 * SCENE_SCALE;
positions[i3] = x; positions[i3 + 1] = y; positions[i3 + 2] = z;
targetPositions[i3] = x; targetPositions[i3 + 1] = y; targetPositions[i3 + 2] = z;
randomOffsets[i3] = (Math.random() - 0.5) * 2;
@@ -263,16 +269,16 @@
for (let x = 0; x < resolution; x++) {
const idx = (y * resolution + x) * 4;
const r = imgData[idx], g = imgData[idx + 1], b = imgData[idx + 2];
- if ((r + g + b) / 3 > 15) validPoints.push({ pos: [(x / resolution - 0.5) * 38, (0.5 - y / resolution) * 38, ((r + g + b) / 765 - 0.5) * 12], col: [r / 255, g / 255, b / 255] });
+ if ((r + g + b) / 3 > 15) validPoints.push({ pos: [(x / resolution - 0.5) * 38 * SCENE_SCALE, (0.5 - y / resolution) * 38 * SCENE_SCALE, ((r + g + b) / 765 - 0.5) * 12 * SCENE_SCALE], col: [r / 255, g / 255, b / 255] });
}
}
if (validPoints.length > 0) {
const { targetPositions, targetColors, geometry } = sceneData;
for (let i = 0; i < PARTICLE_COUNT; i++) {
const i3 = i * 3, point = validPoints[i % validPoints.length];
- targetPositions[i3] = point.pos[0] + (Math.random() - 0.5) * 0.4;
- targetPositions[i3 + 1] = point.pos[1] + (Math.random() - 0.5) * 0.4;
- targetPositions[i3 + 2] = point.pos[2] + (Math.random() - 0.5) * 1.5;
+ targetPositions[i3] = point.pos[0] + (Math.random() - 0.5) * 0.4 * SCENE_SCALE;
+ targetPositions[i3 + 1] = point.pos[1] + (Math.random() - 0.5) * 0.4 * SCENE_SCALE;
+ targetPositions[i3 + 2] = point.pos[2] + (Math.random() - 0.5) * 1.5 * SCENE_SCALE;
targetColors[i3] = point.col[0]; targetColors[i3 + 1] = point.col[1]; targetColors[i3 + 2] = point.col[2];
}
geometry.attributes.targetPosition.needsUpdate = true;
@@ -299,7 +305,7 @@
case "infinity": const infScale = 25; for (let i = 0; i < PARTICLE_COUNT; i++) { const t = (i / PARTICLE_COUNT) * Math.PI * 6; const denom = 1 + Math.sin(t) * Math.sin(t); let x = infScale * Math.cos(t) / denom; let y = infScale * Math.sin(t) * Math.cos(t) / denom; const verticalSpread = (Math.random() - 0.5) * 20; const z = (Math.random() - 0.5) * 15 + Math.sin(t * 2) * 5; const thickness = 4.0; const offsetX = (Math.random() - 0.5) * thickness; const offsetY = (Math.random() - 0.5) * thickness + verticalSpread * 0.3; const offsetZ = (Math.random() - 0.5) * thickness; const color = Math.random() > 0.7 ? shapeGreen : shapeWhite; points.push({ pos: [x + offsetX, y + offsetY, z + offsetZ], col: [color.r, color.g, color.b] }); } break;
}
if (points.length > 0) {
- for (let i = 0; i < PARTICLE_COUNT; i++) { const i3 = i * 3; const point = points[i % points.length]; targetPositions[i3] = point.pos[0]; targetPositions[i3 + 1] = point.pos[1]; targetPositions[i3 + 2] = point.pos[2]; targetColors[i3] = point.col[0]; targetColors[i3 + 1] = point.col[1]; targetColors[i3 + 2] = point.col[2]; }
+ for (let i = 0; i < PARTICLE_COUNT; i++) { const i3 = i * 3; const point = points[i % points.length]; targetPositions[i3] = point.pos[0] * SCENE_SCALE; targetPositions[i3 + 1] = point.pos[1] * SCENE_SCALE; targetPositions[i3 + 2] = point.pos[2] * SCENE_SCALE; targetColors[i3] = point.col[0]; targetColors[i3 + 1] = point.col[1]; targetColors[i3 + 2] = point.col[2]; }
geometry.attributes.targetPosition.needsUpdate = true;
geometry.attributes.targetColor.needsUpdate = true;
uploadedImage = "shape";