From f654e34c633c23e625b8b40d1177126b8885284f Mon Sep 17 00:00:00 2001 From: kjqwer <2990346238@qq.com> Date: Sun, 7 Dec 2025 21:07:14 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E6=A0=B7=E5=BC=8F=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.vue | 120 ++++++++++++++---------- src/components/icons/IconBackground.vue | 102 ++++++++++++++++++++ src/components/icons/IconEditor.vue | 42 +++++++++ src/components/icons/IconGithub.vue | 22 +++++ src/components/icons/IconManager.vue | 32 +++++++ src/components/icons/IconPresets.vue | 33 +++++++ src/components/icons/IconTheme.vue | 102 ++++++++++++++++++++ src/style.css | 2 +- 8 files changed, 404 insertions(+), 51 deletions(-) create mode 100644 src/components/icons/IconBackground.vue create mode 100644 src/components/icons/IconEditor.vue create mode 100644 src/components/icons/IconGithub.vue create mode 100644 src/components/icons/IconManager.vue create mode 100644 src/components/icons/IconPresets.vue create mode 100644 src/components/icons/IconTheme.vue diff --git a/src/App.vue b/src/App.vue index 7324d7a..790f7ab 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,5 +1,5 @@ + + + + diff --git a/src/components/icons/IconEditor.vue b/src/components/icons/IconEditor.vue new file mode 100644 index 0000000..41117fe --- /dev/null +++ b/src/components/icons/IconEditor.vue @@ -0,0 +1,42 @@ + + + diff --git a/src/components/icons/IconGithub.vue b/src/components/icons/IconGithub.vue new file mode 100644 index 0000000..9606a60 --- /dev/null +++ b/src/components/icons/IconGithub.vue @@ -0,0 +1,22 @@ + + + diff --git a/src/components/icons/IconManager.vue b/src/components/icons/IconManager.vue new file mode 100644 index 0000000..ee05341 --- /dev/null +++ b/src/components/icons/IconManager.vue @@ -0,0 +1,32 @@ + + + diff --git a/src/components/icons/IconPresets.vue b/src/components/icons/IconPresets.vue new file mode 100644 index 0000000..ca673c8 --- /dev/null +++ b/src/components/icons/IconPresets.vue @@ -0,0 +1,33 @@ + + + diff --git a/src/components/icons/IconTheme.vue b/src/components/icons/IconTheme.vue new file mode 100644 index 0000000..b329226 --- /dev/null +++ b/src/components/icons/IconTheme.vue @@ -0,0 +1,102 @@ + + + + + diff --git a/src/style.css b/src/style.css index 2875238..41029d0 100644 --- a/src/style.css +++ b/src/style.css @@ -39,7 +39,7 @@ body { background-color: #ffffff; } a:hover { - color: #747bff; + color: #2da44e; } button { background-color: #f9f9f9; From 6e4cdd22f9e262e671b166783d089ec971411b23 Mon Sep 17 00:00:00 2001 From: kjqwer <2990346238@qq.com> Date: Sun, 7 Dec 2025 21:24:50 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E4=B8=BB=E9=A2=98=E6=A0=B7=E5=BC=8F?= =?UTF-8?q?=E6=8C=89=E9=92=AE=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.vue | 28 ++++++++++++--- src/components/icons/IconTheme.vue | 55 ++++++++++++++++++++++++++++-- 2 files changed, 77 insertions(+), 6 deletions(-) diff --git a/src/App.vue b/src/App.vue index 790f7ab..a77f038 100644 --- a/src/App.vue +++ b/src/App.vue @@ -58,6 +58,12 @@ function toggleTheme(event: MouseEvent) { return } + const willBeDark = !isDark.value + + if (willBeDark) { + document.documentElement.classList.add('theme-transition-reverse') + } + const x = event.clientX const y = event.clientY const endRadius = Math.hypot( @@ -66,7 +72,7 @@ function toggleTheme(event: MouseEvent) { ) const transition = document.startViewTransition(async () => { - isDark.value = !isDark.value + isDark.value = willBeDark localStorage.setItem('theme', isDark.value ? 'dark' : 'light') updateTheme() await nextTick() @@ -77,17 +83,25 @@ function toggleTheme(event: MouseEvent) { `circle(0px at ${x}px ${y}px)`, `circle(${endRadius}px at ${x}px ${y}px)` ] + + const isReverse = willBeDark + document.documentElement.animate( { - clipPath: clipPath, + clipPath: isReverse ? [...clipPath].reverse() : clipPath, }, { duration: 400, easing: 'ease-out', - pseudoElement: '::view-transition-new(root)', + pseudoElement: isReverse ? '::view-transition-old(root)' : '::view-transition-new(root)', + fill: 'forwards', } ) }) + + transition.finished.then(() => { + document.documentElement.classList.remove('theme-transition-reverse') + }) } function updateTheme() { @@ -192,7 +206,6 @@ const bgModeLabel = computed(() => { From 89d2330e72ec11ed05821cd005e19ea61619aeb3 Mon Sep 17 00:00:00 2001 From: kjqwer <2990346238@qq.com> Date: Sun, 7 Dec 2025 21:31:31 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E8=83=8C=E6=99=AF=E7=89=B9=E6=95=88?= =?UTF-8?q?=E5=88=87=E6=8D=A2=E7=BE=8E=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.vue | 83 +++++++++++++++++-- .../Background/BackgroundCanvas.vue | 1 + .../Background/GradientBackground.vue | 1 + src/components/Background/GridBackground.vue | 1 + 4 files changed, 79 insertions(+), 7 deletions(-) diff --git a/src/App.vue b/src/App.vue index a77f038..1000ea5 100644 --- a/src/App.vue +++ b/src/App.vue @@ -112,14 +112,83 @@ function switchView(view: 'editor' | 'manager' | 'presets') { currentView.value = view } -function cycleBackground() { - const currentIndex = bgModes.indexOf(currentBgMode.value) - const nextIndex = (currentIndex + 1) % bgModes.length - const nextMode = bgModes[nextIndex] - if (nextMode) { - currentBgMode.value = nextMode - localStorage.setItem('bg.mode', currentBgMode.value) +function cycleBackground(event?: MouseEvent) { + const isAppearanceTransition = 'startViewTransition' in document + && !window.matchMedia('(prefers-reduced-motion: reduce)').matches + && event instanceof MouseEvent + + const updateState = () => { + const currentIndex = bgModes.indexOf(currentBgMode.value) + const nextIndex = (currentIndex + 1) % bgModes.length + const nextMode = bgModes[nextIndex] + if (nextMode) { + currentBgMode.value = nextMode + localStorage.setItem('bg.mode', currentBgMode.value) + } } + + if (!isAppearanceTransition) { + updateState() + return + } + + const x = event.clientX + const y = event.clientY + + const transition = document.startViewTransition(async () => { + updateState() + await nextTick() + }) + + transition.ready.then(() => { + const effects = ['circle', 'vertical', 'horizontal', 'diamond'] + const effect = effects[Math.floor(Math.random() * effects.length)] + + let clipPath: string[] = [] + + if (effect === 'circle') { + const endRadius = Math.hypot( + Math.max(x, innerWidth - x), + Math.max(y, innerHeight - y) + ) + clipPath = [ + `circle(0px at ${x}px ${y}px)`, + `circle(${endRadius}px at ${x}px ${y}px)` + ] + } else if (effect === 'vertical') { + clipPath = [ + 'inset(0 0 100% 0)', + 'inset(0 0 0 0)' + ] + } else if (effect === 'horizontal') { + clipPath = [ + 'inset(0 100% 0 0)', + 'inset(0 0 0 0)' + ] + } else if (effect === 'diamond') { + const endRadius = Math.hypot( + Math.max(x, innerWidth - x), + Math.max(y, innerHeight - y) + ) * 1.5 // Multiply to ensure coverage for diamond shape + + clipPath = [ + `polygon(${x}px ${y}px, ${x}px ${y}px, ${x}px ${y}px, ${x}px ${y}px)`, + `polygon(${x}px ${y - endRadius}px, ${x + endRadius}px ${y}px, ${x}px ${y + endRadius}px, ${x - endRadius}px ${y}px)` + ] + } + + document.documentElement.animate( + { + clipPath: clipPath, + }, + { + duration: 1500, + easing: 'cubic-bezier(0.4, 0, 0.2, 1)', + pseudoElement: '::view-transition-new(root)', + fill: 'forwards', + } + ) + }) } const bgModeLabel = computed(() => { diff --git a/src/components/Background/BackgroundCanvas.vue b/src/components/Background/BackgroundCanvas.vue index a881982..31d649c 100644 --- a/src/components/Background/BackgroundCanvas.vue +++ b/src/components/Background/BackgroundCanvas.vue @@ -168,6 +168,7 @@ onMounted(() => { }) window.addEventListener('mousemove', onMouseMove, { passive: true }) document.addEventListener('visibilitychange', onVisibilityChange) + draw() // Initial draw to ensure no flicker raf = requestAnimationFrame(loop) }) diff --git a/src/components/Background/GradientBackground.vue b/src/components/Background/GradientBackground.vue index 571679b..9309165 100644 --- a/src/components/Background/GradientBackground.vue +++ b/src/components/Background/GradientBackground.vue @@ -185,6 +185,7 @@ onMounted(() => { initMesh() window.addEventListener('resize', onResize) window.addEventListener('mousemove', onMouseMove) + draw() // Initial draw raf = requestAnimationFrame(loop) }) diff --git a/src/components/Background/GridBackground.vue b/src/components/Background/GridBackground.vue index 4ca434a..108898c 100644 --- a/src/components/Background/GridBackground.vue +++ b/src/components/Background/GridBackground.vue @@ -132,6 +132,7 @@ onMounted(() => { resize() window.addEventListener('resize', resize) window.addEventListener('mousemove', onMouseMove) + draw() // Initial draw raf = requestAnimationFrame(loop) }) From dce07797b340b2dc0f0a95436340c5cb123f209b Mon Sep 17 00:00:00 2001 From: kjqwer <2990346238@qq.com> Date: Sun, 7 Dec 2025 21:39:33 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=BF=AB=E9=80=9F?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=9C=A8=E6=9F=90=E4=BA=9B=E7=94=B5=E8=84=91?= =?UTF-8?q?=E4=B8=8A=E7=9A=84=E5=8D=A1=E9=A1=BF=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/PromptQuickAdd.vue | 43 ++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/src/components/PromptQuickAdd.vue b/src/components/PromptQuickAdd.vue index 39e2698..68f173c 100644 --- a/src/components/PromptQuickAdd.vue +++ b/src/components/PromptQuickAdd.vue @@ -1,5 +1,5 @@ + + diff --git a/src/components/preset/PresetList.vue b/src/components/preset/PresetList.vue index 31fd777..46dd2c5 100644 --- a/src/components/preset/PresetList.vue +++ b/src/components/preset/PresetList.vue @@ -1,6 +1,7 @@ @@ -162,11 +222,13 @@ function formatDate(dateStr: string) { background-color: var(--color-bg-primary); border: 1px solid var(--color-border); border-radius: var(--radius-lg); - padding: 1rem; + padding: 0.75rem; display: flex; flex-direction: column; + align-items: stretch; transition: all 0.2s ease; position: relative; + text-align: left; } .preset-card:hover { @@ -183,8 +245,11 @@ function formatDate(dateStr: string) { .preset-type { font-size: 1.25rem; - margin-right: 0.75rem; + margin-right: 0.5rem; flex-shrink: 0; + line-height: 1; + display: flex; + align-items: center; } .preset-name { diff --git a/src/components/preset/TypeSelector.vue b/src/components/preset/TypeSelector.vue new file mode 100644 index 0000000..6993ade --- /dev/null +++ b/src/components/preset/TypeSelector.vue @@ -0,0 +1,207 @@ + + + + +