框选元素中包含分组,旋转时线条跟随矩形中心点移动实现方式?

框选元素中包含分组,旋转时线条跟随矩形中心点移动。
旋转前: 框选元素中包含分组,旋转时线条跟随矩形中心点移动实现方式?
旋转后: 框选元素中包含分组,旋转时线条跟随矩形中心点移动实现方式?

目前采用方法是自己通过三角形余玄函数rotatoNi函数来算坐标的,不知道有没有什么其他方法。(类似fabric提供的函数或属性来更新坐标)

<template>

<div>

<div class="btn" @click="setzoom(0.1)">放大</div>

<div class="btn" @click="setzoom(-0.1)">缩小</div>

<div class="btn" @click="addbox">添加</div>

<div class="btn">初始坐标: X:{{pointer.x.toFixed(0)}} Y:{{pointer.y.toFixed(0)}}</div>

<section style="margin: 0 auto;

clear: both;

width: 1000px;

border: 1px solid yellow;">

<canvas id="can" class="can" style="border:1px solid red;"></canvas>

</section>

</div>

</template>

<script>

var canvas;

var lineArr = {};

var triangle = {};

var canvasDom

var firstAdd

import bus from "@/assets/js/bus.js";

import { fabric } from "fabric";

import myCanvas from "./myCanvas";

