diff --git a/locales/index.d.ts b/locales/index.d.ts index 172ef94b9b..2d5a5c18bb 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -10670,6 +10670,14 @@ export interface Locale extends ILocale { * 画像ファイルを選択してください */ "driveFileTypeWarnDescription": string; + /** + * 設定が不十分です + */ + "settingInvalidWarn": string; + /** + * プレビューが正常に表示されることを確認してから保存してください + */ + "settingInvalidWarnDescription": string; /** * 描画モード */ diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index dcd7190b63..3bfb4de4f6 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -2845,6 +2845,8 @@ _followRequest: _watermarkEditor: driveFileTypeWarn: "このファイルは対応していません" driveFileTypeWarnDescription: "画像ファイルを選択してください" + settingInvalidWarn: "設定が不十分です" + settingInvalidWarnDescription: "プレビューが正常に表示されることを確認してから保存してください" repeatSetting: "描画モード" repeat: "全体を埋め尽くす" padding: "余白" diff --git a/packages/frontend/src/components/MkWatermarkEditorDialog.vue b/packages/frontend/src/components/MkWatermarkEditorDialog.vue index a3550a0473..acc0a9ca16 100644 --- a/packages/frontend/src/components/MkWatermarkEditorDialog.vue +++ b/packages/frontend/src/components/MkWatermarkEditorDialog.vue @@ -125,16 +125,11 @@ function cancel() { emit('cancel'); dialogEl.value?.close(); } - -function save() { - emit('ok'); - dialogEl.value?.close(); -} //#endregion //#region 設定 const useWatermark = computed(defaultStore.makeGetterSetter('useWatermark')); -const watermarkConfig = ref | null>(defaultStore.state.watermarkConfig ?? { +const watermarkConfig = ref(defaultStore.state.watermarkConfig ?? { opacity: 0.2, repeat: true, rotate: 15, @@ -195,6 +190,22 @@ const paddingBottom = computed({ get: () => watermarkConfig.value?.padding?.bottom ?? 0, set: (v) => setPadding('bottom', v), }); + +function save() { + if (canPreview(watermarkConfig.value)) { + defaultStore.set('watermarkConfig', watermarkConfig.value); + } else { + os.alert({ + type: 'warning', + title: i18n.ts._watermarkEditor.settingInvalidWarn, + text: i18n.ts._watermarkEditor.settingInvalidWarnDescription, + }); + return; + } + + emit('ok'); + dialogEl.value?.close(); +} //#endregion //#region ファイル選択 @@ -269,7 +280,6 @@ onMounted(() => { //#region paddingViewの制御 const focusedForm = ref<'top' | 'left' | 'right' | 'bottom' | null>(null); - //#endregion diff --git a/packages/frontend/src/scripts/watermark.ts b/packages/frontend/src/scripts/watermark.ts index 4ef0f485e6..17287f5fe5 100644 --- a/packages/frontend/src/scripts/watermark.ts +++ b/packages/frontend/src/scripts/watermark.ts @@ -84,17 +84,19 @@ export async function applyWatermark(img: string | Blob, el: HTMLCanvasElement, const desiredHeight = canvas.height * (config.sizeRatio ?? 1); if ( - (watermarkAspectRatio > 1 && canvasAspectRatio > 1) || - (watermarkAspectRatio < 1 && canvasAspectRatio < 1) + (watermarkAspectRatio > 1 && canvasAspectRatio > 1) || // 両方横長 + (watermarkAspectRatio < 1 && canvasAspectRatio < 1) // 両方縦長 ) { + // 横幅を基準にウォーターマークのサイズを決定 return { width: desiredWidth, - height: desiredWidth / watermarkAspectRatio + height: desiredWidth / watermarkAspectRatio, }; } else { + // 縦幅を基準にウォーターマークのサイズを決定 return { width: desiredHeight * watermarkAspectRatio, - height: desiredHeight + height: desiredHeight, }; } })(); @@ -102,7 +104,7 @@ export async function applyWatermark(img: string | Blob, el: HTMLCanvasElement, ctx.globalAlpha = config.opacity ?? 1; if (config.repeat) { - // 余白をもたせた状態のウォーターマークを作成しておく + // 余白をもたせた状態のウォーターマークを作成しておく(それをパターン繰り返しする) const resizedWatermark = document.createElement('canvas'); resizedWatermark.width = width + (config.padding ? (config.padding.left ?? 0) + (config.padding.right ?? 0) : 0); resizedWatermark.height = height + (config.padding ? (config.padding.top ?? 0) + (config.padding.bottom ?? 0) : 0);