ps0*_*604 4 javascript fabricjs
在这个jsFiddle 中,我有一个包含 Rect 和 Textbox 的 Fabric 组。我需要能够在不缩放文本的情况下缩放 Rect,因此我尝试在选择组时取消分组,并在清除选择时再次分组。还:
如何使 jsFiddle 工作?
笔记
文本和矩形总是一起移动,即使在任何选择之前或之后也是如此。
var canvas = window._canvas = new fabric.Canvas('c');
var text = new fabric.Textbox("Some text", {
width: 100,
height: 22,
fontSize: 12,
editable: true
});
var rect = new fabric.Rect({
width: 100,
height: 22,
fill: 'yellow'
});
var group = new fabric.Group([ rect, text ], {
left: 30,
top: 30
});
canvas.add(group);
group.on('selected', function (e){
canvas.remove(group);
canvas.add(rect);
canvas.add(text);
canvas.renderAll();
canvas.setActiveObject(rect);
});
canvas.on('selection:cleared', function(e) {
group = new fabric.Group([ rect, text ], {});
});
Run Code Online (Sandbox Code Playgroud)
shk*_*per 10
编辑:OP 澄清了一些要求,因此相应地编辑了解决方案。
虽然分组乍一看似乎是个好主意,但仔细想想,您的文本/矩形组合所需的唯一分组功能是能够一起移动。这意味着创建一个组并尝试禁用所有不需要的功能实际上比将 Text 粘贴到您的 Rect 并仅处理您关心的事件更难。
Fabric.js 有一个很好的子类化机制,我们将使用它来扩展fabric.Rect类。
下面的代码是不言自明的,我只注意几个关键方面:
rectOptions并textOptions传入fabric.RectWithText构造函数,是您通常会传入的对象fabric.Rect和fabric.Textbox构造函数,因此。Textbox被引用text的财产RectWithText情况。recalcTextPosition 给定两者之间的初始偏移量,使用几个三角公式计算文本相对于矩形的位置。moving,scaling和rotating活动顺利重新计算文本的位置。mousedown:before, mousedblclick,editing:exited确保文本在双击时保持可编辑状态。canvas.preserveObjectStacking单击对象的时间来将文本保持在顶部。const canvas = new fabric.Canvas('c')
fabric.RectWithText = fabric.util.createClass(fabric.Rect, {
type: 'rectWithText',
text: null,
textOffsetLeft: 0,
textOffsetTop: 0,
_prevObjectStacking: null,
_prevAngle: 0,
recalcTextPosition: function () {
const sin = Math.sin(fabric.util.degreesToRadians(this.angle))
const cos = Math.cos(fabric.util.degreesToRadians(this.angle))
const newTop = sin * this.textOffsetLeft + cos * this.textOffsetTop
const newLeft = cos * this.textOffsetLeft - sin * this.textOffsetTop
const rectLeftTop = this.getPointByOrigin('left', 'top')
this.text.set('left', rectLeftTop.x + newLeft)
this.text.set('top', rectLeftTop.y + newTop)
},
initialize: function (rectOptions, textOptions, text) {
this.callSuper('initialize', rectOptions)
this.text = new fabric.Textbox(text, {
...textOptions,
selectable: false,
evented: false,
})
this.textOffsetLeft = this.text.left - this.left
this.textOffsetTop = this.text.top - this.top
this.on('moving', () => {
this.recalcTextPosition()
})
this.on('rotating', () => {
this.text.rotate(this.text.angle + this.angle - this._prevAngle)
this.recalcTextPosition()
this._prevAngle = this.angle
})
this.on('scaling', (e) => {
this.recalcTextPosition()
})
this.on('added', () => {
this.canvas.add(this.text)
})
this.on('removed', () => {
this.canvas.remove(this.text)
})
this.on('mousedown:before', () => {
this._prevObjectStacking = this.canvas.preserveObjectStacking
this.canvas.preserveObjectStacking = true
})
this.on('mousedblclick', () => {
this.text.selectable = true
this.text.evented = true
this.canvas.setActiveObject(this.text)
this.text.enterEditing()
this.selectable = false
})
this.on('deselected', () => {
this.canvas.preserveObjectStacking = this._prevObjectStacking
})
this.text.on('editing:exited', () => {
this.text.selectable = false
this.text.evented = false
this.selectable = true
})
}
})
const rectOptions = {
left: 10,
top: 10,
width: 200,
height: 75,
fill: 'rgba(30, 30, 30, 0.3)',
}
const textOptions = {
left: 35,
top: 30,
width: 150,
fill: 'white',
shadow: new fabric.Shadow({
color: 'rgba(34, 34, 100, 0.4)',
blur: 2,
offsetX: -2,
offsetY: 2
}),
fontSize: 30,
}
const rectWithText = new fabric.RectWithText(rectOptions, textOptions, 'Some text')
canvas.add(rectWithText)Run Code Online (Sandbox Code Playgroud)
body {
background: ivory;
}Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.4.0/fabric.js"></script>
<canvas id="c" width="300" height="200"></canvas>Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1704 次 |
| 最近记录: |