export default {

computed: {

},

data () {

return {

allData: [], //所有箱体数据

pointer: {

x: 0,

y: 0

},

i: 1,

plist: [],

setColor: ['#FF0000', '#F2C94C', '#EBFF00', '#9B51E0', '#6FCF97',

'#F2F2F2', '#00FFF0', '#33FF00', '#00A3FF', '#FF00C7', '#FF7A00', '#0075FF']

};

},

mounted () {

this.initCanvas()

this.getboxList()

},

watch: {

},

methods: {

//移动和旋转

movAndrotat (p, type) {

let that = this;

if (p) {

if (p.isCheckTo) {

//单选

p._objects[2].set({ angle: -parseFloat(p.angle) }); //单个旋转文字角度不变

that.allData.forEach((item, k) => {

if (item.id == p.id) {

item.rotationAngle = parseFloat(p.angle) % 360;

item.x = p.calcOwnMatrix()[4];

item.y = p.calcOwnMatrix()[5];

item.operateType = "moving";

}

});

} else {

//多选箱体

if (p.type == "group" && p.groupId != "box") {

// 页面直接选择某分组

let objs = p._objects;

let ownMatrixCache = p.ownMatrixCache;

objs.forEach((obj, objIndex) => {

that.allData.forEach((item) => {

if (item.id == obj.id) {

if (type == "moving") {

let gg = that.rotatoNi(

obj.ownMatrixCache.value[4] + ownMatrixCache.value[4],

obj.ownMatrixCache.value[5] + ownMatrixCache.value[5],

ownMatrixCache.value[4],

ownMatrixCache.value[5],

parseFloat(p.angle)

);

item.x = gg.x;

item.y = gg.y;

} else if (type == "rotating") {

item.rotationAngle = (parseFloat(obj.angle) + parseFloat(p.angle)) % 360;

let gg = that.rotatoNi(

obj.ownMatrixCache.value[4] + ownMatrixCache.value[4],

obj.ownMatrixCache.value[5] + ownMatrixCache.value[5],

ownMatrixCache.value[4],

ownMatrixCache.value[5],

parseFloat(p.angle)

);

item.x = gg.x;

item.y = gg.y;

}

}

});

obj._objects[2].set({ angle: -((parseFloat(p.angle) + parseFloat(obj.angle)) % 360) }).setCoords()

});

} else {

var arr = p._objects;

for (var i = 0; i < arr.length; i++) {

if (arr[i].type == "group" && arr[i].groupId == "box") {

let angle =

parseInt(parseFloat(arr[i].angle) + parseFloat(p.angle)) % 360;

arr[i]._objects[2].set({ angle: -angle }); //单个旋转文字角度不变

that.allData.forEach((item) => {

if (item.id == arr[i].id) {

item.rotationAngle = angle;

item.x = arr[i].matrixCache.value[4];

item.y = arr[i].matrixCache.value[5];

}

});

} else if (arr[i].type == "group" && arr[i].groupId != "box") {

let _objs = arr[i]._objects;

let groupValue = arr[i].matrixCache.value;

_objs.forEach((o, pp) => {

that.allData.forEach((item) => {

if (item.id == o.id) {

if (type == "moving") {

item.x = groupValue[4] + o.left;

item.y = groupValue[5] + o.top;

} else if (type == "rotating") {

let x1 = groupValue[4] + o.left;

let y1 = groupValue[5] + o.top;

let gg = that.rotatoNi(

x1,

y1,

groupValue[4],

groupValue[5],

p.angle

);

item.x = gg.x;

item.y = gg.y;

item.rotationAngle = ((p.angle + o.angle) % 360)

o._objects[2].set({ angle: -((p.angle + o.angle) % 360) })

}

}

});

});

}

}

}

}

that.handleDataMovingRotating(type);

canvas.renderAll();

that.activeTpye = true;

if (type == "moving") {

that.movup = true;

}

if (type == "rotating") {

that.rotup = true;

}

}

},

handleDataMovingRotating (type) {

let that = this;

let activeSelection = canvas.getActiveObject();

let activeRectIds = [];

if (activeSelection) {

if (activeSelection.isCheckTo) {

activeRectIds.push(activeSelection.id);

} else {

let objs = activeSelection._objects;

objs.forEach((o) => {

if (o.type == "group" && o.groupId != "box") {

let items = o._objects;

items.forEach((item) => {

activeRectIds.push(item.id);

});

} else {

activeRectIds.push(o.id);

}

});

}

}

canvas.forEachObject(function (obj, i) {

if (["triangle", "line"].indexOf(obj.type) != -1) {

if (

(obj.type == "line" && obj.startId && obj.strokeDashArray.length == 0) ||

obj.type == "triangle"

) {

let startId = obj.startId;

let endId = obj.endId;

if (

activeRectIds.indexOf(startId) >= 0 ||

activeRectIds.indexOf(endId) >= 0

) {

let [x1, y1, x2, y2] = [0, 0, 0, 0];

that.allData.forEach((data) => {

if (data.id == startId) {

[x1, y1] = [data.x, data.y];

} else if (data.id == endId) {

[x2, y2] = [data.x, data.y];

}

});

if (obj.type == "line") {

obj

.set({

x1,

y1,

x2,

y2,

})

.setCoords();

} else if (obj.type == "triangle") {

obj

.set({

angle: that.getAngle(x1, y1, (x1 + x2) / 2, (y1 + y2) / 2),

left: (x1 + x2) / 2,

top: (y1 + y2) / 2,

})

.setCoords();

}

}

}

}

});

},

addbox () {

let par = {

width: 100,

height: 100,

type: 1,

x: -100,

y: -100,

boxFileId: 1,

index: 0,

boxStatus: 1,

rotationAngle: 0,

visible: true,

};

this.plist.push(par)

firstAdd = this.groupAdd(par, canvas);

canvas.add(firstAdd);

//firstAdd.scale(this.i).setCoords();

},

setzoom (num) {

this.i = this.i + num

if (this.i <= 4 || this.i >= 0.2) {

}

canvas.setZoom(this.i);

/* canvasDom.width = 600 * i

canvasDom.height = 600 * i */

canvas.setWidth(600 * this.i);

canvas.setHeight(600 * this.i);

canvas.renderAll();

canvas.forEachObject((obj, j) => {

if (obj.type == "group") {

}

});

},

//初始化fabric画布

initCanvas () {

let that = this;

canvasDom = document.getElementById("can");

canvasDom.width = 600

canvasDom.height = 600

canvas = new fabric.Canvas("can", { selection: true }); //selection 是否支持多选

canvas.on({

"object:moving": function (e) {

var p = e.target;

that.movAndrotat(p, "moving");

},

"object:rotating": function (e) {

var p = e.target;

that.movAndrotat(p, "rotating");

},

"object:scaling": function (e) {

},

"mouse:down": function (e) {

console.log('点击当前箱体', e)

if (that.plist.length > 0) {

that.plist[0].x = e.pointer.x

that.plist[0].y = e.pointer.y

firstAdd = that.groupAdd(that.plist, canvas);

canvas.add(firstAdd);

that.allData.push(that.plist[0])

that.plist = []

}

},

"mouse:up": function (e) { },

// 点击空白部分长按拖动箱体区域

"mouse:move": function (e) {

let x = e.pointer.x;

let y = e.pointer.y;

that.pointer = e.pointer

if (firstAdd) {

firstAdd.set({ visible: true, left: x, top: y }).setCoords();

canvas.renderAll();

}

return

},

// 鼠标滚动画布放大缩小

"mouse:wheel": function (e) { },

"mouse:over": function (e) { },

//离开画布

"mouse:out": function (e) {

that.pointer = {

x: 0,

y: 0

}

},

"selection:created": function (e) { },

"before:selection:cleared": function (e) { },

});

fabric.Group.prototype.hasControls = true;

canvas.selectionLineWidth = 3;

fabric.Group.prototype.setControlsVisibility({

mt: false,

mb: false,

bl: false,

br: false,

tl: false,

tr: false,

mr: false,

ml: false,

mtr: true,

});

canvas.preserveObjectStacking = false;

},

//查询箱体

getboxList (isflag, callback) {

let res = {

"status": 200, "msg": "SUCCESS", "obj": [{

"outputId": 1, "slotId": 1, "portId": 2, "list": [

{

boxFileId: 1,

boxStatus: 1,

height: 100,

index: 1,

rotationAngle: 0,

type: 1,

visible: true,

width: 100,

x: 150,

id: 1,

y: 200,

groupId: "box",

groupIdd: "5",

networkPort: 2

}, {

boxFileId: 1,

boxStatus: 1,

height: 100,

index: 2,

rotationAngle: 0,

type: 1,

visible: true,

width: 100,

x: 250,

y: 300,

id: 2,

groupId: "box",

groupIdd: "5",

networkPort: 2

}, {

boxFileId: 1,

boxStatus: 1,

height: 100,

index: 3,

rotationAngle: 0,

type: 1,

visible: true,

width: 100,

x: 380,

y: 300,

id: 3,

networkPort: 2

}

],

},

], "total": 0

}

let arr = [];

if (res.obj && res.obj.length > 0) {

let array = res.obj;

for (let i = 0; i < array.length; i++) {

let item = array[i].list;

for (let index = 0; index < item.length; index++) {

item[index].slotId = array[i].slotId;

arr.push(item[index]);

}

}

}

this.allData = arr;

this.handleData2("init");

for (let i = 0; i < arr.length; i++) {

let ltgo = this.groupAdd(arr[i], canvas)

canvas.add(ltgo);

ltgo.scale(this.i).setCoords();

}

this.initGroup();

callback && callback();

return arr;

},

initGroup () {

let boxes = [];

let objs = canvas.getObjects();

objs.map((item) => {

if (item.groupIdd) {

boxes.push(item);

}

});

if (boxes.length) {

var sel = new fabric.ActiveSelection(boxes, {

canvas: canvas,

});

canvas.setActiveObject(sel);

let group = canvas.getActiveObject().toGroup({});

group.set({

id: boxes.groupIdd,

});

canvas.requestRenderAll();

}

},

//重新连线

handleData2 (type) {

//获取所有箱体数据处理 start

canvas.forEachObject(function (obj, i) {

if (["triangle", "line"].indexOf(obj.type) != -1) {

canvas.remove(obj);

}

});

var typeWk = [];

this.allData.forEach((item) => {

if (typeWk.indexOf(item.networkPort) == -1) {

typeWk.push(item.networkPort);

}

});

typeWk.forEach((item) => {

var newarr = this.allData.filter(function (obj) {

return obj.networkPort == item;

});

newarr = newarr.sort((a, b) => {

return a.index - b.index;

});

newarr.forEach((m, n) => {

m.index = n + 1;

});

let result = [];

newarr.forEach((item) => {

result.push(item);

});

this.initLines(result, canvas, type);

});

},

//初始化生成线段

initLines (list, canvas, type) {

list = list.sort((a, b) => {

return a.index - b.index;

});

for (var i = 0; i < list.length; i++) {

var dot = list[i];

var todot = list[i];

if (parseInt(i) + 1 < list.length) {

todot = list[parseInt(i) + 1];

}

if (parseInt(i) + 1 != list.length) {

lineArr["AAA" + i] = this.makeLine(

[dot.x, dot.y, todot.x, todot.y],

list[i],

[],

"",

dot.id ? dot.id : dot.boxId,

todot.id ? todot.id : todot.boxId

);

canvas.add(lineArr["AAA" + i]);

triangle["AAA" + i] = this.createArrowHead(

dot.x,

dot.y,

(todot.x + dot.x) / 2,

(todot.y + dot.y) / 2,

10,

10,

list[i],

type,

dot.id ? dot.id : dot.boxId,

todot.id ? todot.id : todot.boxId

);

canvas.add(triangle["AAA" + i]);

}

}

},

rotatoNi (x1, y1, x2, y2, reg) {

// 在平面坐标上,任意点P(x1,y1),绕一个坐标点Q(x2,y2)逆时针旋转θ角度后,新的坐标设为(x, y)的计算公式:

// x= (x1 - x2)*cos(θ) - (y1 - y2)*sin(θ) + x2 ;

// y= (x1 - x2)*sin(θ) + (y1 - y2)*cos(θ) + y2 ;

let x = parseInt((x1 - x2) * Math.cos(Math.PI * reg / 180) - (y1 - y2) * Math.sin(Math.PI * reg / 180) + x2);

let y = parseInt((x1 - x2) * Math.sin(Math.PI * reg / 180) + (y1 - y2) * Math.cos(Math.PI * reg / 180) + y2);

return { x: x, y: y } //旋转后的坐标(x,y)

},

//左上角直角三角形

creatPath (list, i, type) {

//console.log('当前箱体左上角直角三角形数据', list, i, type)

let wc = 0

let x1 = list.x - list.width / 2 + wc

let y1 = list.y - list.height / 2 + wc

let prot = this.rotatoNi(x1, y1, list.x, list.y, list.rotationAngle)

let x = prot.x

let y = prot.y

let u = 'M ' + x + ' ' + y + ' L ' + (x + 10) + ' ' + y + ' L ' + x + ' ' + (y + 10) + ' z'

var path = new fabric.Path(u);

//console.log(i + '三角形的坐标点', x, y)

return path.set({

angle: list.rotationAngle,

left: x, //距离画布上边的距离

top: y, //距离画布左侧的距离,单位是像素

fill: '#FFFFFF', //填充的颜色

selectable: false,

stroke: '#FFFFFF', // 边框颜色

opacity: 0.3,

strokeWidth: 1,

id: list.id,

networkPort: list.networkPort,

operateType: type,

});

},

//创建中心点

makeCircle2 (list) {

var circle = new fabric.Circle({

originX: "center",

originY: "center",

left: list.x, //距离画布上边的距离

top: list.y, //距离画布左侧的距离,单位是像素

radius: 4, //圆形半径

fill: '#000', //填充的颜色

stroke: this.setColor[list.networkPort] ? this.setColor[list.networkPort] : '#fff', // 边框颜色

selectable: false,

evented: false,

id: list.id,

networkPort: list.networkPort,

index: list.index,

hoverCursor: "pointer",//鼠标指针方式

strokeWidth: 2 // 边框大小

});

return circle

},

//创建文本

makeText (t, list, i, type) {

let x1 = list.x - list.width / 2

let y1 = list.y - list.height / 2

let prot = this.rotatoNi(x1, y1, list.x, list.y, list.rotationAngle)

let x = (prot.x - list.x) / 1.5 + list.x

let y = (prot.y - list.y) / 1.5 + list.y

//console.log(i + '文本的坐标点', x, y)

var textBox = new fabric.Textbox(t, {

/* originX: "left",

originY: "top", */

originX: "center",

originY: "center",

left: x,

top: y,

centeredRotation: true, //中心旋转

fontSize: 12,

selectable: false,

evented: false,

networkPort: list.networkPort,

fill: '#fff',

id: list.id,

operateType: type,

});

return textBox

},

//创建矩形

makeRect (left, top, ids, width, height, angle, groupId, boxId, boxFileId) {

let rect = new fabric.Rect({

//rx: 4, //圆角半径

// ry: 4, //圆角半径

angle: angle,

left: left,

top: top,

originX: "center", //相对于坐标点位置

originY: "center", //相对于坐标点位置

width: width,

height: height,

//hoverCursor: "pointer",

fill: "rgba(0,153,255,0.20)",//"#1C445E",

stroke: '#136094', // 边框颜色

strokeWidth: 2, // 边框大小

borderColor: "#0099FF", //选中边框色

cornerStyle: "circle", // 手柄形状 正方形 rect||圆 circle

cornerColor: "#0099FF", //手柄背景色

cornerStrokeColor: "#0099FF", //手柄框边框

hasControls: true, //手柄

hasBorders: true, //手柄线

visible: true, //是否可见

selectable: true, //是否可选择的对象

evented: true, //是否拖动

centeredRotation: true, //中心旋转

centeredScaling: true, //居中缩放

transparentCorners: false, //选中框透明角

preserveObjectStacking: true,

// opacity: 0.5,

networkPort: ids.networkPort,//网口

index: ids.index,//序号

groupId: groupId,

id: boxId ? boxId : null,

boxFileId: boxFileId,

//lockRotation: true,//锁定对象旋转

});

rect.setControlsVisibility({

mt: false,

mb: false,

bl: false,

br: false,

tl: false,

tr: false,

mr: false,

ml: false,

mtr: true,

});

return rect;

},

//创建线段

/*

coords 坐标

list 当前对象

arr虚线

jt, 虚线箭头

*/

makeLine (coords, list, arr, jt, startId, endId) {

return new fabric.Line(coords, {

fill: this.setColor[list && list.networkPort] ? this.setColor[list && list.networkPort] : '#fff',

stroke: this.setColor[list && list.networkPort] ? this.setColor[list && list.networkPort] : '#fff',

strokeWidth: 2,

originX: "center",

originY: "center",

selectable: false,

evented: false,

hasControls: false,

hasBorders: false,

hasRotatingPoint: false,

hoverCursor: "default",

index: list.index,

networkPort: list && list.networkPort,

jt: jt || '',

id: list && list.id,

startId,

endId, //myJoker: arr,

strokeDashArray: arr || [],

huadongbs: list.huadongbs || false

});

},

//创建连线上的实体三角形箭头

createArrowHead (x1, y1, x2, y2, width, height, list, type, startId, endId) {

return new fabric.Triangle({

angle: this.getAngle(x1, y1, x2, y2),

fill: "white",

top: y2,

left: x2,

width: width,

height: height,

originX: "center",

originY: "center",

selectable: false,

evented: false,

id: list.id,

index: list.index,

networkPort: list.networkPort,

startId,

endId,

huadongbs: list.huadongbs || false

});

},

/* 绘制箭头函数 ------->--------

fromX, fromY:起点坐标(也可以换成p1,只不过它是一个数组)

toX, toY:终点坐标 (也可以换成p2,只不过它是一个数组)

theta:三角斜边一直线夹角

headlen:三角斜边长度

width:箭头线宽度

color:箭头颜色 */

drawArrow (canvas, fromX, fromY, toX, toY, theta, headlen, width, color) {

width = 1;//箭头宽度设置为1

var theta = theta || 30,

headlen = headlen || 10,

width = width || 1,

color = color || '#000',

angle = Math.atan2(fromY - toY, fromX - toX) * 180 / Math.PI,

angle1 = (angle + theta) * Math.PI / 180,

angle2 = (angle - theta) * Math.PI / 180,

topX = headlen * Math.cos(angle1),

topY = headlen * Math.sin(angle1),

botX = headlen * Math.cos(angle2),

botY = headlen * Math.sin(angle2);

var arrowX, arrowY;

arrowX = toX + topX; //箭头结尾左边坐标

arrowY = toY + topY;

canvas.add(this.makeLine([arrowX, arrowY, toX, toY], '', [], 'jt'));

//ctx.moveTo(arrowX, arrowY);

//ctx.lineTo(toX, toY); //箭头开始坐标

arrowX = toX + botX; //箭头结尾右边坐标

arrowY = toY + botY;

canvas.add(this.makeLine([arrowX, arrowY, toX, toY], '', [], 'jt'));

// ctx.lineTo(arrowX, arrowY);

},

//三角形角度计算

getAngle (x1, y1, x2, y2) {

var dx = x2 - x1,

dy = y2 - y1,

angle = Math.atan2(dy, dx);

angle *= 180 / Math.PI;

angle += 90;

return angle;

},

//改变画布大小

zoomIt (factor) { // factor: 比例

let cWidth = canvas.width;

canvas.setWidth(cWidth * factor);

canvas.setHeight(cWidth * factor);

if (canvas.backgroundImage) {

var bi = canvas.backgroundImage;

bi.width = bi.width * factor;

bi.height = bi.height * factor;

}

var objects = canvas.getObjects();

for (var i in objects) {

var scaleX = objects[i].scaleX;

var scaleY = objects[i].scaleY;

var left = objects[i].left;

var top = objects[i].top;

var tempScaleX = scaleX * factor;

var tempScaleY = scaleY * factor;

var tempLeft = left * factor;

var tempTop = top * factor;

objects[i].scaleX = tempScaleX;

objects[i].scaleY = tempScaleY;

objects[i].left = tempLeft;

objects[i].top = tempTop;

objects[i].setCoords();

}

canvas.renderAll();

canvas.calcOffset();

},

//阻止右键默认行为

preventYj () {

$(document).contextmenu(function (ev) {

if (ev.preventDefault) {

ev.preventDefault();

} else {

window.event.returnValue = false;

}

})

},

getTanDeg (tan) {

var result = Math.atan(tan) / (Math.PI / 180);

result = parseInt(result);

return result;

},

//自定义修改序号重新排序

setArrIndex (str, end, list) {

for (var i = 0; i < list.length; i++) {

if (end.index > list[i].index && list[i].index > str.index) {

list[i].index = list[i].index + 1

}

if (end.id == list[i].id) {

list[i].index = str.index + 1

}

}

list = list.sort((a, b) => {

return a.index - b.index

});

return list;

},

//自定义修改序号重新排序

setArrIndex2 (str, end, list) {

//序号2和4 实际就是3和4调换位置

if (str.index < end.index) {

list[str.index] = list.splice(end.index - 1, 1, list[str.index])[0];

for (var i = 0; i < list.length; i++) {

list[i].index = i + 1

}

} else {

list[end.index - 1].index = str.index

for (var i = 0; i < list.length; i++) {

if (str.index > list[i].index && list[i].index > end.index) {

list[i].index = list[i].index - 1

}

}

list[str.index - 1].index = str.index - 1

list = list.sort((a, b) => {

return a.index - b.index

});

}

return list;

},

compare (pro) {

return function (obj1, obj2) {

var val1 = obj1[pro];

var val2 = obj2[pro];

if (val1 < val2) { //正序

return 1;

} else if (val1 > val2) {

return -1;

} else {

return 0;

}

}

},

isMouseoeut (x, y) {

let that = this

var a = -15

let cdiv = document.getElementById("canvasZone")

var X1 = that.getOffsetLeft(cdiv) - a

var Y1 = that.getOffsetTop(cdiv) - a

var X2 = that.getOffsetLeft(cdiv) + cdiv.offsetWidth + a

var Y2 = that.getOffsetTop(cdiv) + cdiv.offsetHeight + a

if (x < X2 && x > X1 && y < Y2 && y > Y1) {

return true

} else {

return false

}

},

groupAdd (list, canvas) {

//console.log('新式分组')

/* x.y表示左上角点 */

var x1 = -50, y1 = -50, width = 100, height = 100;

let x = list.x - list.width / 2

let y = list.y - list.height / 2

let u = 'M ' + x + ' ' + y + ' L ' + (x + 10) + ' ' + y + ' L ' + x + ' ' + (y + 10) + ' z'

var path2 = new fabric.Path(u);

//左上角三角形

path2.set({

left: this.face == true ? (-(list.width / 2)) : (list.width / 2),

left: this.showFace == true ? (-(list.width / 2)) : (list.width / 2), top: -(list.height / 2),

fill: '#dadcdb', //填充的颜色

opacity: list.boxStatus == 1 ? 0.3 : 1,

strokeWidth: 1,

angle: this.face == true ? 0 : 90,

angle: this.showFace == true ? 0 : 90,

})

var t = list.index == 0 ? '' : (list.portId ? list.portId : 0) + "_" + list.index

//文字

// console.log(this.face);

var text2 = new fabric.Text(t, {

angle: -list.rotationAngle,

fontSize: 12,

originX: 'center',

originY: 'center',

fill: '#fff',

left: this.face == true ? (-(list.width / 2) + 20) : (list.width / 2 - 20),

left: this.showFace == true ? (-(list.width / 2) + 20) : (list.width / 2 - 20),

top: -(list.height / 2) + 20,

});

//中心点

var circle2 = new fabric.Circle({

originX: "center",

originY: "center",

radius: 4, //圆形半径

fill: '#000', //填充的颜色

stroke: this.setColor[list.networkPort] ? this.setColor[list.networkPort] : '#fff', // 边框颜色

selectable: false,

evented: false,

hoverCursor: "pointer",//鼠标指针方式

strokeWidth: 2 // 边框大小

});

//矩形

var rect2 = new fabric.Rect({

width: list.width,

height: list.height,

originX: 'center',

originY: 'center',

fill: "rgba(0,153,255,0.20)",//"#1C445E",

stroke: '#136094', // 边框颜色

strokeWidth: 2, // 边框大小

borderColor: "#0099FF", //选中边框色

cornerStyle: "circle", // 手柄形状 正方形 rect||圆 circle

cornerColor: "#0099FF", //手柄背景色

cornerStrokeColor: "#0099FF", //手柄框边框

centeredRotation: true,

portId: list.portId,

slotId: list.slotId,

});

var group2 = new fabric.Group([rect2, circle2, text2, path2], {

left: list.x,

top: list.y,

width: list.width,

height: list.height,

originX: 'center',

originY: 'center',

isCheckTo: true, //有这个字段表示单选,没有多选

networkPort: list.networkPort,//网口

index: list.index,//序号

groupId: 'box',

groupIdd: list.groupId,

id: list.id,

angle: list.rotationAngle,

centeredRotation: true,

fill: "#0099FF",//"#1C445E",

stroke: '#0099FF', // 边框颜色

strokeWidth: 2, // 边框大小

borderColor: "#0099FF", //选中边框色

cornerStyle: "circle", // 手柄形状 正方形 rect||圆 circle

cornerColor: "#0099FF", //手柄背景色

cornerStrokeColor: "#0099FF", //手柄框边框

huadongbs: list.huadongbs || false,

boxFileId: list.boxFileId,

portId: list.portId,

slotId: list.slotId,

// scaleX: this.i,

// scaleY: this.i

});

return group2

}

}

};

</script>

<style scoped>

.btn {

float: left;

margin: 15px;

cursor: pointer;

}

</style>

问题描述

问题出现的环境背景及自己尝试过哪些方法

相关代码

粘贴代码文本(请勿用截图)

你期待的结果是什么?实际看到的错误信息又是什么?

以上是 框选元素中包含分组,旋转时线条跟随矩形中心点移动实现方式? 的全部内容, 来源链接: utcz.com/p/935580.html

回到顶部