This commit is contained in:
fengchuanhn@gmail.com
2026-05-27 00:21:23 +08:00
parent 8f05a8e414
commit b43118112a
9 changed files with 1084 additions and 24 deletions

View File

@@ -0,0 +1,133 @@
<script setup>
import { computed } from "vue";
import { SUBTITLE_FONT_OPTIONS } from "../../config/subtitleStylePresets.js";
const line = defineModel("line", { type: Object, required: true });
const enableBackground = computed({
get: () =>
line.value.backgroundColor &&
line.value.backgroundColor !== "transparent" &&
(line.value.backgroundOpacity ?? 0) > 0,
set: (on) => {
if (on) {
line.value.backgroundColor = line.value.backgroundColor || "#000000";
line.value.backgroundOpacity = line.value.backgroundOpacity || 0.5;
} else {
line.value.backgroundColor = "transparent";
line.value.backgroundOpacity = 0;
}
},
});
const enableShadow = computed({
get: () => (line.value.shadowOffset ?? 0) > 0,
set: (on) => {
line.value.shadowOffset = on ? line.value.shadowOffset || 2 : 0;
},
});
const previewStyle = computed(() => {
const outline = Number(line.value.outlineWidth) || 0;
const offset = Number(line.value.shadowOffset) || 0;
const shadows = [];
if (outline > 0) {
const c = line.value.outlineColor || "#000";
for (let x = -outline; x <= outline; x++) {
for (let y = -outline; y <= outline; y++) {
if (x || y) shadows.push(`${x}px ${y}px 0 ${c}`);
}
}
}
if (offset > 0) {
shadows.push(`${offset}px ${offset}px 0 ${line.value.shadowColor || "#000"}`);
}
return {
fontFamily: line.value.fontName ? `'${line.value.fontName}'` : "优设标题黑",
fontSize: `${Math.min(Number(line.value.fontSize) || 80, 48)}px`,
color: line.value.fontColor || "#fff",
backgroundColor:
enableBackground.value && line.value.backgroundColor !== "transparent"
? line.value.backgroundColor
: "transparent",
textShadow: shadows.join(", ") || "none",
padding: "8px 16px",
};
});
</script>
<template>
<div class="line-style-editor space-y-4 text-slate-800">
<div>
<div class="mb-2 text-sm font-medium text-slate-700">字体设置</div>
<div class="space-y-3">
<div>
<label class="mb-1 block text-xs text-slate-500">字体</label>
<Select
v-model="line.fontName"
:options="SUBTITLE_FONT_OPTIONS"
option-label="label"
option-value="value"
class="w-full"
size="small"
/>
</div>
<div>
<label class="mb-1 block text-xs text-slate-500">字体大小像素</label>
<InputNumber v-model="line.fontSize" :min="24" :max="120" class="w-full" size="small" />
</div>
</div>
</div>
<div>
<div class="mb-2 text-sm font-medium text-slate-700">颜色设置</div>
<div class="flex items-center gap-2">
<input v-model="line.fontColor" type="color" class="h-8 w-10" />
<span class="font-mono text-xs">{{ line.fontColor }}</span>
</div>
</div>
<div>
<div class="mb-2 text-sm font-medium text-slate-700">描边设置</div>
<div class="space-y-2">
<div class="flex items-center gap-2">
<label class="text-xs text-slate-500">描边宽度</label>
<Slider v-model="line.outlineWidth" :min="0" :max="10" class="flex-1" />
<span class="w-8 text-right text-xs">{{ line.outlineWidth }}</span>
</div>
<div class="flex items-center gap-2">
<label class="text-xs text-slate-500">描边颜色</label>
<input v-model="line.outlineColor" type="color" class="h-8 w-10" />
</div>
</div>
</div>
<div>
<div class="mb-2 text-sm font-medium text-slate-700">背景设置</div>
<label class="flex items-center gap-2 text-sm">
<Checkbox v-model="enableBackground" binary />
启用背景
</label>
</div>
<div>
<div class="mb-2 text-sm font-medium text-slate-700">阴影设置可选</div>
<label class="mb-2 flex items-center gap-2 text-sm">
<Checkbox v-model="enableShadow" binary />
启用阴影
</label>
<div v-if="enableShadow" class="flex items-center gap-2">
<label class="text-xs text-slate-500">阴影偏移</label>
<Slider v-model="line.shadowOffset" :min="1" :max="10" class="flex-1" />
<input v-model="line.shadowColor" type="color" class="h-8 w-10" />
</div>
</div>
<div>
<div class="mb-2 text-sm font-medium text-slate-700">效果预览</div>
<div class="rounded bg-slate-100 py-4 text-center" :style="previewStyle">
{{ line.text || "标题文字" }}
</div>
</div>
</div>
</template>