深度画布智能选区
This commit is contained in:
@@ -28,7 +28,18 @@ export class LayerManager {
|
||||
return this.getLayerById(this.activeID.value)
|
||||
}
|
||||
getLayerById(id) {
|
||||
return this.layers.value.find((item: any) => item.info.id === id)
|
||||
function call(arr) {
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
let v = arr[i]
|
||||
if (v.info.id === id) return v
|
||||
if (v.children) {
|
||||
let layer = call(v.children)
|
||||
if (layer) return layer
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
return call(this.layers.value)
|
||||
}
|
||||
setLayerNameById(id, name: string) {
|
||||
const layer = this.getLayerById(id)
|
||||
@@ -82,6 +93,10 @@ export class LayerManager {
|
||||
|
||||
/** 删除指定图层 */
|
||||
deleteLayerById(id, isActive = true) {
|
||||
const layer = this.getLayerById(id)
|
||||
if (layer.children) {
|
||||
layer.children.forEach(v => this.canvasManager.deleteObjectById(v.info.id, false))
|
||||
}
|
||||
this.canvasManager.deleteObjectById(id)
|
||||
if (id === this.activeID.value && isActive) {
|
||||
this.setActiveID(this.layers.value[0]?.info?.id || "")
|
||||
@@ -106,17 +121,38 @@ export class LayerManager {
|
||||
this.setActiveID(newObject.info.id)
|
||||
})
|
||||
}
|
||||
// 拖拽排序
|
||||
dragSort(id, newIndex) {
|
||||
const index = Math.abs(this.layers.value.length - newIndex - 1)
|
||||
this.canvasManager.dragSort(id, index)
|
||||
/** 根据layers排序图层 */
|
||||
async sortLayers(isRecord?: boolean) {
|
||||
const ids = [];
|
||||
call(this.layers.value)
|
||||
await this.canvasManager.sortObjectByIds(ids.reverse(), isRecord)
|
||||
function call(arr) {
|
||||
arr.forEach(v => {
|
||||
ids.push(v.info.id)
|
||||
if (v.children) call(v.children)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 更新图层列表
|
||||
updateLayers() {
|
||||
this.layers.value = this.canvasManager.getObjects()
|
||||
.filter((v: any) => !!v?.info?.id)
|
||||
.reverse()
|
||||
.map(v => v.toObject())
|
||||
async updateLayers(isSort = false) {
|
||||
const objects = this.canvasManager.getObjects().map(v => v.toObject()).filter(v => !!v.info?.id).reverse()
|
||||
objects.forEach(v => {
|
||||
if (v.type === "group") {
|
||||
if (!v.children) v.children = []
|
||||
return;
|
||||
}
|
||||
const parentId = v.info?.parentId
|
||||
if (!parentId) return
|
||||
objects.forEach((obj: any) => {
|
||||
if (obj.info?.id !== parentId) return
|
||||
if (!obj.children) obj.children = []
|
||||
obj.children.push(v)
|
||||
})
|
||||
})
|
||||
const layers = objects.filter(v => !v.info?.parentId)
|
||||
this.layers.value = layers
|
||||
if (isSort) await this.sortLayers()
|
||||
}
|
||||
|
||||
/** 设置图层位置-不设置默认居中 */
|
||||
@@ -136,7 +172,7 @@ export class LayerManager {
|
||||
}
|
||||
}
|
||||
/** 创建空图层 */
|
||||
createEmptyLayer(isRecord = true, isActive = false) {
|
||||
async createEmptyLayer(isRecord = true, isActive = false) {
|
||||
const emptyObject = new fabric.Rect({
|
||||
width: 0,
|
||||
height: 0,
|
||||
@@ -147,37 +183,28 @@ export class LayerManager {
|
||||
}
|
||||
})
|
||||
this.setLayerPosition(emptyObject)
|
||||
this.canvasManager.add(emptyObject, isRecord)
|
||||
await this.canvasManager.add(emptyObject, isRecord)
|
||||
if (isActive) this.setActiveID(emptyObject.info.id, false)
|
||||
return emptyObject
|
||||
}
|
||||
/** 创建组图层 */
|
||||
createGroupLayer(options?: any, isRecord = true, isActive = false) {
|
||||
const child = options?.child || []
|
||||
delete options.child
|
||||
const groupObject = new fabric.Group(child, {
|
||||
// subTargetCheck: true, // 关键:检测子对象
|
||||
// interactive: true, // 启用交互
|
||||
// hasControls: true,
|
||||
// hasBorders: true,
|
||||
|
||||
// // 子对象样式
|
||||
// cornerColor: 'blue',
|
||||
// cornerSize: 8,
|
||||
// borderColor: 'green',
|
||||
|
||||
// // 允许子对象独立变换
|
||||
// lockScalingX: false,
|
||||
// lockScalingY: false,
|
||||
// lockRotation: false,
|
||||
async createGroupLayer(options?: any, isRecord = true, isActive = false) {
|
||||
const children = options?.children || []
|
||||
delete options.children
|
||||
const groupObject = new fabric.Group(children, {
|
||||
...(options || {}),
|
||||
hasControls: false, // 不显示控制点
|
||||
hasBorders: false, // 不显示边框
|
||||
selectable: false, // 不可选中(可选)
|
||||
info: {
|
||||
id: createId("group"),
|
||||
name: '组图层',
|
||||
showChildren: true,
|
||||
...(options?.info || {}),
|
||||
}
|
||||
})
|
||||
// this.setLayerPosition(groupObject)
|
||||
this.canvasManager.add(groupObject, isRecord)
|
||||
this.setLayerPosition(groupObject, options)
|
||||
await this.canvasManager.add(groupObject, isRecord)
|
||||
if (isActive) this.setActiveID(groupObject.info.id, false)
|
||||
return groupObject
|
||||
}
|
||||
@@ -199,7 +226,7 @@ export class LayerManager {
|
||||
return textObject
|
||||
}
|
||||
/** 创建矩形图层 */
|
||||
async createRectLayer(options?: any, isActive = false) {
|
||||
async createRectLayer(options?: any, isRecord = true, isActive = true) {
|
||||
const rectObject = new fabric.Rect({
|
||||
width: 100,
|
||||
height: 100,
|
||||
@@ -213,12 +240,12 @@ export class LayerManager {
|
||||
}
|
||||
})
|
||||
this.setLayerPosition(rectObject, options)
|
||||
await this.canvasManager.add(rectObject)
|
||||
await this.canvasManager.add(rectObject, isRecord)
|
||||
if (isActive) this.setActiveID(rectObject.info.id)
|
||||
return rectObject
|
||||
}
|
||||
/** 创建直线图层 */
|
||||
async createLineLayer(options?: any, isActive = false) {
|
||||
async createLineLayer(options?: any, isRecord = true, isActive = true) {
|
||||
const line = [options?.x1 || 0, options?.y1 || 0, options?.x2 || 100, options?.y2 || 0]
|
||||
delete options.x1
|
||||
delete options.y1
|
||||
@@ -235,14 +262,13 @@ export class LayerManager {
|
||||
}
|
||||
})
|
||||
this.setLayerPosition(lineObject, options)
|
||||
await this.canvasManager.add(lineObject)
|
||||
await this.canvasManager.add(lineObject, isRecord)
|
||||
if (isActive) this.setActiveID(lineObject.info.id)
|
||||
return lineObject
|
||||
}
|
||||
/** 创建椭圆图层 */
|
||||
async createEllipseLayer(options?: any, isActive = false) {
|
||||
async createEllipseLayer(options?: any, isRecord = true, isActive = true) {
|
||||
const ellipseObject = new fabric.Ellipse({
|
||||
radius: 50,
|
||||
fill: '#000',
|
||||
strokeWidth: 0,
|
||||
...(options || {}),
|
||||
@@ -258,7 +284,7 @@ export class LayerManager {
|
||||
return ellipseObject
|
||||
}
|
||||
/** 创建三角形图层 */
|
||||
async createTriangleLayer(options?: any, isActive = false) {
|
||||
async createTriangleLayer(options?: any, isRecord = true, isActive = true) {
|
||||
const triangleObject = new fabric.Triangle({
|
||||
width: 100,
|
||||
height: 100,
|
||||
@@ -272,12 +298,12 @@ export class LayerManager {
|
||||
}
|
||||
})
|
||||
this.setLayerPosition(triangleObject, options)
|
||||
await this.canvasManager.add(triangleObject)
|
||||
await this.canvasManager.add(triangleObject, isRecord)
|
||||
if (isActive) this.setActiveID(triangleObject.info.id)
|
||||
return triangleObject
|
||||
}
|
||||
/** 创建五角星图层 */
|
||||
async createStarLayer(options?: any, isActive = false) {
|
||||
async createStarLayer(options?: any, isRecord = true, isActive = true) {
|
||||
const width = options?.width || 100
|
||||
const height = options?.height || 100
|
||||
delete options.points
|
||||
@@ -292,12 +318,12 @@ export class LayerManager {
|
||||
}
|
||||
})
|
||||
this.setLayerPosition(starObject, options)
|
||||
await this.canvasManager.add(starObject)
|
||||
await this.canvasManager.add(starObject, isRecord)
|
||||
if (isActive) this.setActiveID(starObject.info.id)
|
||||
return starObject
|
||||
}
|
||||
/** 创建箭头图层 */
|
||||
async createArrowLayer(options?: any, isActive = false) {
|
||||
async createArrowLayer(options?: any, isRecord = true, isActive = true) {
|
||||
const width = options?.width || 100
|
||||
const height = options?.height || 10
|
||||
delete options.width
|
||||
@@ -316,7 +342,7 @@ export class LayerManager {
|
||||
}
|
||||
});
|
||||
this.setLayerPosition(arrowObject, options)
|
||||
this.canvasManager.add(arrowObject)
|
||||
await this.canvasManager.add(arrowObject, isRecord)
|
||||
if (isActive) this.setActiveID(arrowObject.info.id)
|
||||
return arrowObject
|
||||
}
|
||||
@@ -324,7 +350,7 @@ export class LayerManager {
|
||||
|
||||
|
||||
/** 创建图片图层 */
|
||||
async createImageLayer(imgOrUrl: string | HTMLImageElement, options?: any, isRecord = true) {
|
||||
async createImageLayer(imgOrUrl: string | HTMLImageElement, options?: any, isRecord = true, isActive = true) {
|
||||
const { canvasWidth, canvasHeight } = this.canvasManager.getCanvasSize();
|
||||
|
||||
const imageObject = await new Promise((resolve) => {
|
||||
@@ -350,7 +376,7 @@ export class LayerManager {
|
||||
}) as fabric.Object
|
||||
this.setLayerPosition(imageObject, options)
|
||||
await this.canvasManager.add(imageObject, isRecord)
|
||||
this.setActiveID(imageObject.info.id)
|
||||
if (isActive) this.setActiveID(imageObject.info.id)
|
||||
return imageObject
|
||||
}
|
||||
|
||||
@@ -363,6 +389,7 @@ export class LayerManager {
|
||||
left: info.left,
|
||||
top: info.top,
|
||||
info: {
|
||||
...(targetLayer?.info || {}),
|
||||
id: createId("image"),
|
||||
name: targetLayer?.info?.name || "合并图层",
|
||||
}
|
||||
@@ -370,7 +397,6 @@ export class LayerManager {
|
||||
resolve(img)
|
||||
}, { crossOrigin: 'anonymous' })
|
||||
})
|
||||
// console.log(mergedImage)
|
||||
const index = this.canvasManager.getObjects().indexOf(targetLayer);
|
||||
this.deleteLayerById(targetLayer.info.id, false)
|
||||
this.setActiveID(mergedImage.info.id, false)
|
||||
@@ -391,12 +417,12 @@ export class LayerManager {
|
||||
})
|
||||
}
|
||||
/** 更新图层缩略图 */
|
||||
async updateLayerThumbnailsById(id: string) {
|
||||
async updateLayerThumbnailsById(id: string, thumbnail?: string, isUpdate = true) {
|
||||
const object = this.canvasManager.getObjectById(id);
|
||||
if (!object) return;
|
||||
const url = await exportObjectToThumbnail(object);
|
||||
const url = thumbnail || await exportObjectToThumbnail(object);
|
||||
object.thumbnail = url
|
||||
this.updateLayers()
|
||||
if (isUpdate) this.updateLayers()
|
||||
}
|
||||
|
||||
dispose() { }
|
||||
|
||||
Reference in New Issue
Block a user