Merge branch 'dev_vite' of ssh://18.167.251.121:10002/aidlab/aida_front into dev_vite
This commit is contained in:
@@ -154,6 +154,8 @@ const isVisible = computed(() => {
|
|||||||
OperationType.ERASER,
|
OperationType.ERASER,
|
||||||
OperationType.RED_BRUSH,
|
OperationType.RED_BRUSH,
|
||||||
OperationType.GREEN_BRUSH,
|
OperationType.GREEN_BRUSH,
|
||||||
|
OperationType.PART_BRUSH,
|
||||||
|
OperationType.PART_ERASER,
|
||||||
].includes(props.activeTool);
|
].includes(props.activeTool);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
<span class="label">{{ t("Canvas.scale") }}</span>
|
<span class="label">{{ t("Canvas.scale") }}</span>
|
||||||
<slider
|
<slider
|
||||||
:min="1"
|
:min="1"
|
||||||
:max="500"
|
:max="1000"
|
||||||
:step="1"
|
:step="1"
|
||||||
is-input
|
is-input
|
||||||
:tipFormatter="(v) => `${scale}%`"
|
:tipFormatter="(v) => `${scale}%`"
|
||||||
@@ -52,19 +52,19 @@
|
|||||||
<div class="repeat-setting-item">
|
<div class="repeat-setting-item">
|
||||||
<span class="label">{{ t("Canvas.offset") }}</span>
|
<span class="label">{{ t("Canvas.offset") }}</span>
|
||||||
<offset-tool
|
<offset-tool
|
||||||
:left="offsetX"
|
:left="offset.x"
|
||||||
:top="offsetY"
|
:top="offset.y"
|
||||||
@input="(e) => emit('inputFillOffset', e)"
|
@input="inputFillOffset"
|
||||||
@change="(e) => emit('changeFillOffset', e)"
|
@change="changeFillOffset"
|
||||||
:show-dish="false"
|
:show-dish="false"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="repeat-setting-item offset">
|
<div class="repeat-setting-item offset">
|
||||||
<offset-tool
|
<offset-tool
|
||||||
:left="offsetX"
|
:left="offset.x"
|
||||||
:top="offsetY"
|
:top="offset.y"
|
||||||
@input="(e) => emit('inputFillOffset', e)"
|
@input="inputFillOffset"
|
||||||
@change="(e) => emit('changeFillOffset', e)"
|
@change="changeFillOffset"
|
||||||
:show-input="false"
|
:show-input="false"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -79,29 +79,6 @@
|
|||||||
import Slider from "../tools/Slider.vue";
|
import Slider from "../tools/Slider.vue";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
object: {
|
|
||||||
required: true,
|
|
||||||
type: Object,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const angle = computed(
|
|
||||||
() => getTransformScaleAngle(props.object.fill?.patternTransform).angle
|
|
||||||
);
|
|
||||||
const scale = computed(() => {
|
|
||||||
const patternTransform = props.object.fill?.patternTransform;
|
|
||||||
const scaleValue = getTransformScaleAngle(patternTransform).scale * 100;
|
|
||||||
return Number(Number(scaleValue).toFixed(2));
|
|
||||||
});
|
|
||||||
const gapX = computed(() => props.object.fill_?.gapX || 0);
|
|
||||||
const gapY = computed(() => props.object.fill_?.gapY || 0);
|
|
||||||
const offsetX = computed(
|
|
||||||
() => (props.object.fill?.offsetX / props.object.width) * 100
|
|
||||||
);
|
|
||||||
const offsetY = computed(
|
|
||||||
() => (props.object.fill?.offsetY / props.object.height) * 100
|
|
||||||
);
|
|
||||||
const emit = defineEmits([
|
const emit = defineEmits([
|
||||||
"inputFillAngle",
|
"inputFillAngle",
|
||||||
"changeFillAngle",
|
"changeFillAngle",
|
||||||
@@ -112,13 +89,63 @@
|
|||||||
"inputFillGap",
|
"inputFillGap",
|
||||||
"changeFillGap",
|
"changeFillGap",
|
||||||
]);
|
]);
|
||||||
const inputFillScale = (e) => {
|
|
||||||
|
const props = defineProps({
|
||||||
|
object: {
|
||||||
|
required: true,
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const angle = computed(
|
||||||
|
() => getTransformScaleAngle(props.object.fill?.patternTransform).angle
|
||||||
|
);
|
||||||
|
const gapX = computed(() => props.object.fill_?.gapX || 0);
|
||||||
|
const gapY = computed(() => props.object.fill_?.gapY || 0);
|
||||||
|
|
||||||
|
// 缩放比例
|
||||||
|
const scale = computed(() => {
|
||||||
|
const object = props.object;
|
||||||
|
const patternTransform = object.fill?.patternTransform;
|
||||||
|
const scaleValue = getTransformScaleAngle(patternTransform).scale;
|
||||||
|
const scaleX = scaleValue / (object.width / object.fill_.width / 5);
|
||||||
|
const scaleY = scaleValue / (object.height / object.fill_.height / 5);
|
||||||
|
const scaleXY = object.width > object.height ? scaleX : scaleY;
|
||||||
|
return Number(Number(scaleXY * 100).toFixed(2));
|
||||||
|
});
|
||||||
|
const inputFillScale = (e) => setFillScale(e, true);
|
||||||
|
const changeFillScale = (e) => setFillScale(e, false);
|
||||||
|
const setFillScale = (e, isInput) => {
|
||||||
|
const object = props.object;
|
||||||
const scale = e / 100;
|
const scale = e / 100;
|
||||||
emit("inputFillScale", scale);
|
const scaleX = (object.width / object.fill_.width / 5) * scale;
|
||||||
|
const scaleY = (object.height / object.fill_.height / 5) * scale;
|
||||||
|
const scaleXY = object.width > object.height ? scaleX : scaleY;
|
||||||
|
emit(isInput ? "inputFillScale" : "changeFillScale", scaleXY);
|
||||||
};
|
};
|
||||||
const changeFillScale = (e) => {
|
|
||||||
const scale = e / 100;
|
// 偏移量
|
||||||
emit("changeFillScale", scale);
|
const offset = computed(() => {
|
||||||
|
const object = props.object;
|
||||||
|
const patternTransform = object.fill?.patternTransform;
|
||||||
|
const scale = getTransformScaleAngle(patternTransform).scale;
|
||||||
|
const offsetX = object.fill?.offsetX;
|
||||||
|
const offsetY = object.fill?.offsetY;
|
||||||
|
const twidth = object.fill_?.width;
|
||||||
|
const theight = object.fill_?.height;
|
||||||
|
const x = ((offsetX - (twidth * scale) / 2) * 100) / object.width;
|
||||||
|
const y = ((offsetY - (theight * scale) / 2) * 100) / object.height;
|
||||||
|
return { x, y };
|
||||||
|
});
|
||||||
|
const inputFillOffset = (e) => setFillOffset(e, true);
|
||||||
|
const changeFillOffset = (e) => setFillOffset(e, false);
|
||||||
|
const setFillOffset = (e, isInput) => {
|
||||||
|
const { left, top } = e;
|
||||||
|
const object = props.object;
|
||||||
|
const patternTransform = object.fill?.patternTransform;
|
||||||
|
const scale = getTransformScaleAngle(patternTransform).scale;
|
||||||
|
const x = (left / 100) * object.width + (object.fill_?.width * scale) / 2;
|
||||||
|
const y = (top / 100) * object.height + (object.fill_?.height * scale) / 2;
|
||||||
|
emit(isInput ? "inputFillOffset" : "changeFillOffset", { x, y });
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -126,6 +153,7 @@
|
|||||||
.repeat-setting {
|
.repeat-setting {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
width: 228px;
|
width: 228px;
|
||||||
|
overflow: hidden;
|
||||||
> .title {
|
> .title {
|
||||||
line-height: 35px;
|
line-height: 35px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
|||||||
@@ -439,16 +439,16 @@
|
|||||||
if (!obj.oldPattern) obj.oldPattern = obj.get("fill");
|
if (!obj.oldPattern) obj.oldPattern = obj.get("fill");
|
||||||
const pattern = new fabric.Pattern({
|
const pattern = new fabric.Pattern({
|
||||||
...obj.get("fill"),
|
...obj.get("fill"),
|
||||||
offsetX: (value.left / 100) * obj.width,
|
offsetX: value.x,
|
||||||
offsetY: (value.top / 100) * obj.height,
|
offsetY: value.y,
|
||||||
});
|
});
|
||||||
obj.set("fill", pattern);
|
obj.set("fill", pattern);
|
||||||
props.canvas.renderAll();
|
props.canvas.renderAll();
|
||||||
};
|
};
|
||||||
const changeFillOffset = (value, obj) => {
|
const changeFillOffset = (value, obj) => {
|
||||||
const pattern = new fabric.Pattern({
|
const pattern = new fabric.Pattern({
|
||||||
offsetX: (value.left / 100) * obj.width,
|
offsetX: value.x,
|
||||||
offsetY: (value.top / 100) * obj.height,
|
offsetY: value.y,
|
||||||
});
|
});
|
||||||
changeFill(obj, pattern);
|
changeFill(obj, pattern);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ export class CanvasManager {
|
|||||||
this.isFixedErasable = options.isFixedErasable || false; // 是否允许擦除固定图层
|
this.isFixedErasable = options.isFixedErasable || false; // 是否允许擦除固定图层
|
||||||
this.eraserStateManager = null; // 橡皮擦状态管理器引用
|
this.eraserStateManager = null; // 橡皮擦状态管理器引用
|
||||||
this.handleCanvasInit = null; // 画布初始化回调函数
|
this.handleCanvasInit = null; // 画布初始化回调函数
|
||||||
|
this.partManager = options.partManager || null;
|
||||||
this.props = options.props || {};
|
this.props = options.props || {};
|
||||||
this.emit = options.emit || (() => {});
|
this.emit = options.emit || (() => {});
|
||||||
// 初始化画布
|
// 初始化画布
|
||||||
@@ -174,7 +175,12 @@ export class CanvasManager {
|
|||||||
_initCanvasEvents() {
|
_initCanvasEvents() {
|
||||||
// 添加笔刷图像转换处理回调
|
// 添加笔刷图像转换处理回调
|
||||||
this.canvas.onBrushImageConverted = async (fabricImage) => {
|
this.canvas.onBrushImageConverted = async (fabricImage) => {
|
||||||
await this.addImageToLayer({ fabricImage, targetLayerId: null });
|
const activeTool = this.toolManager?.activeTool?.value;
|
||||||
|
if(activeTool === OperationType.PART_BRUSH){
|
||||||
|
this.partManager?.addPartImage(fabricImage);
|
||||||
|
}else{
|
||||||
|
await this.addImageToLayer({ fabricImage, targetLayerId: null });
|
||||||
|
}
|
||||||
// 返回false表示使用默认行为(直接添加到画布)
|
// 返回false表示使用默认行为(直接添加到画布)
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
@@ -1208,8 +1214,8 @@ backgroundObject.scaleY,'CanvasManager resetCanvasSizeByFixedLayer')
|
|||||||
let scaleY = scale * 5 * v.fill_.height / flHeight;
|
let scaleY = scale * 5 * v.fill_.height / flHeight;
|
||||||
let scaleXY = flWidth > flHeight ? scaleX : scaleY;
|
let scaleXY = flWidth > flHeight ? scaleX : scaleY;
|
||||||
|
|
||||||
let left = fill.offsetX + v.fill_.width * scale / 2;
|
let left = fill.offsetX - v.fill_.width * scale / 2;
|
||||||
let top = fill.offsetY + v.fill_.height * scale / 2;
|
let top = fill.offsetY - v.fill_.height * scale / 2;
|
||||||
|
|
||||||
obj.scale = [scaleXY, scaleXY];
|
obj.scale = [scaleXY, scaleXY];
|
||||||
obj.angle = angle;
|
obj.angle = angle;
|
||||||
@@ -1707,15 +1713,15 @@ backgroundObject.scaleY,'CanvasManager resetCanvasSizeByFixedLayer')
|
|||||||
resolve(tcanvas);
|
resolve(tcanvas);
|
||||||
}, { crossOrigin: "anonymous" });
|
}, { crossOrigin: "anonymous" });
|
||||||
})
|
})
|
||||||
let scaleX_ = fixedLayerObj.width / image.width * (item.scale?.[0] || 1) / 5;
|
let scaleX_ = flWidth / image.width * (item.scale?.[0] || 1) / 5;
|
||||||
let scaleY_ = fixedLayerObj.height / image.height * (item.scale?.[1] || 1) / 5;
|
let scaleY_ = flHeight / image.height * (item.scale?.[1] || 1) / 5;
|
||||||
let scale = fixedLayerObj.width > fixedLayerObj.height ? scaleX_ : scaleY_;
|
let scale = flWidth > flHeight ? scaleX_ : scaleY_;
|
||||||
let offsetX = (item.location?.[0] || 0) - image.width * scale / 2
|
let offsetX = (item.location?.[0] || 0) + image.width * scale / 2
|
||||||
let offsetY = (item.location?.[1] || 0) - image.height * scale / 2
|
let offsetY = (item.location?.[1] || 0) + image.height * scale / 2
|
||||||
let top = fixedLayerObj.top - fixedLayerObj.height * fixedLayerObj.scaleY / 2
|
let top = flTop - flHeight * flScaleY / 2
|
||||||
let left = fixedLayerObj.left - fixedLayerObj.width * fixedLayerObj.scaleX / 2
|
let left = flLeft - flWidth * flScaleX / 2
|
||||||
let scaleX = fixedLayerObj.scaleX
|
let scaleX = flScaleX
|
||||||
let scaleY = fixedLayerObj.scaleY
|
let scaleY = flScaleY
|
||||||
let opacity = 1
|
let opacity = 1
|
||||||
let angle = 0
|
let angle = 0
|
||||||
let gapX = 0
|
let gapX = 0
|
||||||
@@ -1725,8 +1731,8 @@ backgroundObject.scaleY,'CanvasManager resetCanvasSizeByFixedLayer')
|
|||||||
let flipY = false;
|
let flipY = false;
|
||||||
let blendMode = BlendMode.MULTIPLY;
|
let blendMode = BlendMode.MULTIPLY;
|
||||||
if(item.object){
|
if(item.object){
|
||||||
top += item.object.top * fixedLayerObj.scaleY
|
top += item.object.top * flScaleY
|
||||||
left += item.object.left * fixedLayerObj.scaleX
|
left += item.object.left * flScaleX
|
||||||
scaleX *= item.object.scaleX
|
scaleX *= item.object.scaleX
|
||||||
scaleY *= item.object.scaleY
|
scaleY *= item.object.scaleY
|
||||||
opacity = item.object.opacity
|
opacity = item.object.opacity
|
||||||
@@ -1742,8 +1748,8 @@ backgroundObject.scaleY,'CanvasManager resetCanvasSizeByFixedLayer')
|
|||||||
id: id,
|
id: id,
|
||||||
layerId: id,
|
layerId: id,
|
||||||
layerName: name,
|
layerName: name,
|
||||||
width: fixedLayerObj.width,
|
width: flWidth,
|
||||||
height: fixedLayerObj.height,
|
height: flHeight,
|
||||||
top: top,
|
top: top,
|
||||||
left: left,
|
left: left,
|
||||||
scaleX: scaleX,
|
scaleX: scaleX,
|
||||||
|
|||||||
@@ -53,11 +53,15 @@ export class PartManager {
|
|||||||
// 当前工具
|
// 当前工具
|
||||||
this.activeTool = this.toolManager.activeTool;
|
this.activeTool = this.toolManager.activeTool;
|
||||||
|
|
||||||
|
this.rgba = { r: 0, g: 255, b: 0, a: 200 };
|
||||||
this.partGroup = null; // 当前选区对象
|
this.partGroup = null; // 当前选区对象
|
||||||
this.partId = "part_selector";
|
this.partId = "part_selector";
|
||||||
this.partCanvas = null;// 选区画布
|
this.partCanvas = null;// 选区画布
|
||||||
// 点选工具相关
|
// 点位列表
|
||||||
this.pointList = []; // 存储点选坐标
|
this.pointList = []; // 存储点选坐标
|
||||||
|
|
||||||
|
// 绘制列表
|
||||||
|
this.drawList = []; // 存储绘制对象
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -69,6 +73,10 @@ export class PartManager {
|
|||||||
const wasActive = this.isActive;
|
const wasActive = this.isActive;
|
||||||
this.isActive = this.tools.includes(toolId);
|
this.isActive = this.tools.includes(toolId);
|
||||||
|
|
||||||
|
if (toolId === OperationType.PART_ERASER) {
|
||||||
|
this.setEraserTool();
|
||||||
|
}
|
||||||
|
|
||||||
// 如果从非选区工具切换到选区工具,初始化事件
|
// 如果从非选区工具切换到选区工具,初始化事件
|
||||||
if (!wasActive && this.isActive) {
|
if (!wasActive && this.isActive) {
|
||||||
this.initEvents();
|
this.initEvents();
|
||||||
@@ -79,11 +87,12 @@ export class PartManager {
|
|||||||
this.cleanupEvents();
|
this.cleanupEvents();
|
||||||
this.clearPartObject();
|
this.clearPartObject();
|
||||||
this.clearPointData();
|
this.clearPointData();
|
||||||
} else {
|
|
||||||
this.clearPointData();
|
|
||||||
this.resetPartObject();
|
|
||||||
}
|
}
|
||||||
console.log("切换工具", toolId);
|
// 如果从选区工具切换到选区工具,重置选区
|
||||||
|
else if (wasActive && this.isActive) {
|
||||||
|
// this.clearPointData();
|
||||||
|
// this.resetPartObject();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 初始化选区相关事件 */
|
/** 初始化选区相关事件 */
|
||||||
@@ -246,8 +255,7 @@ export class PartManager {
|
|||||||
const image1 = await this.loadImageToObject(url);
|
const image1 = await this.loadImageToObject(url);
|
||||||
this.resetPartObject();
|
this.resetPartObject();
|
||||||
const group = this.partGroup;
|
const group = this.partGroup;
|
||||||
const rgba = { r: 0, g: 255, b: 0, a: 200 }
|
const canvas = getObjectAlphaToCanvas(image1, null, 0, this.rgba);
|
||||||
const canvas = getObjectAlphaToCanvas(image1, null, 0, rgba);
|
|
||||||
this.partCanvas = canvas;
|
this.partCanvas = canvas;
|
||||||
const image2 = new fabric.Image(canvas);
|
const image2 = new fabric.Image(canvas);
|
||||||
image2.set({
|
image2.set({
|
||||||
@@ -300,8 +308,7 @@ export class PartManager {
|
|||||||
const image1 = await this.loadImageToObject(url);
|
const image1 = await this.loadImageToObject(url);
|
||||||
this.resetPartObject();
|
this.resetPartObject();
|
||||||
const group = this.partGroup;
|
const group = this.partGroup;
|
||||||
const rgba = { r: 0, g: 255, b: 0, a: 200 }
|
const canvas = getObjectAlphaToCanvas(image1, null, 0, this.rgba);
|
||||||
const canvas = getObjectAlphaToCanvas(image1, null, 0, rgba);
|
|
||||||
this.partCanvas = canvas;
|
this.partCanvas = canvas;
|
||||||
const image2 = new fabric.Image(canvas);
|
const image2 = new fabric.Image(canvas);
|
||||||
image2.set({
|
image2.set({
|
||||||
@@ -311,45 +318,6 @@ export class PartManager {
|
|||||||
group.add(image2);
|
group.add(image2);
|
||||||
this.canvas.renderAll();
|
this.canvas.renderAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** 绘制工具模式下点击事件处理 */
|
|
||||||
_brushDownHandler(options) {
|
|
||||||
}
|
|
||||||
/** 绘制工具模式下移动事件处理 */
|
|
||||||
_brushMoveHandler(options) {
|
|
||||||
|
|
||||||
}
|
|
||||||
/** 绘制工具模式下抬起事件处理 */
|
|
||||||
_brushUpHandler(options) {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** 擦除工具模式下抬起事件处理 */
|
|
||||||
_eraseUpHandler(options) {
|
|
||||||
}
|
|
||||||
/** 擦除工具模式下点击事件处理 */
|
|
||||||
_eraseDownHandler(options) {
|
|
||||||
}
|
|
||||||
/** 擦除工具模式下移动事件处理 */
|
|
||||||
_eraseMoveHandler(options) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 处理鼠标点位 */
|
|
||||||
handleMousePosition(options, fixedObject) {
|
|
||||||
const pos = options.absolutePointer;
|
|
||||||
const { x, y } = options.absolutePointer;
|
|
||||||
const width = fixedObject.width * fixedObject.scaleX;
|
|
||||||
const height = fixedObject.height * fixedObject.scaleY;
|
|
||||||
const X = (x - (fixedObject.left - width / 2)) / fixedObject.scaleX;
|
|
||||||
const Y = (y - (fixedObject.top - height / 2)) / fixedObject.scaleY;
|
|
||||||
return {
|
|
||||||
x: Math.round(X),
|
|
||||||
y: Math.round(Y),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 获取分隔后图片 */
|
/** 获取分隔后图片 */
|
||||||
async getSegAnythingImage(obj) {
|
async getSegAnythingImage(obj) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -378,6 +346,85 @@ export class PartManager {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
/** 处理鼠标点位 */
|
||||||
|
handleMousePosition(options, fixedObject) {
|
||||||
|
const pos = options.absolutePointer;
|
||||||
|
const { x, y } = options.absolutePointer;
|
||||||
|
const width = fixedObject.width * fixedObject.scaleX;
|
||||||
|
const height = fixedObject.height * fixedObject.scaleY;
|
||||||
|
const X = (x - (fixedObject.left - width / 2)) / fixedObject.scaleX;
|
||||||
|
const Y = (y - (fixedObject.top - height / 2)) / fixedObject.scaleY;
|
||||||
|
return {
|
||||||
|
x: Math.round(X),
|
||||||
|
y: Math.round(Y),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async addPartImage(fabricImage) {
|
||||||
|
const scaleX = fabricImage.scaleX / this.partGroup.scaleX;
|
||||||
|
const scaleY = fabricImage.scaleY / this.partGroup.scaleY;
|
||||||
|
const top = (fabricImage.top - this.partGroup.top) / this.partGroup.scaleY;
|
||||||
|
const left = (fabricImage.left - this.partGroup.left) / this.partGroup.scaleX;
|
||||||
|
fabricImage.set({
|
||||||
|
scaleX,
|
||||||
|
scaleY,
|
||||||
|
top: top + this.partGroup.height / 2,
|
||||||
|
left: left + this.partGroup.width / 2,
|
||||||
|
})
|
||||||
|
this.drawList.push(fabricImage);
|
||||||
|
const tcanvas = new fabric.StaticCanvas(document.createElement("canvas"), {
|
||||||
|
width: this.partGroup.width,
|
||||||
|
height: this.partGroup.height,
|
||||||
|
enableRetinaScaling: false,
|
||||||
|
});
|
||||||
|
this.drawList.forEach(item => tcanvas.add(item))
|
||||||
|
tcanvas.renderAll();
|
||||||
|
const canvas = getObjectAlphaToCanvas(tcanvas, null, 0, this.rgba);
|
||||||
|
this.partCanvas = canvas;
|
||||||
|
const image = new fabric.Image(canvas);
|
||||||
|
image.set({
|
||||||
|
originX: this.partGroup.originX,
|
||||||
|
originY: this.partGroup.originY,
|
||||||
|
erasable: true,
|
||||||
|
});
|
||||||
|
this.resetPartObject();
|
||||||
|
this.partGroup.add(image);
|
||||||
|
this.canvas.renderAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 绘制工具模式下点击事件处理 */
|
||||||
|
_brushDownHandler(options) {
|
||||||
|
}
|
||||||
|
/** 绘制工具模式下移动事件处理 */
|
||||||
|
_brushMoveHandler(options) {
|
||||||
|
|
||||||
|
}
|
||||||
|
/** 绘制工具模式下抬起事件处理 */
|
||||||
|
_brushUpHandler(options) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 切换到擦除工具 */
|
||||||
|
setEraserTool() {
|
||||||
|
if (!this.canvas) return console.warn("未找到画布");
|
||||||
|
const objects = this.canvas.getObjects();
|
||||||
|
objects.forEach(obj => {
|
||||||
|
obj.set({
|
||||||
|
erasable: true
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/** 擦除工具模式下抬起事件处理 */
|
||||||
|
_eraseUpHandler(options) {
|
||||||
|
}
|
||||||
|
/** 擦除工具模式下点击事件处理 */
|
||||||
|
_eraseDownHandler(options) {
|
||||||
|
}
|
||||||
|
/** 擦除工具模式下移动事件处理 */
|
||||||
|
_eraseMoveHandler(options) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/** 删除指定ID的对象 */
|
/** 删除指定ID的对象 */
|
||||||
removeObjectsById(id) {
|
removeObjectsById(id) {
|
||||||
@@ -415,6 +462,7 @@ export class PartManager {
|
|||||||
originY: fixedObject.originY,
|
originY: fixedObject.originY,
|
||||||
selectable: false,
|
selectable: false,
|
||||||
evented: false,
|
evented: false,
|
||||||
|
erasable: false,
|
||||||
})
|
})
|
||||||
this.canvas.add(group);
|
this.canvas.add(group);
|
||||||
this.partGroup = group;
|
this.partGroup = group;
|
||||||
|
|||||||
@@ -736,15 +736,40 @@ export class ToolManager {
|
|||||||
if (!isExecute && this.canvasManager && this.canvasManager.partManager) {
|
if (!isExecute && this.canvasManager && this.canvasManager.partManager) {
|
||||||
this.canvasManager.partManager.setCurrentTool(OperationType.PART_BRUSH);
|
this.canvasManager.partManager.setCurrentTool(OperationType.PART_BRUSH);
|
||||||
}
|
}
|
||||||
|
const greenColor = "#0f0";
|
||||||
|
// 确保有笔刷管理器
|
||||||
|
if (this.brushManager) {
|
||||||
|
// 设置绿色笔刷
|
||||||
|
this.brushManager.setBrushColor(greenColor); // 纯绿色
|
||||||
|
this.brushManager.setBrushOpacity(200/255); // 完全不透明
|
||||||
|
this.brushManager.setBrushType("pencil"); // 铅笔类型
|
||||||
|
|
||||||
|
// 更新笔刷大小(使用当前大小)
|
||||||
|
if (BrushStore && BrushStore.state.size) {
|
||||||
|
this.brushManager.setBrushSize(BrushStore.state.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新应用到画布
|
||||||
|
this.brushManager.updateBrush();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 启用笔刷指示器并设置绿色
|
||||||
|
this._enableBrushIndicator(greenColor);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 设置部件选取工具--橡皮擦
|
* 设置部件选取工具--橡皮擦
|
||||||
*/
|
*/
|
||||||
setupPartEraserTool(isExecute = false) {
|
setupPartEraserTool(isExecute = false) {
|
||||||
if (!this.canvas) return;
|
if (!this.canvas) return;
|
||||||
this.canvas.isDrawingMode = false;
|
this.canvas.isDrawingMode = true;
|
||||||
this.canvas.selection = false;
|
this.canvas.selection = false;
|
||||||
if (!isExecute && this.canvasManager && this.canvasManager.partManager) {
|
if (this.brushManager) {
|
||||||
|
this.brushManager.createEraser();
|
||||||
|
}
|
||||||
|
// 启用笔刷指示器
|
||||||
|
this._enableBrushIndicator();
|
||||||
|
|
||||||
|
if (!isExecute && this.canvasManager && this.canvasManager.partManager) {
|
||||||
this.canvasManager.partManager.setCurrentTool(OperationType.PART_ERASER);
|
this.canvasManager.partManager.setCurrentTool(OperationType.PART_ERASER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1602,7 +1627,9 @@ export class ToolManager {
|
|||||||
OperationType.ERASER,
|
OperationType.ERASER,
|
||||||
OperationType.RED_BRUSH,
|
OperationType.RED_BRUSH,
|
||||||
OperationType.GREEN_BRUSH,
|
OperationType.GREEN_BRUSH,
|
||||||
OperationType.LIQUIFY,
|
OperationType.LIQUIFY,
|
||||||
|
OperationType.PART_BRUSH,
|
||||||
|
OperationType.PART_ERASER,
|
||||||
];
|
];
|
||||||
|
|
||||||
return brushTools.includes(currentTool);
|
return brushTools.includes(currentTool);
|
||||||
|
|||||||
@@ -69,6 +69,10 @@ export async function restoreFabricObject(serializedObject, canvas) {
|
|||||||
*/
|
*/
|
||||||
export function getObjectAlphaToCanvas(object, revData, diff = 30, rgba = { r: 255, g: 255, b: 255, a: 255 }) {
|
export function getObjectAlphaToCanvas(object, revData, diff = 30, rgba = { r: 255, g: 255, b: 255, a: 255 }) {
|
||||||
const image = object.getElement();
|
const image = object.getElement();
|
||||||
|
if (image.nodeName !== "IMG" && image.nodeName !== "CANVAS") {
|
||||||
|
console.warn("对象不是图片");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
const { width, height } = image;
|
const { width, height } = image;
|
||||||
if (!width || !height) {
|
if (!width || !height) {
|
||||||
console.warn("对象没有元素");
|
console.warn("对象没有元素");
|
||||||
|
|||||||
@@ -417,7 +417,6 @@
|
|||||||
}"
|
}"
|
||||||
@change-canvas="changeCanvas"
|
@change-canvas="changeCanvas"
|
||||||
@canvas-init="canvasInit"
|
@canvas-init="canvasInit"
|
||||||
isFixedErasable
|
|
||||||
showFixedLayer
|
showFixedLayer
|
||||||
>
|
>
|
||||||
<template #existsImageList>
|
<template #existsImageList>
|
||||||
|
|||||||
@@ -155,6 +155,7 @@
|
|||||||
.repeat-setting {
|
.repeat-setting {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
width: 228px;
|
width: 228px;
|
||||||
|
overflow: hidden;
|
||||||
> .title {
|
> .title {
|
||||||
line-height: 35px;
|
line-height: 35px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
|||||||
Reference in New Issue
Block a user