更新 fabric.Path 中的选择框
Update Selection Box in fabric.Path
版本
3.4.0
环境信息
Google Chrome | 77.0.3865.120(正式版)(64 位)(队列:稳定)
修订 | 416d6d8013e9adb6dd33b0c12e7614ff403d1a94-refs/branch-heads/3865@{#884}
OS | Windows 10 OS 版本 1803(内部版本 17134.1099)
JavaScript | V8 7.7.299.13
测试用例
https://jsfiddle.net/areuohm/y2not8em/32/
(function(){
var canvas = new fabric.Canvas('canvasWorkspaceFamiliogram', { selection: false });
fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';
var itemM = new fabric.Rect({width: 30,height: 30,fill: 'white',stroke: 'black',strokeWidth: 1, left:50,top:50});
var itemF = new fabric.Circle({radius: 15,fill: 'white',stroke: 'black',strokeWidth: 1,left: 400,top: 200});
itemF.relations = [];
itemM.relations = [];
canvas.add(itemM);
canvas.add(itemF);
createSVGPath(itemF,itemM,canvas);
canvas.renderAll();
}());
function createSVGPath(startObj, endObj, context){
var svgCommands = [
[ 'L', startObj.left, startObj.top],
[ 'V', startObj.top + 50],
[ 'H', endObj.left, endObj.top + 50],
[ 'V', endObj.top]
];
var line = new fabric.Path(svgCommands, {
fill: '', stroke: 'black', objectCaching: false, dirty: false,
perPixelTargetFind: true, selectable: true, hasControls: false
});
context.add(line);
let mi = svgCommands.length - 1;
startObj.relations.push({relation: line, maxIndex: mi, type:'M'});
endObj.relations.push({relation: line, maxIndex: mi, type:'Z'});
startObj.on('moving', function (e) {
this.relations.forEach((T,index) => {
if(T.type === 'M'){
T.relation.path[0][1] = e.target.left;
T.relation.path[0][2] = e.target.top;
}
});
context.requestRenderAll();
});
endObj.on('moving', function (e) {
this.relations.forEach((T,index) => {
if(T.type === 'Z'){
T.relation.path[T.maxIndex - 1][1] = e.target.left;
T.relation.path[T.maxIndex ][1] = e.target.top;
}
});
context.requestRenderAll();
});
}
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.4.0/fabric.min.js"></script>
<canvas id="canvasWorkspaceFamiliogram" width="500" height="470" style="border:1px solid #ccc"></canvas>
重现步骤
在我创建路径的初始状态下,选择框是根据线。但是如果我移动圆形或方形,路径线中的选择框不会更新
预期行为
¿如何刷新或更新此框?
问题在 Github
您需要更新路径对象的路径偏移量,并在修改任何起点或终点后调用setCoords。
演示版
(function() {
const canvas = new fabric.Canvas('canvasWorkspaceFamiliogram', {
selection: false
});
fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';
const itemM = new fabric.Rect({
width: 30,
height: 30,
fill: 'white',
stroke: 'black',
strokeWidth: 1,
left: 50,
top: 50
});
const itemF = new fabric.Circle({
radius: 15,
fill: 'white',
stroke: 'black',
strokeWidth: 1,
left: 400,
top: 200
});
itemF.relations = [];
itemM.relations = [];
canvas.add(itemM);
canvas.add(itemF);
createSVGPath(itemF, itemM, canvas);
canvas.renderAll();
}());
function createSVGPath(startObj, endObj, context) {
const svgCommands = [
['L', startObj.left, startObj.top],
['V', startObj.top + 50],
['H', endObj.left, endObj.top + 50],
['V', endObj.top]
];
const line = new fabric.Path(svgCommands, {
fill: '',
stroke: 'black',
objectCaching: false,
dirty: false,
perPixelTargetFind: true,
selectable: true,
hasControls: false
});
context.add(line);
const mi = svgCommands.length - 1;
startObj.relations.push({
relation: line,
maxIndex: mi,
type: 'M'
});
endObj.relations.push({
relation: line,
maxIndex: mi,
type: 'Z'
});
startObj.on('moving', function(e) {
this.relations.forEach((T, index) => {
if (T.type === 'M') {
T.relation.path[0][1] = e.target.left;
T.relation.path[0][2] = e.target.top;
}
});
context.requestRenderAll();
});
endObj.on('moving', function(e) {
this.relations.forEach((T, index) => {
if (T.type === 'Z') {
T.relation.path[T.maxIndex - 1][1] = e.target.left;
T.relation.path[T.maxIndex][1] = e.target.top;
}
});
context.requestRenderAll();
});
startObj.on('modified', updatePath);
endObj.on('modified', updatePath);
}
function updatePath() {
this.relations.forEach((T, index) => {
const obj = T.relation;
if (obj.type === 'path') {
fabric.Polyline.prototype._setPositionDimensions.call(obj, {});
obj.setCoords();
}
})
}
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.4.0/fabric.min.js"></script>
<canvas id="canvasWorkspaceFamiliogram" width="500" height="470" style="border:1px solid #ccc"></canvas>
版本
3.4.0
环境信息
Google Chrome | 77.0.3865.120(正式版)(64 位)(队列:稳定) 修订 | 416d6d8013e9adb6dd33b0c12e7614ff403d1a94-refs/branch-heads/3865@{#884} OS | Windows 10 OS 版本 1803(内部版本 17134.1099) JavaScript | V8 7.7.299.13
测试用例
https://jsfiddle.net/areuohm/y2not8em/32/
(function(){
var canvas = new fabric.Canvas('canvasWorkspaceFamiliogram', { selection: false });
fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';
var itemM = new fabric.Rect({width: 30,height: 30,fill: 'white',stroke: 'black',strokeWidth: 1, left:50,top:50});
var itemF = new fabric.Circle({radius: 15,fill: 'white',stroke: 'black',strokeWidth: 1,left: 400,top: 200});
itemF.relations = [];
itemM.relations = [];
canvas.add(itemM);
canvas.add(itemF);
createSVGPath(itemF,itemM,canvas);
canvas.renderAll();
}());
function createSVGPath(startObj, endObj, context){
var svgCommands = [
[ 'L', startObj.left, startObj.top],
[ 'V', startObj.top + 50],
[ 'H', endObj.left, endObj.top + 50],
[ 'V', endObj.top]
];
var line = new fabric.Path(svgCommands, {
fill: '', stroke: 'black', objectCaching: false, dirty: false,
perPixelTargetFind: true, selectable: true, hasControls: false
});
context.add(line);
let mi = svgCommands.length - 1;
startObj.relations.push({relation: line, maxIndex: mi, type:'M'});
endObj.relations.push({relation: line, maxIndex: mi, type:'Z'});
startObj.on('moving', function (e) {
this.relations.forEach((T,index) => {
if(T.type === 'M'){
T.relation.path[0][1] = e.target.left;
T.relation.path[0][2] = e.target.top;
}
});
context.requestRenderAll();
});
endObj.on('moving', function (e) {
this.relations.forEach((T,index) => {
if(T.type === 'Z'){
T.relation.path[T.maxIndex - 1][1] = e.target.left;
T.relation.path[T.maxIndex ][1] = e.target.top;
}
});
context.requestRenderAll();
});
}
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.4.0/fabric.min.js"></script>
<canvas id="canvasWorkspaceFamiliogram" width="500" height="470" style="border:1px solid #ccc"></canvas>
重现步骤
在我创建路径的初始状态下,选择框是根据线。但是如果我移动圆形或方形,路径线中的选择框不会更新
预期行为
¿如何刷新或更新此框?
问题在 Github
您需要更新路径对象的路径偏移量,并在修改任何起点或终点后调用setCoords。
演示版
(function() {
const canvas = new fabric.Canvas('canvasWorkspaceFamiliogram', {
selection: false
});
fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';
const itemM = new fabric.Rect({
width: 30,
height: 30,
fill: 'white',
stroke: 'black',
strokeWidth: 1,
left: 50,
top: 50
});
const itemF = new fabric.Circle({
radius: 15,
fill: 'white',
stroke: 'black',
strokeWidth: 1,
left: 400,
top: 200
});
itemF.relations = [];
itemM.relations = [];
canvas.add(itemM);
canvas.add(itemF);
createSVGPath(itemF, itemM, canvas);
canvas.renderAll();
}());
function createSVGPath(startObj, endObj, context) {
const svgCommands = [
['L', startObj.left, startObj.top],
['V', startObj.top + 50],
['H', endObj.left, endObj.top + 50],
['V', endObj.top]
];
const line = new fabric.Path(svgCommands, {
fill: '',
stroke: 'black',
objectCaching: false,
dirty: false,
perPixelTargetFind: true,
selectable: true,
hasControls: false
});
context.add(line);
const mi = svgCommands.length - 1;
startObj.relations.push({
relation: line,
maxIndex: mi,
type: 'M'
});
endObj.relations.push({
relation: line,
maxIndex: mi,
type: 'Z'
});
startObj.on('moving', function(e) {
this.relations.forEach((T, index) => {
if (T.type === 'M') {
T.relation.path[0][1] = e.target.left;
T.relation.path[0][2] = e.target.top;
}
});
context.requestRenderAll();
});
endObj.on('moving', function(e) {
this.relations.forEach((T, index) => {
if (T.type === 'Z') {
T.relation.path[T.maxIndex - 1][1] = e.target.left;
T.relation.path[T.maxIndex][1] = e.target.top;
}
});
context.requestRenderAll();
});
startObj.on('modified', updatePath);
endObj.on('modified', updatePath);
}
function updatePath() {
this.relations.forEach((T, index) => {
const obj = T.relation;
if (obj.type === 'path') {
fabric.Polyline.prototype._setPositionDimensions.call(obj, {});
obj.setCoords();
}
})
}
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.4.0/fabric.min.js"></script>
<canvas id="canvasWorkspaceFamiliogram" width="500" height="470" style="border:1px solid #ccc"></canvas>