summaryrefslogtreecommitdiff
path: root/packages/frontend/src/components/MkWatermarkEditorDialog.Layer.vue
diff options
context:
space:
mode:
Diffstat (limited to 'packages/frontend/src/components/MkWatermarkEditorDialog.Layer.vue')
-rw-r--r--packages/frontend/src/components/MkWatermarkEditorDialog.Layer.vue325
1 files changed, 325 insertions, 0 deletions
diff --git a/packages/frontend/src/components/MkWatermarkEditorDialog.Layer.vue b/packages/frontend/src/components/MkWatermarkEditorDialog.Layer.vue
new file mode 100644
index 0000000000..11ae091d90
--- /dev/null
+++ b/packages/frontend/src/components/MkWatermarkEditorDialog.Layer.vue
@@ -0,0 +1,325 @@
+<!--
+SPDX-FileCopyrightText: syuilo and misskey-project
+SPDX-License-Identifier: AGPL-3.0-only
+-->
+
+<template>
+<div :class="$style.root" class="_gaps">
+ <template v-if="layer.type === 'text'">
+ <MkInput v-model="layer.text">
+ <template #label>{{ i18n.ts._watermarkEditor.text }}</template>
+ </MkInput>
+
+ <FormSlot>
+ <template #label>{{ i18n.ts._watermarkEditor.position }}</template>
+ <MkPositionSelector
+ v-model:x="layer.align.x"
+ v-model:y="layer.align.y"
+ ></MkPositionSelector>
+ </FormSlot>
+
+ <MkRange
+ v-model="layer.scale"
+ :min="0"
+ :max="1"
+ :step="0.01"
+ :textConverter="(v) => (v * 100).toFixed(1) + '%'"
+ continuousUpdate
+ >
+ <template #label>{{ i18n.ts._watermarkEditor.scale }}</template>
+ </MkRange>
+
+ <MkRange
+ v-model="layer.angle"
+ :min="-1"
+ :max="1"
+ :step="0.01"
+ continuousUpdate
+ >
+ <template #label>{{ i18n.ts._watermarkEditor.angle }}</template>
+ </MkRange>
+
+ <MkRange
+ v-model="layer.opacity"
+ :min="0"
+ :max="1"
+ :step="0.01"
+ :textConverter="(v) => (v * 100).toFixed(1) + '%'"
+ continuousUpdate
+ >
+ <template #label>{{ i18n.ts._watermarkEditor.opacity }}</template>
+ </MkRange>
+
+ <MkSwitch v-model="layer.repeat">
+ <template #label>{{ i18n.ts._watermarkEditor.repeat }}</template>
+ </MkSwitch>
+ </template>
+
+ <template v-else-if="layer.type === 'image'">
+ <MkButton inline rounded primary @click="chooseFile">{{ i18n.ts.selectFile }}</MkButton>
+
+ <FormSlot>
+ <template #label>{{ i18n.ts._watermarkEditor.position }}</template>
+ <MkPositionSelector
+ v-model:x="layer.align.x"
+ v-model:y="layer.align.y"
+ ></MkPositionSelector>
+ </FormSlot>
+
+ <MkRange
+ v-model="layer.scale"
+ :min="0"
+ :max="1"
+ :step="0.01"
+ :textConverter="(v) => (v * 100).toFixed(1) + '%'"
+ continuousUpdate
+ >
+ <template #label>{{ i18n.ts._watermarkEditor.scale }}</template>
+ </MkRange>
+
+ <MkRange
+ v-model="layer.angle"
+ :min="-1"
+ :max="1"
+ :step="0.01"
+ continuousUpdate
+ >
+ <template #label>{{ i18n.ts._watermarkEditor.angle }}</template>
+ </MkRange>
+
+ <MkRange
+ v-model="layer.opacity"
+ :min="0"
+ :max="1"
+ :step="0.01"
+ :textConverter="(v) => (v * 100).toFixed(1) + '%'"
+ continuousUpdate
+ >
+ <template #label>{{ i18n.ts._watermarkEditor.opacity }}</template>
+ </MkRange>
+
+ <MkSwitch v-model="layer.repeat">
+ <template #label>{{ i18n.ts._watermarkEditor.repeat }}</template>
+ </MkSwitch>
+
+ <MkSwitch v-model="layer.cover">
+ <template #label>{{ i18n.ts._watermarkEditor.cover }}</template>
+ </MkSwitch>
+ </template>
+
+ <template v-else-if="layer.type === 'stripe'">
+ <MkRange
+ v-model="layer.frequency"
+ :min="1"
+ :max="30"
+ :step="0.01"
+ continuousUpdate
+ >
+ <template #label>{{ i18n.ts._watermarkEditor.stripeFrequency }}</template>
+ </MkRange>
+
+ <MkRange
+ v-model="layer.threshold"
+ :min="0"
+ :max="1"
+ :step="0.01"
+ continuousUpdate
+ >
+ <template #label>{{ i18n.ts._watermarkEditor.stripeWidth }}</template>
+ </MkRange>
+
+ <MkRange
+ v-model="layer.angle"
+ :min="-1"
+ :max="1"
+ :step="0.01"
+ continuousUpdate
+ >
+ <template #label>{{ i18n.ts._watermarkEditor.angle }}</template>
+ </MkRange>
+
+ <MkRange
+ v-model="layer.opacity"
+ :min="0"
+ :max="1"
+ :step="0.01"
+ :textConverter="(v) => (v * 100).toFixed(1) + '%'"
+ continuousUpdate
+ >
+ <template #label>{{ i18n.ts._watermarkEditor.opacity }}</template>
+ </MkRange>
+ </template>
+
+ <template v-else-if="layer.type === 'polkadot'">
+ <MkRange
+ v-model="layer.angle"
+ :min="-1"
+ :max="1"
+ :step="0.01"
+ continuousUpdate
+ >
+ <template #label>{{ i18n.ts._watermarkEditor.angle }}</template>
+ </MkRange>
+
+ <MkRange
+ v-model="layer.scale"
+ :min="0"
+ :max="10"
+ :step="0.01"
+ continuousUpdate
+ >
+ <template #label>{{ i18n.ts._watermarkEditor.scale }}</template>
+ </MkRange>
+
+ <MkRange
+ v-model="layer.majorRadius"
+ :min="0"
+ :max="1"
+ :step="0.01"
+ :textConverter="(v) => (v * 100).toFixed(1) + '%'"
+ continuousUpdate
+ >
+ <template #label>{{ i18n.ts._watermarkEditor.polkadotMainDotRadius }}</template>
+ </MkRange>
+
+ <MkRange
+ v-model="layer.majorOpacity"
+ :min="0"
+ :max="1"
+ :step="0.01"
+ :textConverter="(v) => (v * 100).toFixed(1) + '%'"
+ continuousUpdate
+ >
+ <template #label>{{ i18n.ts._watermarkEditor.polkadotMainDotOpacity }}</template>
+ </MkRange>
+
+ <MkRange
+ v-model="layer.minorDivisions"
+ :min="0"
+ :max="16"
+ :step="1"
+ continuousUpdate
+ >
+ <template #label>{{ i18n.ts._watermarkEditor.polkadotSubDotDivisions }}</template>
+ </MkRange>
+
+ <MkRange
+ v-model="layer.minorRadius"
+ :min="0"
+ :max="1"
+ :step="0.01"
+ :textConverter="(v) => (v * 100).toFixed(1) + '%'"
+ continuousUpdate
+ >
+ <template #label>{{ i18n.ts._watermarkEditor.polkadotSubDotRadius }}</template>
+ </MkRange>
+
+ <MkRange
+ v-model="layer.minorOpacity"
+ :min="0"
+ :max="1"
+ :step="0.01"
+ :textConverter="(v) => (v * 100).toFixed(1) + '%'"
+ continuousUpdate
+ >
+ <template #label>{{ i18n.ts._watermarkEditor.polkadotSubDotOpacity }}</template>
+ </MkRange>
+ </template>
+
+ <template v-else-if="layer.type === 'checker'">
+ <MkRange
+ v-model="layer.angle"
+ :min="-1"
+ :max="1"
+ :step="0.01"
+ continuousUpdate
+ >
+ <template #label>{{ i18n.ts._watermarkEditor.angle }}</template>
+ </MkRange>
+
+ <MkRange
+ v-model="layer.scale"
+ :min="0"
+ :max="10"
+ :step="0.01"
+ continuousUpdate
+ >
+ <template #label>{{ i18n.ts._watermarkEditor.scale }}</template>
+ </MkRange>
+
+ <MkRange
+ v-model="layer.opacity"
+ :min="0"
+ :max="1"
+ :step="0.01"
+ :textConverter="(v) => (v * 100).toFixed(1) + '%'"
+ continuousUpdate
+ >
+ <template #label>{{ i18n.ts._watermarkEditor.opacity }}</template>
+ </MkRange>
+ </template>
+</div>
+</template>
+
+<script setup lang="ts">
+import { ref, onMounted } from 'vue';
+import * as Misskey from 'misskey-js';
+import type { WatermarkPreset } from '@/utility/watermark.js';
+import { i18n } from '@/i18n.js';
+import MkButton from '@/components/MkButton.vue';
+import MkInput from '@/components/MkInput.vue';
+import MkSwitch from '@/components/MkSwitch.vue';
+import MkRange from '@/components/MkRange.vue';
+import FormSlot from '@/components/form/slot.vue';
+import MkPositionSelector from '@/components/MkPositionSelector.vue';
+import * as os from '@/os.js';
+import { selectFile } from '@/utility/drive.js';
+import { misskeyApi } from '@/utility/misskey-api.js';
+
+const layer = defineModel<WatermarkPreset['layers'][number]>('layer', { required: true });
+
+const driveFile = ref<Misskey.entities.DriveFile | null>(null);
+const driveFileError = ref(false);
+onMounted(async () => {
+ if (layer.value.type === 'image' && layer.value.imageId != null) {
+ await misskeyApi('drive/files/show', {
+ fileId: layer.value.imageId,
+ }).then((res) => {
+ driveFile.value = res;
+ }).catch((err) => {
+ driveFileError.value = true;
+ });
+ }
+});
+
+function chooseFile(ev: MouseEvent) {
+ selectFile({
+ anchorElement: ev.currentTarget ?? ev.target,
+ multiple: false,
+ label: i18n.ts.selectFile,
+ features: {
+ watermark: false,
+ },
+ }).then((file) => {
+ if (layer.value.type !== 'image') return;
+ if (!file.type.startsWith('image')) {
+ os.alert({
+ type: 'warning',
+ title: i18n.ts._watermarkEditor.driveFileTypeWarn,
+ text: i18n.ts._watermarkEditor.driveFileTypeWarnDescription,
+ });
+ return;
+ }
+
+ layer.value.imageId = file.id;
+ layer.value.imageUrl = file.url;
+ driveFileError.value = false;
+ });
+}
+</script>
+
+<style module>
+.root {
+
+}
+</style>