From cd9322a8243b12632db2dd9a29a702d7531a5aa0 Mon Sep 17 00:00:00 2001
From: syuilo <4439005+syuilo@users.noreply.github.com>
Date: Tue, 3 Jun 2025 19:18:29 +0900
Subject: feat(frontend): 画像編集機能 (#16121)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* wip

* wip

* wip

* wip

* Update watermarker.ts

* wip

* wip

* Update watermarker.ts

* Update MkUploaderDialog.vue

* wip

* Update ImageEffector.ts

* Update ImageEffector.ts

* wip

* wip

* wip

* wip

* wip

* wip

* Update MkRange.vue

* Update MkRange.vue

* wip

* wip

* Update MkImageEffectorDialog.vue

* Update MkImageEffectorDialog.Layer.vue

* wip

* Update zoomLines.ts

* Update zoomLines.ts

* wip

* wip

* Update ImageEffector.ts

* wip

* Update ImageEffector.ts

* wip

* Update ImageEffector.ts

* swip

* wip

* Update ImageEffector.ts

* wop

* Update MkUploaderDialog.vue

* Update ImageEffector.ts

* wip

* wip

* wip

* Update def.ts

* Update def.ts

* test

* test

* Update manager.ts

* Update manager.ts

* Update manager.ts

* Update manager.ts

* Update MkImageEffectorDialog.vue

* wip

* use WEBGL_lose_context

* wip

* Update MkUploaderDialog.vue

* Update drive.vue

* wip

* Update MkUploaderDialog.vue

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip
---
 packages/frontend/src/components/MkRange.vue | 68 +++++++++++++++++++++++-----
 1 file changed, 57 insertions(+), 11 deletions(-)

(limited to 'packages/frontend/src/components/MkRange.vue')

diff --git a/packages/frontend/src/components/MkRange.vue b/packages/frontend/src/components/MkRange.vue
index f36e68b687..9a6a207c74 100644
--- a/packages/frontend/src/components/MkRange.vue
+++ b/packages/frontend/src/components/MkRange.vue
@@ -12,7 +12,12 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<slot name="prefix"></slot>
 		<div ref="containerEl" class="container">
 			<div class="track">
-				<div class="highlight" :style="{ width: (steppedRawValue * 100) + '%' }"></div>
+				<div class="highlight right" :style="{ width: ((steppedRawValue - minRatio) * 100) + '%', left: (Math.abs(Math.min(0, min)) / (max + Math.abs(Math.min(0, min)))) * 100 + '%' }">
+					<div class="shine right"></div>
+				</div>
+				<div class="highlight left" :style="{ width: ((minRatio - steppedRawValue) * 100) + '%', left: (steppedRawValue) * 100 + '%' }">
+					<div class="shine left"></div>
+				</div>
 			</div>
 			<div v-if="steps && showTicks" class="ticks">
 				<div v-for="i in (steps + 1)" class="tick" :style="{ left: (((i - 1) / steps) * 100) + '%' }"></div>
@@ -24,7 +29,9 @@ SPDX-License-Identifier: AGPL-3.0-only
 				@mouseenter.passive="onMouseenter"
 				@mousedown="onMousedown"
 				@touchstart="onMousedown"
-			></div>
+			>
+				<div class="thumbInner"></div>
+			</div>
 		</div>
 		<slot name="suffix"></slot>
 	</div>
@@ -63,6 +70,9 @@ const emit = defineEmits<{
 const containerEl = useTemplateRef('containerEl');
 const thumbEl = useTemplateRef('thumbEl');
 
+const maxRatio = computed(() => Math.abs(props.max) / (props.max + Math.abs(Math.min(0, props.min))));
+const minRatio = computed(() => Math.abs(Math.min(0, props.min)) / (props.max + Math.abs(Math.min(0, props.min))));
+
 const rawValue = ref((props.modelValue - props.min) / (props.max - props.min));
 const steppedRawValue = computed(() => {
 	if (props.step) {
@@ -222,15 +232,17 @@ function onMousedown(ev: MouseEvent | TouchEvent) {
 		}
 	}
 
-	$thumbHeight: 20px;
-	$thumbWidth: 20px;
+	$thumbHeight: 32px;
+	$thumbWidth: 32px;
+	$thumbInnerHeight: 19px;
+	$thumbInnerWidth: 19px;
 
 	> .body {
 		display: flex;
 		align-items: center;
 		justify-content: center;
 		gap: 8px;
-		padding: 7px 12px;
+		padding: 0px 4px;
 		background: var(--MI_THEME-panel);
 		border: solid 1px var(--MI_THEME-panel);
 		border-radius: 6px;
@@ -256,10 +268,30 @@ function onMousedown(ev: MouseEvent | TouchEvent) {
 				> .highlight {
 					position: absolute;
 					top: 0;
-					left: 0;
 					height: 100%;
-					background: var(--MI_THEME-accent);
-					opacity: 0.5;
+					background: color(from var(--MI_THEME-buttonGradateA) srgb r g b / 0.5);
+					overflow: clip;
+
+					> .shine {
+						position: absolute;
+						top: 0;
+						width: 64px;
+						height: 100%;
+					}
+				}
+
+				> .highlight.right {
+					> .shine.right {
+						right: calc(#{$thumbInnerWidth} / 2);
+						background: linear-gradient(-90deg, var(--MI_THEME-buttonGradateB), color(from var(--MI_THEME-buttonGradateA) srgb r g b / 0));
+					}
+				}
+
+				> .highlight.left {
+					> .shine.left {
+						left: calc(#{$thumbInnerWidth} / 2);
+						background: linear-gradient(90deg, var(--MI_THEME-buttonGradateB), color(from var(--MI_THEME-buttonGradateA) srgb r g b / 0));
+					}
 				}
 			}
 
@@ -290,11 +322,25 @@ function onMousedown(ev: MouseEvent | TouchEvent) {
 				width: $thumbWidth;
 				height: $thumbHeight;
 				cursor: grab;
-				background: var(--MI_THEME-accent);
-				border-radius: 999px;
 
 				&:hover {
-					background: hsl(from var(--MI_THEME-accent) h s calc(l + 10));
+					> .thumbInner {
+						background: hsl(from var(--MI_THEME-accent) h s calc(l + 10));
+					}
+				}
+
+				> .thumbInner {
+					position: absolute;
+					top: 0;
+					left: 0;
+					right: 0;
+					bottom: 0;
+					margin: auto;
+					width: $thumbInnerWidth;
+					height: $thumbInnerHeight;
+					background: var(--MI_THEME-accent);
+					border-radius: 999px;
+					pointer-events: none;
 				}
 			}
 		}
-- 
cgit v1.2.3-freya

