布局修改 部分bug修复

This commit is contained in:
X1627315083
2025-08-22 10:27:48 +08:00
parent 141821a843
commit 594bf5ce0a
275 changed files with 5675 additions and 13049 deletions

View File

@@ -5,7 +5,7 @@
<!-- 笔刷类型选择 -->
<div class="brush-section">
<div class="section-header">
<span>笔刷类型</span>
<span>{{ $t('Canvas.BrushType') }}</span>
</div>
<div class="brush-type-grid">
<div
@@ -314,14 +314,14 @@
<!-- 阴影设置 -->
<div class="brush-section">
<div class="section-header">
<span>{{ $t("阴影设置") }}</span>
<span>{{ $t("Canvas.ShadowSettings") }}</span>
</div>
<div class="property-list">
<!-- 阴影开关 -->
<div class="property-item">
<div class="checkbox-property">
<span>{{ $t("启用阴影") }}</span>
<span>{{ $t("Canvas.EnableShadows") }}</span>
<div class="toggle-switch">
<input
type="checkbox"
@@ -340,7 +340,7 @@
<div class="property-item">
<div class="color-property">
<div class="color-header">
<span>{{ $t("阴影颜色") }}</span>
<span>{{ $t("Canvas.ShadowColor") }}</span>
<div
class="color-preview"
:style="{ backgroundColor: brushStore.state.shadowColor }"
@@ -361,7 +361,7 @@
<div class="property-item">
<div class="slider-property">
<div class="slider-header">
<span>{{ $t("阴影宽度") }}</span>
<span>{{ $t("Canvas.ShadowWidth") }}</span>
<span class="slider-value">{{ brushStore.state.shadowWidth }}px</span>
</div>
<div class="slider-container">
@@ -396,7 +396,7 @@
<div class="property-item">
<div class="slider-property">
<div class="slider-header">
<span>{{ $t("阴影X偏移") }}</span>
<span>{{ $t("Canvas.ShadowOffsetX") }}</span>
<span class="slider-value">{{ brushStore.state.shadowOffsetX }}px</span>
</div>
<div class="slider-container">
@@ -432,7 +432,7 @@
<div class="property-item">
<div class="slider-property">
<div class="slider-header">
<span>{{ $t("阴影Y偏移") }}</span>
<span>{{ $t("Canvas.ShadowOffsetY") }}</span>
<span class="slider-value">{{ brushStore.state.shadowOffsetY }}px</span>
</div>
<div class="slider-container">
@@ -467,7 +467,7 @@
<!-- 阴影预览 -->
<div class="property-item">
<div class="shadow-preview-container">
<div class="shadow-preview-title">{{ $t("阴影预览") }}</div>
<div class="shadow-preview-title">{{ $t("Canvas.ShadowPreview") }}</div>
<div class="shadow-preview-box">
<div
class="shadow-preview-element"
@@ -489,7 +489,7 @@
<!-- 笔刷预设 -->
<div class="brush-section">
<div class="section-header">
<span>笔刷预设</span>
<span>{{ $t('Canvas.BrushPreset') }}</span>
<button class="save-preset-btn" @click="saveCurrentAsPreset" title="保存当前设置为预设">
<i class="save-icon">+</i>
</button>
@@ -904,7 +904,7 @@ const brushStore = BrushStore;
/* overflow-y: auto; */
min-width: 280px;
border-left: 1px solid rgba(0, 0, 0, 0.05); /* 更柔和的边框 */
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
font-family: pingfang_medium, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
animation: panelFadeIn 0.3s ease;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); /* 添加阴影效果 */
backdrop-filter: blur(2px); /* 添加模糊效果 */
@@ -1066,7 +1066,7 @@ const brushStore = BrushStore;
background-color: rgba(0, 0, 0, 0.05);
padding: 3px 7px;
border-radius: 4px;
font-family: "Consolas", monospace;
font-family: pingfang_medium, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
.slider-container {

View File

@@ -272,7 +272,7 @@ onMounted(() => {
<template>
<div class="canvas-header">
<div class="canvas-header-wrapper">
<span class="canvas-title">Canvas</span>
<span class="canvas-title">{{ $t('Canvas.Canvas') }}</span>
<!-- 默认设置 -->
<!-- v-if="
!activeTool ||
@@ -283,7 +283,7 @@ onMounted(() => {
<div class="setting-group">
<span class="setting-label">{{ $t("Canvas.width") }}</span>
<a-input-number
:value="canvasWidth"
:value="canvasWidth?.toFixed(2)"
class="setting-input"
:min="1"
:max="9999"
@@ -299,7 +299,7 @@ onMounted(() => {
<div class="setting-group">
<span class="setting-label">{{ $t("Canvas.height") }}</span>
<a-input-number
:value="canvasHeight"
:value="canvasHeight?.toFixed(2)"
class="setting-input"
:min="1"
:max="9999"

View File

@@ -33,7 +33,7 @@
<!-- 参数调整区域 -->
<div class="liquify-params">
<div class="param-item">
<div class="param-label">尺寸</div>
<div class="param-label">{{ $t('liquifyPanel.size') }}</div>
<div class="param-control">
<input
type="range"
@@ -48,7 +48,7 @@
</div>
<div class="param-item">
<div class="param-label">压力</div>
<div class="param-label">{{ $t('liquifyPanel.pressure') }}</div>
<div class="param-control">
<input
type="range"
@@ -63,7 +63,7 @@
</div>
<div class="param-item" v-if="showDistortion">
<div class="param-label">失真</div>
<div class="param-label">{{ $t('liquifyPanel.distortion') }}</div>
<div class="param-control">
<input
type="range"
@@ -78,7 +78,7 @@
</div>
<div class="param-item">
<div class="param-label">动力</div>
<div class="param-label">{{ $t('liquifyPanel.power') }}</div>
<div class="param-control">
<input
type="range"
@@ -139,6 +139,9 @@ import { OperationType } from "../utils/layerHelper";
import { LiquifyRealTimeUpdater } from "../managers/liquify/LiquifyRealTimeUpdater";
import { LiquifyStateManager } from "../managers/liquify/LiquifyStateManager";
import { Modal } from "ant-design-vue";
import { useI18n } from "vue-i18n";
const {t} = useI18n()
// Props定义
const props = defineProps({
@@ -227,9 +230,9 @@ const stateManager = ref(null);
// 可用液化模式
const availableModes = ref([
{ id: "push", name: "推", iconText: "↔" },
{ id: "clockwise", name: "顺时针转动", iconText: "↻" },
{ id: "counterclockwise", name: "逆时针转动", iconText: "↺" },
{ id: "push", name: t('liquifyPanel.push'), iconText: "↔" },
{ id: "clockwise", name: t('liquifyPanel.clockwise'), iconText: "↻" },
{ id: "counterclockwise", name: t('liquifyPanel.counterclockwise'), iconText: "↺" },
// { id: "pinch", name: "捏合", iconText: "⤢" },
// { id: "expand", name: "展开", iconText: "⤡" },
// { id: "crystal", name: "水晶", iconText: "✧" },

View File

@@ -2,6 +2,8 @@
import { ref, inject, computed, onMounted, onUnmounted } from "vue";
import { findLayerRecursively, OperationType } from "../utils/layerHelper";
import ToolButton from "../../ExistsImageList/ToolButton.vue";
import { useI18n } from 'vue-i18n'
const emit = defineEmits([
"tool-selected",
@@ -15,7 +17,7 @@ const emit = defineEmits([
"toggle-red-green-mode",
"undo-redo-status-changed",
]);
const {t} = useI18n()
const props = defineProps({
activeTool: String,
minimapEnabled: {
@@ -62,63 +64,63 @@ const redoFun = () => commandManager.redo();
const normalToolsList = ref([
{
id: "undo",
title: "Undo",
title: t("Canvas.undo"),
action: undo,
icon: { name: "CUndo", size: "20" },
class: "undo-btn",
},
{
id: "redo",
title: "Redo",
title: t("Canvas.Redo"),
action: redo,
icon: { name: "CRedo", size: "20" },
class: "redo-btn",
},
{
id: OperationType.DRAW,
title: "Drawing",
title: t("Canvas.Drawing"),
action: () => selectTool(OperationType.DRAW),
icon: { name: "CBrush", size: "24" },
class: "draw-btn",
},
{
id: OperationType.ERASER,
title: "Eraser",
title: t("Canvas.Eraser"),
action: () => selectTool(OperationType.ERASER),
icon: { name: "CEraser", size: "22" },
class: "eraser-btn",
},
{
id: "fillColor",
title: "Fill Color",
title: t("Canvas.FillColor"),
action: () => fillColorRef.value.click(),
icon: { name: "CThemeColor", size: "22" },
class: "fill-color-btn",
},
{
id: OperationType.PAN,
title: "Pan",
title: t("Canvas.Pan"),
action: () => selectTool(OperationType.PAN),
icon: { name: "CHand", size: "28" },
class: "hand-btn",
},
{
id: OperationType.SELECT,
title: "Select",
title: t("Canvas.Select"),
action: () => selectTool(OperationType.SELECT),
icon: { name: "CSelect", size: "28" },
class: "select-btn",
},
{
id: OperationType.LIQUIFY,
title: "Liquefying",
title: t("Canvas.Liquefying"),
action: () => selectTool(OperationType.LIQUIFY),
icon: { name: "CLiquefying", size: "32" },
class: "liquify-btn",
},
{
id: OperationType.LASSO,
title: "Lasso",
title: t("Canvas.Lasso"),
action: () => selectTool(OperationType.LASSO),
icon: { name: "CLasso", size: "28" },
class: "lasso-btn",
@@ -131,28 +133,28 @@ const normalToolsList = ref([
},
{
id: "zoomIn",
title: "Zoom In",
title: t("Canvas.ZoomIn"),
action: zoomIn,
icon: { name: "CZoomIn", size: "30" },
class: "zoom-in-btn",
},
{
id: "zoomOut",
title: "Zoom Out",
title: t("Canvas.ZoomOut"),
action: zoomOut,
icon: { name: "CZoomOut", size: "26" },
class: "zoom-out-btn",
},
{
id: "upload",
title: "Upload Image",
title: t("Canvas.Upload"),
action: triggerImageUpload,
icon: { name: "CUpload", size: "26" },
class: "upload-btn",
},
{
id: "addText",
title: "Add Text",
title: t("Canvas.AddText"),
action: () => addText(),
icon: { name: "CFont", size: "20" },
class: "text-btn",
@@ -163,14 +165,14 @@ const normalToolsList = ref([
const redGreenToolsList = ref([
{
id: "undo",
title: "Undo",
title: t("Canvas.undo"),
action: undo,
icon: { name: "CUndo", size: "20" },
class: "undo-btn",
},
{
id: "redo",
title: "Redo",
title: t("Canvas.Redo"),
action: redo,
icon: { name: "CRedo", size: "20" },
class: "redo-btn",
@@ -193,21 +195,21 @@ const redGreenToolsList = ref([
},
{
id: OperationType.ERASER,
title: "Eraser (E)",
title: t("Canvas.Eraser"),
action: () => selectTool(OperationType.ERASER, true),
icon: { name: "CEraser", size: "22" },
class: "eraser-btn",
},
{
id: "zoomIn",
title: "Zoom In",
title: t("Canvas.ZoomIn"),
action: zoomIn,
icon: { name: "CZoomIn", size: "30" },
class: "zoom-in-btn",
},
{
id: "zoomOut",
title: "Zoom Out",
title: t("Canvas.ZoomOut"),
action: zoomOut,
icon: { name: "CZoomOut", size: "26" },
class: "zoom-out-btn",

View File

@@ -118,7 +118,7 @@ const canvasManagerLoaded = ref(false); // 画布是否加载完成
// 红绿图模式状态
const isRedGreenMode = ref(false);
const isShowLayerPanel = ref(true); // 是否显示图层面板
const isShowLayerPanel = ref(false); // 是否显示图层面板
provide("isShowLayerPanel", isShowLayerPanel); // 提供红绿图模式状态给子组件
@@ -255,6 +255,7 @@ onMounted(async () => {
layerManager,
activeTool, // 响应式引用,存储当前选中的工具
brushSize: brushSize.value, // 可选,初始画笔大小
t, // 国际化函数
});
// 初始化文本编辑功能
@@ -1127,7 +1128,7 @@ defineExpose({
flex-direction: column;
/* height: 100vh; */
background-color: #ffffff;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
font-family: pingfang_medium, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
position: absolute;
left: 0;
right: 0;

View File

@@ -26,12 +26,14 @@ export class ToolManager {
* @param {Object} options.layerManager 图层管理实例
* @param {Object} options.brushManager 画笔管理器实例(可选,如果不提供会创建一个)
* @param {Object} options.activeTool 当前活动工具的响应式引用
* @param {Function} options.t 国际化函数
*/
constructor(options = {}) {
this.canvas = options.canvas;
this.commandManager = options.commandManager;
this.canvasManager = options.canvasManager;
this.layerManager = options.layerManager;
this.t = options.t
this.activeTool = options.activeTool || {
value: OperationType.SELECT,
};
@@ -47,6 +49,7 @@ export class ToolManager {
canvas: this.canvas,
brushSize: options.brushSize,
layerManager: this.layerManager, // 传入图层管理器引用
t:this.t
});
// 初始化笔刷指示器

View File

@@ -7,11 +7,12 @@ export class BaseBrush {
* 构造函数
* @param {Object} canvas fabric画布实例
* @param {Object} options 笔刷配置选项
* @param {Object} t 翻译函数
*/
constructor(canvas, options = {}) {
this.canvas = canvas;
this.options = options;
this.t = options.t;
// 基本属性
this.id = options.id || this.constructor.name;
this.name = options.name || "未命名笔刷";
@@ -211,35 +212,35 @@ export class BaseBrush {
return [
{
id: "size",
name: "笔刷大小",
name: this.t('Canvas.BrushSize'),
type: "slider",
defaultValue: 5,
min: 0.5,
max: 100,
step: 0.5,
description: "笔刷的大小(像素)",
category: "基本",
description: this.t('Canvas.BrushDeSize'),
category: this.t('Canvas.basic'),
order: 10,
},
{
id: "color",
name: "笔刷颜色",
name: this.t('Canvas.BrushColor'),
type: "color",
defaultValue: "#000000",
description: "笔刷的颜色",
category: "基本",
description: this.t('Canvas.BrushDeColor'),
category: this.t('Canvas.basic'),
order: 20,
},
{
id: "opacity",
name: "不透明度",
name: this.t('Canvas.BrushOpacity'),
type: "slider",
defaultValue: 1,
min: 0.05,
max: 1,
step: 0.01,
description: "笔刷的不透明度",
category: "基本",
description: this.t('Canvas.BrushdeOpacity'),
category: this.t('Canvas.basic'),
order: 30,
},
];

View File

@@ -33,11 +33,13 @@ export class BrushManager {
* @param {Object} options.canvas fabric.js画布实例
* @param {Object} options.brushStore 笔刷数据存储(可选)
* @param {Object} options.layerManager 图层管理器实例(可选)
* @param {Function} options.t 国际化函数
*/
constructor(options = {}) {
this.canvas = options.canvas;
this.brushStore = options.brushStore || BrushStore;
this.layerManager = options.layerManager; // 添加图层管理器引用
this.t = options.t
// 当前活动笔刷
this.activeBrush = null;
@@ -59,76 +61,89 @@ export class BrushManager {
_registerDefaultBrushes() {
// 注册铅笔笔刷
brushRegistry.register("pencil", PencilBrush, {
name: "Pencil",
name: this.t("Canvas.Pencil"),
description: "基础铅笔工具,适合精细线条绘制",
category: "基础笔刷",
t:this.t,
category: this.t('Canvas.BasicBrushes'),
});
// 注册材质笔刷
brushRegistry.register("texture", TextureBrush, {
name: "Texture",
name: this.t("Canvas.Texture"),
description: "使用纹理图片作为笔刷,支持缩放和透明度",
category: "基础笔刷",
t:this.t,
category: this.t('Canvas.BasicBrushes'),
});
// 注册集成的笔刷类型
brushRegistry.register("crayon", CrayonBrush, {
name: "Crayon",
name: this.t("Canvas.Crayon"),
description: "使用纹理图片作为笔刷,支持缩放和透明度",
category: "基础笔刷",
t:this.t,
category: this.t('Canvas.BasicBrushes'),
});
brushRegistry.register("fur", FurBrush, {
name: "Fur",
name: this.t("Canvas.Fur"),
description: "使用纹理图片作为笔刷,支持缩放和透明度",
category: "基础笔刷",
t:this.t,
category: this.t('Canvas.BasicBrushes'),
});
brushRegistry.register("ink", InkBrush, {
name: "Ink",
name: this.t("Canvas.Ink"),
description: "墨水笔刷,适合书写和绘图",
category: "基础笔刷",
t:this.t,
category: this.t('Canvas.BasicBrushes'),
});
brushRegistry.register("", LongfurBrush, {
name: "Longfur",
name: this.t("Canvas.Longfur"),
description: "长毛发笔刷,适合绘制动物毛皮、草或头发",
category: "基础笔刷",
t:this.t,
category: this.t('Canvas.BasicBrushes'),
});
brushRegistry.register("writing", WritingBrush, {
name: "Writing",
name: this.t("Canvas.Writing"),
description: "书法笔刷,模拟中国传统书法毛笔效果,具有笔锋和墨色变化",
category: "基础笔刷",
t:this.t,
category: this.t('Canvas.BasicBrushes'),
});
brushRegistry.register("marker", MarkerBrush, {
name: "Marker",
name: this.t("Canvas.Marker"),
description: "马克笔笔刷,适合粗线条和填充",
category: "基础笔刷",
t:this.t,
category: this.t('Canvas.BasicBrushes'),
});
brushRegistry.register("pen", CustomPenBrush, {
name: "Pen",
name: this.t("Canvas.Pen"),
description: "自定义钢笔笔刷,适合书写和绘图",
category: "基础笔刷",
t:this.t,
category: this.t('Canvas.BasicBrushes'),
});
brushRegistry.register("ribbon", RibbonBrush, {
name: "Ribbon",
name: this.t("Canvas.Ribbon"),
description: "丝带笔刷,适合创建流动的丝带效果",
category: "基础笔刷",
t:this.t,
category: this.t('Canvas.BasicBrushes'),
});
brushRegistry.register("shaded", ShadedBrush, {
name: "Shaded",
name: this.t("Canvas.Shaded"),
description: "阴影笔刷,适合创建渐变和阴影效果",
category: "基础笔刷",
t:this.t,
category: this.t('Canvas.BasicBrushes'),
});
brushRegistry.register("spray", SprayBrush, {
name: "spray",
name: this.t("Canvas.Spray"),
description: "模拟喷枪效果,创建散点效果",
category: "基础笔刷",
t:this.t,
category: this.t('Canvas.BasicBrushes'),
});
// brushRegistry.register("sketchy", SketchyBrush);
// brushRegistry.register("spraypaint", SpraypaintBrush, {
// name: "Spraypaint",
// description: "喷漆笔刷,模拟喷漆效果",
// category: "基础笔刷",
// t:this.t,
// category: this.t('Canvas.BasicBrushes'),
// });
// // // 注册喷枪笔刷
@@ -140,7 +155,7 @@ export class BrushManager {
// id: "spray",
// name: "Spray",
// description: "模拟喷枪效果,创建散点效果",
// category: "基础笔刷",
// category: this.t('Canvas.BasicBrushes'),
// ...options,
// });
// }

View File

@@ -13,9 +13,9 @@ export class CrayonBrush extends BaseBrush {
constructor(canvas, options = {}) {
super(canvas, {
id: "crayon",
name: "蜡笔",
name: options.t("Canvas.Crayon"),
description: "模拟蜡笔效果,具有颗粒感和纹理",
category: "特效笔刷",
category: options.t("Canvas.SpecialEffectsBrush"),
icon: "crayon",
...options,
});
@@ -27,6 +27,7 @@ export class CrayonBrush extends BaseBrush {
this._inkAmount = options._inkAmount || 10;
this.randomness = options.randomness || 0.5; // 随机性
this.texture = options.texture || "default"; // 纹理类型
this.t = options.t
}
/**
@@ -149,52 +150,52 @@ export class CrayonBrush extends BaseBrush {
const crayonProperties = [
{
id: "separation",
name: "颗粒分离度",
name: this.t('Canvas.ParticleSeparationDegree'),
type: "slider",
defaultValue: this._sep,
min: 0.5,
max: 10,
step: 0.5,
description: "控制蜡笔颗粒的分离程度",
category: "蜡笔设置",
description: this.t('Canvas.ParticleSeparationDegreeDescription'),
category: this.t('Canvas.PencilSettings'),
order: 100,
},
{
id: "inkAmount",
name: "墨量",
name: this.t('Canvas.TheAmountOfInk'),
type: "slider",
defaultValue: this._inkAmount,
min: 1,
max: 50,
step: 1,
description: "控制蜡笔的颜料量",
category: "蜡笔设置",
description: this.t('Canvas.TheAmountOfInkDescription'),
category: this.t('Canvas.PencilSettings'),
order: 110,
},
{
id: "randomness",
name: "随机性",
name: this.t('Canvas.randomness'),
type: "slider",
defaultValue: this.randomness,
min: 0,
max: 1,
step: 0.05,
description: "控制蜡笔纹理的随机程度",
category: "蜡笔设置",
description: this.t('Canvas.randomnessDescription'),
category: this.t('Canvas.PencilSettings'),
order: 120,
},
{
id: "texture",
name: "纹理类型",
name: this.t('Canvas.TextureType'),
type: "select",
defaultValue: this.texture,
options: [
{ value: "default", label: "默认" },
{ value: "rough", label: "粗糙" },
{ value: "smooth", label: "平滑" },
{ value: "default", label: this.t('Canvas.Default') },
{ value: "rough", label: this.t('Canvas.Rough') },
{ value: "smooth", label: this.t('Canvas.Smooth') },
],
description: "设置蜡笔的纹理类型",
category: "蜡笔设置",
description: this.t('Canvas.TextureTypeDescription'),
category: this.t('Canvas.PencilSettings'),
order: 130,
},
];

View File

@@ -13,9 +13,9 @@ export class CustomPenBrush extends BaseBrush {
constructor(canvas, options = {}) {
super(canvas, {
id: "pen",
name: "钢笔",
name: options.t('Canvas.Pen'),
description: "模拟钢笔效果,具有变化的透明度",
category: "基础笔刷",
category: options.t('Canvas.BasicBrushes'),
icon: "pen",
...options,
});
@@ -115,38 +115,38 @@ export class CustomPenBrush extends BaseBrush {
const penProperties = [
{
id: "lineWidth",
name: "线条宽度",
name: this.t('Canvas.PenWidth'),
type: "slider",
defaultValue: this._lineWidth,
min: 1,
max: 10,
step: 0.5,
description: "控制钢笔线条的宽度",
category: "钢笔设置",
description: this.t('Canvas.PenWidthDescription'),
category: this.t('Canvas.PenSettings'),
order: 100,
},
{
id: "inkOpacityMin",
name: "最小墨水透明度",
name: this.t('Canvas.PenMinimumInkTransparency'),
type: "slider",
defaultValue: this.inkOpacityMin,
min: 0.1,
max: 0.5,
step: 0.05,
description: "控制钢笔墨水最小透明度",
category: "钢笔设置",
description: this.t('Canvas.PenMinimumInkTransparencyDescription'),
category: this.t('Canvas.PenSettings'),
order: 110,
},
{
id: "inkOpacityMax",
name: "最大墨水透明度",
name: this.t('Canvas.PenMaximumInkTransparency'),
type: "slider",
defaultValue: this.inkOpacityMax,
min: 0.3,
max: 1,
step: 0.05,
description: "控制钢笔墨水最大透明度",
category: "钢笔设置",
description: this.t('Canvas.PenMaximumInkTransparencyDescription'),
category: this.t('Canvas.PenSettings'),
order: 120,
},
];

View File

@@ -13,9 +13,9 @@ export class FurBrush extends BaseBrush {
constructor(canvas, options = {}) {
super(canvas, {
id: "fur",
name: "毛发笔刷",
name: options.t('Canvas.Longfur'),
description: "创建类似于毛发或草的纹理效果",
category: "特效笔刷",
category: options.t('Canvas.SpecialEffectsBrush'),
icon: "fur",
...options,
});
@@ -123,38 +123,38 @@ export class FurBrush extends BaseBrush {
const furProperties = [
{
id: "furLength",
name: "毛发长度",
name: this.t('Canvas.FurLength'),
type: "slider",
defaultValue: this.furLength,
min: 1,
max: 50,
step: 1,
description: "控制毛发的长度",
category: "毛发设置",
description: this.t('Canvas.FurLengthDescription'),
category: this.t('Canvas.FurSettings'),
order: 100,
},
{
id: "furDensity",
name: "毛发密度",
name: this.t('Canvas.FurDensity'),
type: "slider",
defaultValue: this.furDensity,
min: 0.1,
max: 1,
step: 0.05,
description: "控制毛发的密度",
category: "毛发设置",
description: this.t('Canvas.FurDensityDescription'),
category: this.t('Canvas.FurSettings'),
order: 110,
},
{
id: "furRandomness",
name: "随机性",
name: this.t('Canvas.FurRandomness'),
type: "slider",
defaultValue: this.furRandomness,
min: 0,
max: 1,
step: 0.05,
description: "控制毛发的随机分布程度",
category: "毛发设置",
description: this.t('Canvas.FurRandomnessDescription'),
category: this.t('Canvas.FurSettings'),
order: 120,
},
];

View File

@@ -13,9 +13,9 @@ export class InkBrush extends BaseBrush {
constructor(canvas, options = {}) {
super(canvas, {
id: "ink",
name: "水墨笔刷",
name: options.t('Canvas.Ink'),
description: "模拟中国传统水墨画效果,墨色深浅不一",
category: "特效笔刷",
category: options.t('Canvas.SpecialEffectsBrush'),
icon: "ink",
...options,
});
@@ -27,6 +27,7 @@ export class InkBrush extends BaseBrush {
this.splashEnabled = options.splashEnabled !== undefined ? options.splashEnabled : true;
this.splashSize = options.splashSize || 5;
this.splashDistance = options.splashDistance || 30;
this.t = options.t
}
/**
@@ -159,60 +160,60 @@ export class InkBrush extends BaseBrush {
const inkProperties = [
{
id: "inkAmount",
name: "墨量",
name: this.t('Canvas.InkAmount'),
type: "slider",
defaultValue: this._inkAmount,
min: 1,
max: 20,
step: 1,
description: "控制水墨的浓度",
category: "水墨设置",
description: this.t('Canvas.InkAmountDescription'),
category: this.t('Canvas.InkSettings'),
order: 100,
},
{
id: "range",
name: "笔触范围",
name: this.t('Canvas.InkRange'),
type: "slider",
defaultValue: this._range,
min: 5,
max: 50,
step: 1,
description: "控制水墨扩散的范围",
category: "水墨设置",
description: this.t('Canvas.InkRangeDescription'),
category: this.t('Canvas.InkSettings'),
order: 110,
},
{
id: "splashEnabled",
name: "溅墨效果",
name: this.t('Canvas.InkSplashEnabled'),
type: "checkbox",
defaultValue: this.splashEnabled,
description: "是否启用溅墨效果",
category: "水墨设置",
description: this.t('Canvas.InkSplashEnabledDescription'),
category: this.t('Canvas.InkSettings'),
order: 120,
},
{
id: "splashSize",
name: "溅墨大小",
name: this.t('Canvas.InkSize'),
type: "slider",
defaultValue: this.splashSize,
min: 1,
max: 20,
step: 1,
description: "溅墨点的大小",
category: "水墨设置",
description: this.t('Canvas.InkSizeDescription'),
category: this.t('Canvas.InkSettings'),
order: 130,
visibleWhen: { splashEnabled: true },
},
{
id: "splashDistance",
name: "溅墨距离",
name: this.t('Canvas.InkRandomness'),
type: "slider",
defaultValue: this.splashDistance,
min: 10,
max: 100,
step: 5,
description: "溅墨可扩散的最大距离",
category: "水墨设置",
description: this.t('Canvas.InkRandomnessDescription'),
category: this.t('Canvas.InkSettings'),
order: 140,
visibleWhen: { splashEnabled: true },
},

View File

@@ -13,9 +13,9 @@ export class LongfurBrush extends BaseBrush {
constructor(canvas, options = {}) {
super(canvas, {
id: "longfur",
name: "长毛发",
name: options.t('Canvas.Longfur'),
description: "创建流动的长毛发效果,适合绘制动物毛皮、草或头发",
category: "特效笔刷",
category: options.t('Canvas.SpecialEffectsBrush'),
icon: "longfur",
...options,
});
@@ -198,59 +198,59 @@ export class LongfurBrush extends BaseBrush {
const longfurProperties = [
{
id: "furLength",
name: "毛发长度",
name: this.t('Canvas.FurLength'),
type: "slider",
defaultValue: this.furLength,
min: 5,
max: 100,
step: 1,
description: "控制毛发的长度",
category: "长毛发设置",
description: this.t('Canvas.FurLengthDescription'),
category: this.t('Canvas.LongfurSettings'),
order: 100,
},
{
id: "furDensity",
name: "毛发密度",
name: this.t('Canvas.FurDensity'),
type: "slider",
defaultValue: this.furDensity,
min: 0.1,
max: 1,
step: 0.05,
description: "控制毛发的密度",
category: "长毛发设置",
description: this.t('Canvas.FurDensityDescription'),
category: this.t('Canvas.LongfurSettings'),
order: 110,
},
{
id: "furFlowFactor",
name: "流动系数",
name: this.t('Canvas.FlowCoefficient'),
type: "slider",
defaultValue: this.furFlowFactor,
min: 0,
max: 1,
step: 0.05,
description: "控制毛发的流动感",
category: "长毛发设置",
description: this.t('Canvas.FlowCoefficientDescription'),
category: this.t('Canvas.LongfurSettings'),
order: 120,
},
{
id: "furCurvature",
name: "弯曲度",
name: this.t('Canvas.furCurvature'),
type: "slider",
defaultValue: this.furCurvature,
min: 0,
max: 1,
step: 0.05,
description: "控制毛发的弯曲程度",
category: "长毛发设置",
description: this.t('Canvas.furCurvatureDescription'),
category: this.t('Canvas.LongfurSettings'),
order: 130,
},
{
id: "randomizeDirection",
name: "随机方向",
name: this.t('Canvas.randomizeDirection'),
type: "checkbox",
defaultValue: this.randomizeDirection,
description: "是否随机化毛发方向",
category: "长毛发设置",
description: this.t('Canvas.randomizeDirectionDescription'),
category: this.t('Canvas.LongfurSettings'),
order: 140,
},
];

View File

@@ -13,9 +13,9 @@ export class MarkerBrush extends BaseBrush {
constructor(canvas, options = {}) {
super(canvas, {
id: "marker",
name: "马克笔",
name: options.t("Canva.Marker"),
description: "模拟马克笔效果,具有半透明平头笔触",
category: "基础笔刷",
category: options.t("Canvas.BasicBrushes"),
icon: "marker",
...options,
});
@@ -150,40 +150,40 @@ export class MarkerBrush extends BaseBrush {
const markerProperties = [
{
id: "lineWidth",
name: "笔触宽度",
name: this.t('Canvas.MarkerWidth'),
type: "slider",
defaultValue: this._lineWidth,
min: 1,
max: 10,
step: 0.5,
description: "控制马克笔笔触的宽度",
category: "马克笔设置",
description: this.t('Canvas.MarkerWidthDescription'),
category: this.t('Canvas.MarkerSettings'),
order: 100,
},
{
id: "capStyle",
name: "笔头样式",
name: this.t('Canvas.MarkerCapStyle'),
type: "select",
defaultValue: this.capStyle,
options: [
{ value: "round", label: "圆形" },
{ value: "square", label: "方形" },
{ value: "round", label: this.t('Canvas.MarkerCapStyleRound') },
{ value: "square", label: this.t('Canvas.MarkerCapStyleSquare') },
],
description: "设置马克笔笔头的形状",
category: "马克笔设置",
description: this.t('Canvas.MarkerCapStyleDescription'),
category: this.t('Canvas.MarkerSettings'),
order: 110,
},
{
id: "blendMode",
name: "混合模式",
name: this.t('Canvas.MarkerMixedModel'),
type: "select",
defaultValue: this.blendMode,
options: [
{ value: "multiply", label: "正片叠底" },
{ value: "normal", label: "正常" },
{ value: "multiply", label: this.t('Canvas.MarkerMixedModelMultiply') },
{ value: "normal", label: this.t('Canvas.MarkerMixedModelNormal') },
],
description: "设置马克笔的颜色混合方式",
category: "马克笔设置",
description: this.t('Canvas.MarkerMixedModelDescription'),
category: this.t('Canvas.MarkerSettings'),
order: 120,
},
];

View File

@@ -13,9 +13,9 @@ export class RibbonBrush extends BaseBrush {
constructor(canvas, options = {}) {
super(canvas, {
id: "ribbon",
name: "飘带",
name: options.t('Canvas.Ribbon'),
description: "创建流畅的飘带状线条,具有动态宽度变化和曲线美感",
category: "特效笔刷",
category: options.t('Canvas.SpecialEffectsBrush'),
icon: "ribbon",
...options,
});
@@ -237,66 +237,66 @@ export class RibbonBrush extends BaseBrush {
const ribbonProperties = [
{
id: "ribbonWidth",
name: "飘带宽度",
name: this.t('Canvas.RibbonWidth'),
type: "slider",
defaultValue: this.ribbonWidth,
min: 5,
max: 100,
step: 5,
description: "控制飘带的最大宽度",
category: "飘带设置",
description: this.t('Canvas.RibbonWidthDescription'),
category: this.t('Canvas.RibbonSettings'),
order: 100,
},
{
id: "widthVariation",
name: "宽度变化",
name: this.t('Canvas.RibbonVariation'),
type: "slider",
defaultValue: this.widthVariation,
min: 0,
max: 1,
step: 0.05,
description: "控制飘带宽度的变化程度",
category: "飘带设置",
description: this.t('Canvas.RibbonVariationDescription'),
category: this.t('Canvas.RibbonSettings'),
order: 110,
},
{
id: "ribbonSmoothness",
name: "平滑度",
name: this.t('Canvas.RibbonSmoothness'),
type: "slider",
defaultValue: this.ribbonSmoothness,
min: 0,
max: 1,
step: 0.05,
description: "控制飘带曲线的平滑程度",
category: "飘带设置",
description: this.t('Canvas.RibbonSmoothnessDescription'),
category: this.t('Canvas.RibbonSettings'),
order: 120,
},
{
id: "gradient",
name: "启用渐变",
name: this.t('Canvas.RibbonGradient'),
type: "checkbox",
defaultValue: this.gradient,
description: "是否启用渐变效果",
category: "飘带设置",
description: this.t('Canvas.RibbonGradientDescription'),
category: this.t('Canvas.RibbonSettings'),
order: 130,
},
{
id: "gradientColor1",
name: "渐变起始颜色",
name: this.t('Canvas.RibbonGradientColor1'),
type: "color",
defaultValue: this.gradientColors[0] || "#000000",
description: "设置渐变的起始颜色",
category: "飘带设置",
description: this.t('Canvas.RibbonGradientColor1Description'),
category: this.t('Canvas.RibbonSettings'),
order: 140,
visibleWhen: { gradient: true },
},
{
id: "gradientColor2",
name: "渐变结束颜色",
name: this.t('Canvas.RibbonGradientColor2'),
type: "color",
defaultValue: this.gradientColors[1] || "#555555",
description: "设置渐变的结束颜色",
category: "飘带设置",
description: this.t('Canvas.RibbonGradientColor2Description'),
category: this.t('Canvas.RibbonSettings'),
order: 150,
visibleWhen: { gradient: true },
},

View File

@@ -13,9 +13,9 @@ export class ShadedBrush extends BaseBrush {
constructor(canvas, options = {}) {
super(canvas, {
id: "shaded",
name: "阴影笔",
name: options.t('Canvas.Shaded'),
description: "创建带有阴影效果的绘制,适合素描和明暗表现",
category: "绘画笔刷",
category: options.t('Canvas.PaintingBrush'),
icon: "shaded",
...options,
});
@@ -246,70 +246,70 @@ export class ShadedBrush extends BaseBrush {
const shadedProperties = [
{
id: "shadowColor",
name: "阴影颜色",
name: this.t('Canvas.ShadedColor'),
type: "color",
defaultValue: this.shadowColor,
description: "设置阴影的颜色",
category: "阴影设置",
description: this.t('Canvas.ShadedColorDescription'),
category: this.t('Canvas.ShadedSettings'),
order: 100,
},
{
id: "shadowBlur",
name: "阴影模糊",
name: this.t('Canvas.ShadedBlur'),
type: "slider",
defaultValue: this.shadowBlur,
min: 0,
max: 50,
step: 1,
description: "控制阴影的模糊程度",
category: "阴影设置",
description: this.t('Canvas.ShadedBlurDescription'),
category: this.t('Canvas.ShadedSettings'),
order: 110,
},
{
id: "shadowOffsetX",
name: "阴影X偏移",
name: this.t('Canvas.ShadedOffsetX'),
type: "slider",
defaultValue: this.shadowOffsetX,
min: -20,
max: 20,
step: 1,
description: "控制阴影的水平偏移",
category: "阴影设置",
description: this.t('Canvas.ShadedOffsetXDescription'),
category: this.t('Canvas.ShadedSettings'),
order: 120,
},
{
id: "shadowOffsetY",
name: "阴影Y偏移",
name: this.t('Canvas.ShadedOffsetY'),
type: "slider",
defaultValue: this.shadowOffsetY,
min: -20,
max: 20,
step: 1,
description: "控制阴影的垂直偏移",
category: "阴影设置",
description: this.t('Canvas.ShadedOffsetYDescription'),
category: this.t('Canvas.ShadedSettings'),
order: 130,
},
{
id: "blendMode",
name: "混合模式",
name: this.t('Canvas.ShadedBlendMode'),
type: "select",
defaultValue: this.blendMode,
options: [
{ value: "normal", label: "正常" },
{ value: "multiply", label: "正片叠底" },
{ value: "screen", label: "滤色" },
{ value: "overlay", label: "叠加" },
{ value: "darken", label: "变暗" },
{ value: "lighten", label: "变亮" },
{ value: "color-dodge", label: "颜色减淡" },
{ value: "color-burn", label: "颜色加深" },
{ value: "hard-light", label: "强光" },
{ value: "soft-light", label: "柔光" },
{ value: "difference", label: "差值" },
{ value: "exclusion", label: "排除" },
{ value: "normal", label: this.t('Canvas.ShadedMixedModelNormal') },
{ value: "multiply", label: this.t('Canvas.ShadedMixedModelMultiply') },
{ value: "screen", label: this.t('Canvas.ShadedMixedModelScreen') },
{ value: "overlay", label: this.t('Canvas.ShadedMixedModelOverlay') },
{ value: "darken", label: this.t('Canvas.ShadedMixedModelDarken') },
{ value: "lighten", label: this.t('Canvas.ShadedMixedModelLighten') },
{ value: "color-dodge", label: this.t('Canvas.ShadedMixedModelColorDodge') },
{ value: "color-burn", label: this.t('Canvas.ShadedMixedModelColorBurn') },
{ value: "hard-light", label: this.t('Canvas.ShadedMixedModelHardLight') },
{ value: "soft-light", label: this.t('Canvas.ShadedMixedModelSoftLight') },
{ value: "difference", label: this.t('Canvas.ShadedMixedModelDifference') },
{ value: "exclusion", label: this.t('Canvas.ShadedMixedModelExclusion') },
],
description: "设置阴影的混合模式",
category: "阴影设置",
description: this.t('Canvas.ShadedBlendModeDescription'),
category: this.t('Canvas.ShadedSettings'),
order: 140,
},
];

View File

@@ -13,9 +13,9 @@ export class SprayBrush extends BaseBrush {
constructor(canvas, options = {}) {
super(canvas, {
id: "crayon",
name: "喷枪",
name: options.t('Canvas.Spray'),
description: "模拟喷枪效果,具有颗粒感和纹理",
category: "特效笔刷",
category: options.t('Canvas.SpecialEffectsBrush'),
icon: "crayon",
...options,
});
@@ -151,52 +151,52 @@ export class SprayBrush extends BaseBrush {
const crayonProperties = [
{
id: "separation",
name: "颗粒分离度",
name: this.t('Canvas.ParticleSeparationDegree'),
type: "slider",
defaultValue: this._sep,
min: 0.5,
max: 10,
step: 0.5,
description: "控制喷枪颗粒的分离程度",
category: "喷枪设置",
description: this.t('Canvas.ParticleSeparationDegree'),
category: this.t('Canvas.SpraySettings'),
order: 100,
},
{
id: "inkAmount",
name: "墨量",
name: this.t('Canvas.TheAmountOfInk'),
type: "slider",
defaultValue: this._inkAmount,
min: 1,
max: 50,
step: 1,
description: "控制喷枪的颜料量",
category: "喷枪设置",
description: this.t('Canvas.TheAmountOfInkDescription'),
category: this.t('Canvas.SpraySettings'),
order: 110,
},
{
id: "randomness",
name: "随机性",
name: this.t('Canvas.randomness'),
type: "slider",
defaultValue: this.randomness,
min: 0,
max: 1,
step: 0.05,
description: "控制喷枪纹理的随机程度",
category: "喷枪设置",
description: this.t('Canvas.randomnessDescription'),
category: this.t('Canvas.SpraySettings'),
order: 120,
},
{
id: "texture",
name: "纹理类型",
name: this.t('Canvas.TextureType'),
type: "select",
defaultValue: this.texture,
options: [
{ value: "default", label: "默认" },
{ value: "rough", label: "粗糙" },
{ value: "smooth", label: "平滑" },
{ value: "default", label: this.t('Canvas.Default') },
{ value: "rough", label: this.t('Canvas.Rough') },
{ value: "smooth", label: this.t('Canvas.Smooth') },
],
description: "设置喷枪的纹理类型",
category: "喷枪设置",
description: this.t('Canvas.TextureTypeDescription'),
category: this.t('Canvas.SpraySettings'),
order: 130,
},
];

View File

@@ -13,9 +13,9 @@ export class WritingBrush extends BaseBrush {
constructor(canvas, options = {}) {
super(canvas, {
id: "writing",
name: "书法笔",
name: options.t('Canvas.Writing'),
description: "模拟中国传统书法毛笔效果,具有笔锋和墨色变化",
category: "特效笔刷",
category: options.t('Canvas.SpecialEffectsBrush'),
icon: "writing",
...options,
});
@@ -174,47 +174,47 @@ export class WritingBrush extends BaseBrush {
const writingProperties = [
{
id: "brushPressure",
name: "笔压感应",
name: this.t('Canvas.WritingBrushPressure'),
type: "slider",
defaultValue: this.brushPressure,
min: 0.1,
max: 1,
step: 0.05,
description: "控制笔触的力度感应",
category: "书法设置",
description: this.t('Canvas.WritingBrushPressureDescription'),
category: this.t('Canvas.WritingSettings'),
order: 100,
},
{
id: "inkAmount",
name: "墨量",
name: this.t('Canvas.WritingAmount'),
type: "slider",
defaultValue: this.inkAmount,
min: 1,
max: 50,
step: 1,
description: "控制笔触中的墨水量",
category: "书法设置",
description: this.t('Canvas.WritingAmountDescription'),
category: this.t('Canvas.WritingSettings'),
order: 110,
},
{
id: "brushTaperFactor",
name: "笔锋系数",
name: this.t('Canvas.WritingPenTipCoefficient'),
type: "slider",
defaultValue: this.brushTaperFactor,
min: 0,
max: 1,
step: 0.05,
description: "控制笔锋的尖锐程度",
category: "书法设置",
description: this.t('Canvas.WritingPenTipCoefficientDescription'),
category: this.t('Canvas.WritingSettings'),
order: 120,
},
{
id: "enableInkDripping",
name: "墨滴效果",
name: this.t('Canvas.WritingDropEffect'),
type: "checkbox",
defaultValue: this.enableInkDripping,
description: "是否启用墨滴效果",
category: "书法设置",
description: this.t('Canvas.WritingDropEffectDescription'),
category: this.t('Canvas.WritingSettings'),
order: 130,
},
];

View File

@@ -36,11 +36,11 @@ const state = reactive({
// 笔刷预设
presets: [
{ name: "细线", size: 2, opacity: 1, color: "#000000", type: "pencil" },
{ name: "中粗", size: 5, opacity: 1, color: "#000000", type: "pencil" },
{ name: "粗线", size: 10, opacity: 1, color: "#000000", type: "pencil" },
{ name: "水彩", size: 15, opacity: 0.7, color: "#3366ff", type: "marker" },
{ name: "喷枪", size: 20, opacity: 0.5, color: "#ff6633", type: "spray" },
// { name: "细线", size: 2, opacity: 1, color: "#000000", type: "pencil" },
// { name: "中粗", size: 5, opacity: 1, color: "#000000", type: "pencil" },
// { name: "粗线", size: 10, opacity: 1, color: "#000000", type: "pencil" },
// { name: "水彩", size: 15, opacity: 0.7, color: "#3366ff", type: "marker" },
// { name: "喷枪", size: 20, opacity: 0.5, color: "#ff6633", type: "spray" },
],
// 材质预设