diff options
Diffstat (limited to 'packages/frontend/src/components/MkImageEffectorDialog.vue')
| -rw-r--r-- | packages/frontend/src/components/MkImageEffectorDialog.vue | 112 |
1 files changed, 30 insertions, 82 deletions
diff --git a/packages/frontend/src/components/MkImageEffectorDialog.vue b/packages/frontend/src/components/MkImageEffectorDialog.vue index 3d7801f925..85e86e3a77 100644 --- a/packages/frontend/src/components/MkImageEffectorDialog.vue +++ b/packages/frontend/src/components/MkImageEffectorDialog.vue @@ -16,37 +16,36 @@ SPDX-License-Identifier: AGPL-3.0-only > <template #header><i class="ti ti-sparkles"></i> {{ i18n.ts._imageEffector.title }}</template> - <div :class="$style.root"> - <div :class="$style.container"> - <div :class="[$style.preview, prefer.s.animation ? $style.animatedBg : null]"> - <canvas ref="canvasEl" :class="$style.previewCanvas" @pointerdown.prevent.stop="onImagePointerdown"></canvas> - <div :class="$style.previewContainer"> - <div class="_acrylic" :class="$style.previewTitle">{{ i18n.ts.preview }}</div> - <div class="_acrylic" :class="$style.editControls"> - <button class="_button" :class="[$style.previewControlsButton, penMode != null ? $style.active : null]" @click="showPenMenu"><i class="ti ti-pencil"></i></button> - </div> - <div class="_acrylic" :class="$style.previewControls"> - <button class="_button" :class="[$style.previewControlsButton, !enabled ? $style.active : null]" @click="enabled = false">Before</button> - <button class="_button" :class="[$style.previewControlsButton, enabled ? $style.active : null]" @click="enabled = true">After</button> - </div> + <MkPreviewWithControls> + <template #preview> + <canvas ref="canvasEl" :class="$style.previewCanvas" @pointerdown.prevent.stop="onImagePointerdown"></canvas> + <div :class="$style.previewContainer"> + <div class="_acrylic" :class="$style.previewTitle">{{ i18n.ts.preview }}</div> + <div class="_acrylic" :class="$style.editControls"> + <button class="_button" :class="[$style.previewControlsButton, penMode != null ? $style.active : null]" @click="showPenMenu"><i class="ti ti-pencil"></i></button> + </div> + <div class="_acrylic" :class="$style.previewControls"> + <button class="_button" :class="[$style.previewControlsButton, !enabled ? $style.active : null]" @click="enabled = false">Before</button> + <button class="_button" :class="[$style.previewControlsButton, enabled ? $style.active : null]" @click="enabled = true">After</button> </div> </div> - <div :class="$style.controls"> - <div class="_spacer _gaps"> - <XLayer - v-for="(layer, i) in layers" - :key="layer.id" - v-model:layer="layers[i]" - @del="onLayerDelete(layer)" - @swapUp="onLayerSwapUp(layer)" - @swapDown="onLayerSwapDown(layer)" - ></XLayer> + </template> - <MkButton rounded primary style="margin: 0 auto;" @click="addEffect"><i class="ti ti-plus"></i> {{ i18n.ts._imageEffector.addEffect }}</MkButton> - </div> + <template #controls> + <div class="_spacer _gaps"> + <XLayer + v-for="(layer, i) in layers" + :key="layer.id" + v-model:layer="layers[i]" + @del="onLayerDelete(layer)" + @swapUp="onLayerSwapUp(layer)" + @swapDown="onLayerSwapDown(layer)" + ></XLayer> + + <MkButton rounded primary style="margin: 0 auto;" @click="addEffect"><i class="ti ti-plus"></i> {{ i18n.ts._imageEffector.addEffect }}</MkButton> </div> - </div> - </div> + </template> + </MkPreviewWithControls> </MkModalWindow> </template> @@ -56,15 +55,12 @@ import type { ImageEffectorLayer } from '@/utility/image-effector/ImageEffector. import { i18n } from '@/i18n.js'; import { ImageEffector } from '@/utility/image-effector/ImageEffector.js'; import MkModalWindow from '@/components/MkModalWindow.vue'; -import MkSelect from '@/components/MkSelect.vue'; +import MkPreviewWithControls from '@/components/MkPreviewWithControls.vue'; import MkButton from '@/components/MkButton.vue'; -import MkInput from '@/components/MkInput.vue'; import XLayer from '@/components/MkImageEffectorDialog.Layer.vue'; import * as os from '@/os.js'; -import { deepClone } from '@/utility/clone.js'; import { FXS } from '@/utility/image-effector/fxs.js'; import { genId } from '@/utility/id.js'; -import { prefer } from '@/preferences.js'; const props = defineProps<{ image: File; @@ -99,7 +95,7 @@ watch(layers, async () => { } }, { deep: true }); -function addEffect(ev: MouseEvent) { +function addEffect(ev: PointerEvent) { os.popupMenu(Object.entries(FXS).map(([id, fx]) => ({ text: fx.uiDefinition.name, action: () => { @@ -223,7 +219,7 @@ watch(enabled, () => { const penMode = ref<'fill' | 'blur' | 'pixelate' | null>(null); -function showPenMenu(ev: MouseEvent) { +function showPenMenu(ev: PointerEvent) { os.popupMenu([{ text: i18n.ts._imageEffector._fxs.fill, action: () => { @@ -299,7 +295,7 @@ function onImagePointerdown(ev: PointerEvent) { scaleX: 0.1, scaleY: 0.1, angle: 0, - radius: 3, + radius: 10, ellipse: false, }, }); @@ -367,33 +363,6 @@ function onImagePointerdown(ev: PointerEvent) { </script> <style module> -.root { - container-type: inline-size; - height: 100%; -} - -.container { - height: 100%; - display: grid; - grid-template-columns: 1fr 400px; -} - -.preview { - position: relative; - background-color: var(--MI_THEME-bg); - background-image: linear-gradient(135deg, transparent 30%, var(--MI_THEME-panel) 30%, var(--MI_THEME-panel) 50%, transparent 50%, transparent 80%, var(--MI_THEME-panel) 80%, var(--MI_THEME-panel) 100%); - background-size: 20px 20px; -} - -.animatedBg { - animation: bg 1.2s linear infinite; -} - -@keyframes bg { - 0% { background-position: 0 0; } - 100% { background-position: -20px -20px; } -} - .previewContainer { display: flex; flex-direction: column; @@ -442,16 +411,6 @@ function onImagePointerdown(ev: PointerEvent) { } } -.previewSpinner { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - pointer-events: none; - user-select: none; - -webkit-user-drag: none; -} - .previewCanvas { position: absolute; top: 0; @@ -467,15 +426,4 @@ function onImagePointerdown(ev: PointerEvent) { object-fit: contain; touch-action: none; } - -.controls { - overflow-y: scroll; -} - -@container (max-width: 800px) { - .container { - grid-template-columns: 1fr; - grid-template-rows: 1fr 1fr; - } -} </style> |