如何防止箭头(三角形+线组)缩放而线应该增加它的长度 - FabricJs 3.6.6
How to prevent arrow heads (triangles + line group) from scaling while the line should increase it's length - FabricJs 3.6.6
var canvas = new fabric.Canvas('canvas', {width: 400, height: 400});
canvas.on('object:scaled', function (e) {
let type = e.target.get('type');
if (type == 'group') {
var triangleCount = 0, triangles = [];
//console.log(e.target);
e.target._objects.forEach(function (object) {
if (object.get('type') == 'triangle') {
triangles[triangleCount] = object;
triangleCount++;
let ratio = 1 / e.target.get('scaleY');
object.set('scaleY', ratio);
}
});
canvas.requestRenderAll();
}
});
function addArrow() {
var line = new fabric.Line([10, 10, 10, (10 + 50)], {
strokeUniform: true,
lockScalingX: true,
borderColor: 'transparent',
left: 10,
top: 10,
strokeWidth: 2,
stroke: '#000'
});
var triangleBottom = new fabric.Triangle({
width: 16, height: 16, fill: '#000',
scaleX: 1, scaleY: 1, strokeUniform: true, lockScalingX: true, lockScalingY: true, lockUniScaling: true, lockSkewingX: true, lockSkewingY: true, left: (10 - 8), top: (10 + 36)
});
triangleBottom.rotate(180);
var triangleTop = new fabric.Triangle({
opacity: 1, width: 16, height: 16, fill: '#000', scaleX: 1, scaleY: 1, strokeUniform: true, lockScalingX: true, lockScalingY: true, left: (10 - 8), top: (10 - 0)
});
//groupItems.push(triangleTop);
let groupItems = [line, triangleBottom, triangleTop];
var group = new fabric.Group(groupItems, {
hasControls: true,
left: 10,
top: 10,
strokeUniform: true,
lockScalingX: true
}).setControlsVisibility({
tl: false,
tr: false,
mt: true,
mb: true,
ml: false,
mr: false,
bl: false,
br: false
});
canvas.add(group);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.6.6/fabric.min.js"></script>
<button onclick="addArrow()">Add arrow</button>
<canvas id="canvas" class="canvas" style="border:1px solid #000;"></canvas>
我对 fabric.js 有疑问。我创建了一个包含直线和 2 个三角形的“组”。所以它可以是我们的双头箭头。现在我想要的是能够旋转和缩放它。但这就是问题所在。我希望这些箭头保持相同的大小,不幸的是它们也 increasing/decreasing 缩放了线条。
我真的不知道如何解决它。这是我的尝试。尝试使用静态比率,因为默认情况下箭头的高度为 50,三角形的高度为 16,尝试了一些计算。但他们永远不会做出正确的决定。也确实尝试删除并重新输入这些三角形,但是在旋转和调整组大小时失败了。
我是不是遗漏了什么明显的东西?或者很难阻止我分组的一个元素缩放。我想做的另一件事是防止缩放矩形中的文本,但我担心它会再次成为同样的噩梦
canvas.on('object:scaled', function (e) {
let type = e.target.get('type');
if (type == 'group') {
var triangleCount = 0, triangles = [];
e.target._objects.forEach(function (object) {
if (object.get('type') == 'triangle') {
triangles[triangleCount] = object;
triangleCount++;
let currentGroupHeight = e.target.get('scaleY') * e.target.get('height');
let ratio = object.get('height') * e.target.get('scaleY') / e.target.get('height') * e.target.get('scaleY');
//object.set('scaleY', 50 / 16);
object.set('scaleY', ratio);
} else if (object.get('type') == 'i-text') {
//canvas.remove(object);
object.set({ scaleX: 1, scaleY: 1 });
}
});
canvas.requestRenderAll();
}
});
function addArrow(options, doubleHeads) {
var line = new fabric.Line([options.e.layerX, options.e.layerY, options.e.layerX, (options.e.layerY + 50)], {
strokeUniform: true,
lockScalingX: true,
borderColor: 'transparent',
left: options.e.layerX,
top: options.e.layerY,
});
var triangleBottom = new fabric.Triangle({
width: 16, height: 16, fill: '#000',
scaleX: 1, scaleY: 1, strokeUniform: true, lockScalingX: true, lockScalingY: true, lockUniScaling: true, lockSkewingX: true, lockSkewingY: true, left: (options.e.layerX - 8), top: (options.e.layerY + 36)
});
triangleBottom.rotate(180);
let display = 0;
if (doubleHeads) {
display = 1;
}
var triangleTop = new fabric.Triangle({
opacity: display, width: 16, height: 16, fill: '#000', scaleX: 1, scaleY: 1, strokeUniform: true, lockScalingX: true, lockScalingY: true, left: (options.e.layerX - 8), top: (options.e.layerY - 0)
});
//groupItems.push(triangleTop);
let groupItems = [line, triangleBottom, triangleTop];
var group = new fabric.Group(groupItems, {
hasControls: true,
left: options.e.layerX,
top: options.e.layerY,
strokeUniform: true,
lockScalingX: true
}).setControlsVisibility({
tl: false,
tr: false,
mt: true,
mb: true,
ml: false,
mr: false,
bl: false,
br: false
});
canvas.add(group);
}
我能想到的唯一方法是在object:scaling
事件中调用箭头调整功能。我想知道是否还有其他更好的解决方案。
var canvas = new fabric.Canvas('canvas', {width: 400, height: 400});
canvas.on('object:scaling', function (e) {
let type = e.target.get('type');
if (type == 'group') {
adjustArrowsSize(e.target._objects, e.target.get('scaleY'))
}
});
canvas.on('object:scaled', function (e) {
let type = e.target.get('type');
if (type == 'group') {
adjustArrowsSize(e.target._objects, e.target.get('scaleY'))
}
});
function adjustArrowsSize(arrowObjects, objectScaleY) {
var triangleCount = 0, triangles = [];
arrowObjects.forEach(function (object) {
if (object.get('type') == 'triangle') {
triangles[triangleCount] = object;
triangleCount++;
let ratio = 1 / objectScaleY;
object.set('scaleY', ratio);
}
});
canvas.requestRenderAll();
}
function addArrow() {
var line = new fabric.Line([10, 10, 10, (10 + 50)], {
strokeUniform: true,
lockScalingX: true,
borderColor: 'transparent',
left: 10,
top: 10,
strokeWidth: 2,
stroke: '#000'
});
var triangleBottom = new fabric.Triangle({
width: 16, height: 16, fill: '#000',
scaleX: 1, scaleY: 1, strokeUniform: true, lockScalingX: true, lockScalingY: true, lockUniScaling: true, lockSkewingX: true, lockSkewingY: true, left: (10 - 8), top: (10 + 36)
});
triangleBottom.rotate(180);
var triangleTop = new fabric.Triangle({
opacity: 1, width: 16, height: 16, fill: '#000', scaleX: 1, scaleY: 1, strokeUniform: true, lockScalingX: true, lockScalingY: true, left: (10 - 8), top: (10 - 0)
});
//groupItems.push(triangleTop);
let groupItems = [line, triangleBottom, triangleTop];
var group = new fabric.Group(groupItems, {
hasControls: true,
left: 10,
top: 10,
strokeUniform: true,
lockScalingX: true
}).setControlsVisibility({
tl: false,
tr: false,
mt: true,
mb: true,
ml: false,
mr: false,
bl: false,
br: false
});
canvas.add(group);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.6.6/fabric.min.js"></script>
<button onclick="addArrow()">Add arrow</button>
<canvas id="canvas" class="canvas" style="border:1px solid #000;"></canvas>
var canvas = new fabric.Canvas('canvas', {width: 400, height: 400});
canvas.on('object:scaled', function (e) {
let type = e.target.get('type');
if (type == 'group') {
var triangleCount = 0, triangles = [];
//console.log(e.target);
e.target._objects.forEach(function (object) {
if (object.get('type') == 'triangle') {
triangles[triangleCount] = object;
triangleCount++;
let ratio = 1 / e.target.get('scaleY');
object.set('scaleY', ratio);
}
});
canvas.requestRenderAll();
}
});
function addArrow() {
var line = new fabric.Line([10, 10, 10, (10 + 50)], {
strokeUniform: true,
lockScalingX: true,
borderColor: 'transparent',
left: 10,
top: 10,
strokeWidth: 2,
stroke: '#000'
});
var triangleBottom = new fabric.Triangle({
width: 16, height: 16, fill: '#000',
scaleX: 1, scaleY: 1, strokeUniform: true, lockScalingX: true, lockScalingY: true, lockUniScaling: true, lockSkewingX: true, lockSkewingY: true, left: (10 - 8), top: (10 + 36)
});
triangleBottom.rotate(180);
var triangleTop = new fabric.Triangle({
opacity: 1, width: 16, height: 16, fill: '#000', scaleX: 1, scaleY: 1, strokeUniform: true, lockScalingX: true, lockScalingY: true, left: (10 - 8), top: (10 - 0)
});
//groupItems.push(triangleTop);
let groupItems = [line, triangleBottom, triangleTop];
var group = new fabric.Group(groupItems, {
hasControls: true,
left: 10,
top: 10,
strokeUniform: true,
lockScalingX: true
}).setControlsVisibility({
tl: false,
tr: false,
mt: true,
mb: true,
ml: false,
mr: false,
bl: false,
br: false
});
canvas.add(group);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.6.6/fabric.min.js"></script>
<button onclick="addArrow()">Add arrow</button>
<canvas id="canvas" class="canvas" style="border:1px solid #000;"></canvas>
我对 fabric.js 有疑问。我创建了一个包含直线和 2 个三角形的“组”。所以它可以是我们的双头箭头。现在我想要的是能够旋转和缩放它。但这就是问题所在。我希望这些箭头保持相同的大小,不幸的是它们也 increasing/decreasing 缩放了线条。
我真的不知道如何解决它。这是我的尝试。尝试使用静态比率,因为默认情况下箭头的高度为 50,三角形的高度为 16,尝试了一些计算。但他们永远不会做出正确的决定。也确实尝试删除并重新输入这些三角形,但是在旋转和调整组大小时失败了。
我是不是遗漏了什么明显的东西?或者很难阻止我分组的一个元素缩放。我想做的另一件事是防止缩放矩形中的文本,但我担心它会再次成为同样的噩梦
canvas.on('object:scaled', function (e) {
let type = e.target.get('type');
if (type == 'group') {
var triangleCount = 0, triangles = [];
e.target._objects.forEach(function (object) {
if (object.get('type') == 'triangle') {
triangles[triangleCount] = object;
triangleCount++;
let currentGroupHeight = e.target.get('scaleY') * e.target.get('height');
let ratio = object.get('height') * e.target.get('scaleY') / e.target.get('height') * e.target.get('scaleY');
//object.set('scaleY', 50 / 16);
object.set('scaleY', ratio);
} else if (object.get('type') == 'i-text') {
//canvas.remove(object);
object.set({ scaleX: 1, scaleY: 1 });
}
});
canvas.requestRenderAll();
}
});
function addArrow(options, doubleHeads) {
var line = new fabric.Line([options.e.layerX, options.e.layerY, options.e.layerX, (options.e.layerY + 50)], {
strokeUniform: true,
lockScalingX: true,
borderColor: 'transparent',
left: options.e.layerX,
top: options.e.layerY,
});
var triangleBottom = new fabric.Triangle({
width: 16, height: 16, fill: '#000',
scaleX: 1, scaleY: 1, strokeUniform: true, lockScalingX: true, lockScalingY: true, lockUniScaling: true, lockSkewingX: true, lockSkewingY: true, left: (options.e.layerX - 8), top: (options.e.layerY + 36)
});
triangleBottom.rotate(180);
let display = 0;
if (doubleHeads) {
display = 1;
}
var triangleTop = new fabric.Triangle({
opacity: display, width: 16, height: 16, fill: '#000', scaleX: 1, scaleY: 1, strokeUniform: true, lockScalingX: true, lockScalingY: true, left: (options.e.layerX - 8), top: (options.e.layerY - 0)
});
//groupItems.push(triangleTop);
let groupItems = [line, triangleBottom, triangleTop];
var group = new fabric.Group(groupItems, {
hasControls: true,
left: options.e.layerX,
top: options.e.layerY,
strokeUniform: true,
lockScalingX: true
}).setControlsVisibility({
tl: false,
tr: false,
mt: true,
mb: true,
ml: false,
mr: false,
bl: false,
br: false
});
canvas.add(group);
}
我能想到的唯一方法是在object:scaling
事件中调用箭头调整功能。我想知道是否还有其他更好的解决方案。
var canvas = new fabric.Canvas('canvas', {width: 400, height: 400});
canvas.on('object:scaling', function (e) {
let type = e.target.get('type');
if (type == 'group') {
adjustArrowsSize(e.target._objects, e.target.get('scaleY'))
}
});
canvas.on('object:scaled', function (e) {
let type = e.target.get('type');
if (type == 'group') {
adjustArrowsSize(e.target._objects, e.target.get('scaleY'))
}
});
function adjustArrowsSize(arrowObjects, objectScaleY) {
var triangleCount = 0, triangles = [];
arrowObjects.forEach(function (object) {
if (object.get('type') == 'triangle') {
triangles[triangleCount] = object;
triangleCount++;
let ratio = 1 / objectScaleY;
object.set('scaleY', ratio);
}
});
canvas.requestRenderAll();
}
function addArrow() {
var line = new fabric.Line([10, 10, 10, (10 + 50)], {
strokeUniform: true,
lockScalingX: true,
borderColor: 'transparent',
left: 10,
top: 10,
strokeWidth: 2,
stroke: '#000'
});
var triangleBottom = new fabric.Triangle({
width: 16, height: 16, fill: '#000',
scaleX: 1, scaleY: 1, strokeUniform: true, lockScalingX: true, lockScalingY: true, lockUniScaling: true, lockSkewingX: true, lockSkewingY: true, left: (10 - 8), top: (10 + 36)
});
triangleBottom.rotate(180);
var triangleTop = new fabric.Triangle({
opacity: 1, width: 16, height: 16, fill: '#000', scaleX: 1, scaleY: 1, strokeUniform: true, lockScalingX: true, lockScalingY: true, left: (10 - 8), top: (10 - 0)
});
//groupItems.push(triangleTop);
let groupItems = [line, triangleBottom, triangleTop];
var group = new fabric.Group(groupItems, {
hasControls: true,
left: 10,
top: 10,
strokeUniform: true,
lockScalingX: true
}).setControlsVisibility({
tl: false,
tr: false,
mt: true,
mb: true,
ml: false,
mr: false,
bl: false,
br: false
});
canvas.add(group);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.6.6/fabric.min.js"></script>
<button onclick="addArrow()">Add arrow</button>
<canvas id="canvas" class="canvas" style="border:1px solid #000;"></canvas>