Files
aida_front/src/component/Canvas/CanvasEditor/managers/brushes/brushManager.js

721 lines
19 KiB
JavaScript
Raw Normal View History

2025-06-09 10:25:54 +08:00
//import { fabric } from "fabric-with-all";
import { BrushStore } from "../../store/BrushStore";
import { brushRegistry } from "./BrushRegistry";
// 导入基础笔刷类型
import { PencilBrush } from "./types/PencilBrush";
import { TextureBrush } from "./types/TextureBrush";
// 导入集成的笔刷类型
import { CrayonBrush } from "./types/CrayonBrush";
import { FurBrush } from "./types/FurBrush";
import { InkBrush } from "./types/InkBrush";
import { LongfurBrush } from "./types/LongfurBrush";
import { WritingBrush } from "./types/WritingBrush";
import { MarkerBrush } from "./types/MarkerBrush";
import { CustomPenBrush } from "./types/CustomPenBrush";
import { RibbonBrush } from "./types/RibbonBrush";
import { ShadedBrush } from "./types/ShadedBrush";
import { SketchyBrush } from "./types/SketchyBrush";
import { SpraypaintBrush } from "./types/SpraypaintBrush";
/**
* 笔刷管理器
* 负责管理和切换不同的笔刷类型
*/
export class BrushManager {
/**
* 构造函数
* @param {Object} options 配置选项
* @param {Object} options.canvas fabric.js画布实例
* @param {Object} options.brushStore 笔刷数据存储可选
* @param {Object} options.layerManager 图层管理器实例可选
*/
constructor(options = {}) {
this.canvas = options.canvas;
this.brushStore = options.brushStore || BrushStore;
this.layerManager = options.layerManager; // 添加图层管理器引用
// 当前活动笔刷
this.activeBrush = null;
this.activeBrushId = null;
// 初始化笔刷注册
this._registerDefaultBrushes();
}
/**
* 注册默认笔刷
* @private
*/
_registerDefaultBrushes() {
// 注册铅笔笔刷
brushRegistry.register("pencil", PencilBrush, {
name: "铅笔",
description: "基础铅笔工具,适合精细线条绘制",
category: "基础笔刷",
});
// 注册材质笔刷
brushRegistry.register("texture", TextureBrush);
// 注册集成的笔刷类型
brushRegistry.register("crayon", CrayonBrush);
brushRegistry.register("fur", FurBrush);
brushRegistry.register("ink", InkBrush);
brushRegistry.register("longfur", LongfurBrush);
brushRegistry.register("writing", WritingBrush);
brushRegistry.register("marker", MarkerBrush);
brushRegistry.register("pen", CustomPenBrush);
brushRegistry.register("ribbon", RibbonBrush);
brushRegistry.register("shaded", ShadedBrush);
brushRegistry.register("sketchy", SketchyBrush);
brushRegistry.register("spraypaint", SpraypaintBrush);
// 注册喷枪笔刷
brushRegistry.register(
"spray",
class SprayBrush extends PencilBrush {
constructor(canvas, options = {}) {
super(canvas, {
id: "spray",
name: "喷枪",
description: "模拟喷枪效果,创建散点效果",
category: "基础笔刷",
...options,
});
}
create() {
this.brush = new fabric.SprayBrush(this.canvas);
this.configure(this.brush, this.options);
return this.brush;
}
configure(brush, options = {}) {
super.configure(brush, options);
if (options.density !== undefined) {
brush.density = options.density;
}
if (options.randomOpacity !== undefined) {
brush.randomOpacity = options.randomOpacity;
}
if (options.dotWidth !== undefined) {
brush.dotWidth = options.dotWidth;
}
}
}
);
// 注册橡皮擦笔刷
brushRegistry.register(
"eraser",
class EraserBrush extends PencilBrush {
constructor(canvas, options = {}) {
super(canvas, {
id: "eraser",
name: "橡皮擦",
description: "擦除已绘制的内容",
category: "工具",
...options,
});
}
create() {
// 直接使用 fabric-with-erasing 库提供的 EraserBrush
this.brush = new fabric.EraserBrush(this.canvas);
this.configure(this.brush, this.options);
// 配置橡皮擦特有属性
this.brush.inverted = this.options.inverted || false; // 是否反向擦除(恢复擦除)
return this.brush;
}
configure(brush, options = {}) {
super.configure(brush, options);
// 橡皮擦特有配置
if (options.inverted !== undefined) {
brush.inverted = options.inverted;
}
}
/**
* 设置反向擦除模式
* @param {Boolean} inverted 是否启用反向擦除撤销擦除效果
*/
setInverted(inverted) {
if (this.brush) {
this.brush.inverted = inverted;
}
}
/**
* 获取橡皮擦配置属性
* @returns {Array} 可配置属性数组
*/
getConfigurableProperties() {
return [
...super.getConfigurableProperties(),
{
id: "inverted",
name: "反向擦除",
type: "boolean",
description: "启用时可以恢复已擦除的内容",
defaultValue: false,
min: null,
max: null,
},
];
}
/**
* 更新橡皮擦属性
* @param {String} propId 属性ID
* @param {any} value 属性值
*/
updateProperty(propId, value) {
if (propId === "inverted") {
this.setInverted(value);
} else {
super.updateProperty(propId, value);
}
}
}
);
// 注册水彩笔刷
brushRegistry.register(
"watercolor",
class WatercolorBrush extends PencilBrush {
constructor(canvas, options = {}) {
super(canvas, {
id: "watercolor",
name: "水彩",
description: "模拟水彩效果,带有流动感和透明感",
category: "特效笔刷",
...options,
});
}
create() {
// 创建一个自定义的PencilBrush来模拟水彩效果
this.brush = new fabric.PencilBrush(this.canvas);
this.configure(this.brush, this.options);
// 水彩效果特有的属性
this.brush.globalCompositeOperation = "multiply";
this.brush.shadow = new fabric.Shadow({
color: this.options.color || "#000",
blur: 5,
offsetX: 0,
offsetY: 0,
});
return this.brush;
}
configure(brush, options = {}) {
super.configure(brush, options);
// 水彩笔刷特有的配置
brush.opacity = Math.min(0.5, options.opacity || 0.3); // 默认透明度30%
}
}
);
// 注册粉笔笔刷
brushRegistry.register(
"chalk",
class ChalkBrush extends PencilBrush {
constructor(canvas, options = {}) {
super(canvas, {
id: "chalk",
name: "粉笔",
description: "模拟粉笔效果,有颗粒感和不连续性",
category: "特效笔刷",
...options,
});
}
create() {
this.brush = new fabric.PencilBrush(this.canvas);
this.configure(this.brush, this.options);
// 自定义绘画方法来模拟粉笔效果
const originalOnMouseMove = this.brush.onMouseMove;
this.brush.onMouseMove = function (pointer, options) {
// 随机调整坐标位置,增加粉笔质感
const jitter = 2;
pointer.x += (Math.random() - 0.5) * jitter;
pointer.y += (Math.random() - 0.5) * jitter;
// 调用原始方法
originalOnMouseMove.call(this, pointer, options);
};
return this.brush;
}
configure(brush, options = {}) {
super.configure(brush, options);
// 粉笔特有的设置
brush.strokeDashArray = [5, 5]; // 虚线效果
}
}
);
}
/**
* 获取所有可用笔刷类型
* @returns {Array} 笔刷类型数组包含idname和description
*/
getBrushTypes() {
// 从注册表获取所有笔刷信息
const brushes = brushRegistry.getAllBrushes();
// 将笔刷信息转换为期望的格式
return brushes.map((brushInfo) => ({
id: brushInfo.id,
name: brushInfo.metadata.name || brushInfo.id,
description: brushInfo.metadata.description || "",
category: brushInfo.metadata.category || "默认",
icon: brushInfo.metadata.icon || null,
}));
}
/**
* 初始化笔刷列表并更新BrushStore
*/
initializeBrushes() {
// 获取所有笔刷
const allBrushes = this.getBrushTypes();
// 更新BrushStore中的可用笔刷列表
this.brushStore.setAvailableBrushes(allBrushes);
// 设置默认笔刷
if (!this.activeBrushId && allBrushes.length > 0) {
this.setBrushType(allBrushes[0].id);
}
}
/**
* 设置笔刷类型
* @param {String} brushId 笔刷ID
* @returns {Object|null} 设置的笔刷实例
*/
setBrushType(brushId) {
// 如果相同笔刷,不做处理
if (this.activeBrushId === brushId) {
return this.activeBrush;
}
// 销毁当前笔刷
if (this.activeBrush) {
// 调用生命周期方法
if (this.activeBrush.onDeselected) {
this.activeBrush.onDeselected();
}
this.activeBrush.destroy();
}
// 创建新笔刷实例
try {
const brushInstance = brushRegistry.createBrushInstance(
brushId,
this.canvas,
{
color: brushId === "eraser" ? this.brushStore.state.color : undefined,
width: this.brushStore.state.size,
opacity: this.brushStore.state.opacity,
// 材质笔刷特有配置
textureEnabled: this.brushStore.state.textureEnabled,
texturePath: this.brushStore.state.texturePath,
textureScale: this.brushStore.state.textureScale,
}
);
if (brushInstance) {
// 创建笔刷
const fabricBrush = brushInstance.create();
// 更新画布的当前笔刷
if (fabricBrush) {
this.canvas.freeDrawingBrush = fabricBrush;
}
// 更新当前笔刷引用
this.activeBrush = brushInstance;
this.activeBrushId = brushId;
// 调用生命周期方法
if (this.activeBrush.onSelected) {
this.activeBrush.onSelected();
}
// 更新Store的笔刷类型
this.brushStore.setBrushType(brushId);
// 更新Store的当前笔刷实例用于动态属性系统
this.brushStore.setCurrentBrushInstance(brushInstance);
return brushInstance;
}
} catch (error) {
console.error(`创建笔刷 ${brushId} 失败:`, error);
}
return null;
}
/**
* 设置笔刷颜色
* @param {String} color 十六进制颜色值
*/
setBrushColor(color) {
if (!this.canvas.freeDrawingBrush) return;
// 更新笔刷颜色
this.canvas.freeDrawingBrush.color = color;
// 更新活动笔刷
if (this.activeBrush) {
this.activeBrush.configure(this.canvas.freeDrawingBrush, { color });
}
// 更新Store
this.brushStore.setBrushColor(color);
}
/**
* 设置笔刷大小
* @param {Number} size 笔刷大小
*/
setBrushSize(size) {
if (!this.canvas.freeDrawingBrush) return;
// 限制大小范围
const brushSize = Math.max(0.1, Math.min(100, size));
// 更新笔刷大小
this.canvas.freeDrawingBrush.width = brushSize;
// 更新活动笔刷
if (this.activeBrush) {
this.activeBrush.configure(this.canvas.freeDrawingBrush, {
width: brushSize,
});
}
// 更新Store
this.brushStore.setBrushSize(brushSize);
return brushSize;
}
/**
* 增加笔刷大小
* @param {Number} amount 增加量
* @returns {Number} 新的笔刷大小
*/
increaseBrushSize(amount = 1) {
const currentSize = this.brushStore.state.size;
return this.setBrushSize(currentSize + amount);
}
/**
* 减少笔刷大小
* @param {Number} amount 减少量
* @returns {Number} 新的笔刷大小
*/
decreaseBrushSize(amount = 1) {
const currentSize = this.brushStore.state.size;
return this.setBrushSize(currentSize - amount);
}
/**
* 增加笔刷透明度
* @param {Number} amount 增加量
* @returns {Number} 新的笔刷大小
*/
increaseBrushOpacity(amount = 0.01) {
const currentSize = this.brushStore.state.opacity;
return this.setBrushOpacity(currentSize + amount);
}
/**
* 减少笔刷大小
* @param {Number} amount 减少量
* @returns {Number} 新的笔刷大小
*/
decreaseBrushOpacity(amount = 0.01) {
const currentSize = this.brushStore.state.opacity;
return this.setBrushOpacity(currentSize - amount);
}
/**
* 设置笔刷透明度
* @param {Number} opacity 透明度 (0-1)
*/
setBrushOpacity(opacity) {
if (!this.canvas.freeDrawingBrush) return;
// 限制透明度范围
const brushOpacity = Math.max(0.05, Math.min(1, opacity));
// 更新笔刷透明度
this.canvas.freeDrawingBrush.opacity = brushOpacity;
// 更新活动笔刷
if (this.activeBrush) {
this.activeBrush.configure(this.canvas.freeDrawingBrush, {
opacity: brushOpacity,
});
}
// 更新Store
this.brushStore.setBrushOpacity(brushOpacity);
return brushOpacity;
}
/**
* 设置材质缩放
* @param {Number} scale 缩放比例
*/
setTextureScale(scale) {
// 限制缩放范围
const textureScale = Math.max(0.1, Math.min(10, scale));
// 更新活动笔刷
if (this.activeBrush && this.activeBrush.setTextureScale) {
this.activeBrush.setTextureScale(textureScale);
}
// 更新Store
this.brushStore.setTextureScale(textureScale);
return textureScale;
}
/**
* 增加材质缩放
* @param {Number} amount 增加量
*/
increaseTextureScale(amount = 0.1) {
const currentScale = this.brushStore.state.textureScale;
return this.setTextureScale(currentScale + amount);
}
/**
* 减少材质缩放
* @param {Number} amount 减少量
*/
decreaseTextureScale(amount = 0.1) {
const currentScale = this.brushStore.state.textureScale;
return this.setTextureScale(currentScale - amount);
}
/**
* 设置材质路径
* @param {String} path 材质图片路径
*/
setTexturePath(path) {
// 更新活动笔刷
if (this.activeBrush && this.activeBrush.setTexturePath) {
this.activeBrush.setTexturePath(path);
}
// 更新Store
this.brushStore.setTexturePath(path);
return path;
}
/**
* 启用/禁用材质
* @param {Boolean} enabled 是否启用
*/
setTextureEnabled(enabled) {
// 更新Store
this.brushStore.setTextureEnabled(enabled);
// 如果启用材质,且当前不是材质笔刷,需要切换
if (enabled && this.activeBrushId !== "texture") {
this.setBrushType("texture");
}
return enabled;
}
/**
* 注册新笔刷
* @param {String} id 笔刷ID
* @param {Class} brushClass 笔刷类
* @param {Object} metadata 笔刷元数据
* @returns {Boolean} 是否注册成功
*/
registerBrush(id, brushClass, metadata = {}) {
const success = brushRegistry.register(id, brushClass, metadata);
if (success) {
// 更新可用笔刷列表
this.initializeBrushes();
}
return success;
}
/**
* 获取当前笔刷类型
* @returns {String} 当前笔刷类型ID
*/
getCurrentBrushType() {
return this.activeBrushId;
}
/**
* 获取当前笔刷大小
* @returns {Number} 当前笔刷大小
*/
getBrushSize() {
return this.brushStore.state.size;
}
/**
* 获取当前笔刷颜色
* @returns {String} 当前笔刷颜色
*/
getBrushColor() {
return this.brushStore.state.color;
}
/**
* 获取当前笔刷透明度
* @returns {Number} 当前笔刷透明度
*/
getBrushOpacity() {
return this.brushStore.state.opacity;
}
/**
* 获取材质缩放
* @returns {Number} 材质缩放比例
*/
getTextureScale() {
return this.brushStore.state.textureScale;
}
/**
* 创建材质笔刷
* 这个方法保留用于向下兼容
* @deprecated 请使用setBrushType('texture')代替
* @returns {Object} 材质笔刷实例
*/
createTextureBrush() {
console.warn('createTextureBrush方法已废弃请使用setBrushType("texture")');
return this.setBrushType("texture");
}
/**
* 更新笔刷
* 根据当前设置应用笔刷属性到画布
*/
updateBrush() {
if (!this.canvas) return;
// 如果有活动的笔刷实例,重新配置它
if (this.activeBrush && this.canvas.freeDrawingBrush) {
this.activeBrush.configure(this.canvas.freeDrawingBrush, {
color: this.brushStore.state.color,
width: this.brushStore.state.size,
opacity: this.brushStore.state.opacity,
});
} else {
// 如果没有活动笔刷,创建一个默认的
this.setBrushType(this.activeBrushId || "pencil");
}
// 更新画布状态
this?.canvas?.renderAll?.();
return this.canvas.freeDrawingBrush;
}
/**
* 创建橡皮擦
* @returns {Object} 橡皮擦笔刷
*/
createEraser() {
return this.setBrushType("eraser");
}
/**
* 创建吸色工具
* @param {Function} callback 选择颜色后的回调函数
*/
createEyedropper(callback) {
// 保存当前状态
const previousBrushId = this.activeBrushId;
// 一次性事件处理程序
const handleMouseDown = (event) => {
const pointer = this.canvas.getPointer(event.e);
const ctx = this.canvas.getContext();
// 获取点击位置的像素
const imageData = ctx.getImageData(pointer.x, pointer.y, 1, 1).data;
// 将RGB转换为十六进制颜色
const color = `#${(
(1 << 24) +
(imageData[0] << 16) +
(imageData[1] << 8) +
imageData[2]
)
.toString(16)
.slice(1)}`;
// 调用回调函数
if (typeof callback === "function") {
callback(color);
}
// 恢复之前的笔刷
this.setBrushType(previousBrushId);
// 移除事件监听器
this.canvas.off("mouse:down", handleMouseDown);
};
// 添加事件监听器
this.canvas.on("mouse:down", handleMouseDown);
// 设置吸色光标
this.canvas.defaultCursor = "crosshair";
console.log("吸色工具已激活,点击画布选择颜色");
}
/**
* 销毁资源
*/
dispose() {
// 销毁当前笔刷
if (this.activeBrush) {
this.activeBrush.destroy();
this.activeBrush = null;
}
this.canvas = null;
}
}
// 导出单例
export default BrushManager;