Reputation: 242
I'm looking for some guidance on textbox editing. I have a working canvas with a textbox on it. When I click the textbox I select it, when I double click I begin editing, this seems like normal behaviour - is it possible to begin editing with the single click and (important) have the text caret (cursor) where I clicked.
EG: If my textbox already has the words "Click me", if I click (single) before the 'me' can I begin editing using canvas.getActiveObject().enterEditing() or similar with the position of the textbox caret (cursor) in the location I clicked?
Double click works fine, but I'm trying to do this with one click.
Here is a JSFiddle, to play with or clone. https://jsfiddle.net/Milner99/2vgb5cLz/7/
Fiddle code
let canvas = new fabric.Canvas('fabricjs1');
let jsonDesign = ` {"version":"4.4.0","objects[{"type":"textbox","version":"4.4.0","originX":"left","originY":"top","left":54.99,"top":155.62,"width":381,"height":161.09,"fill":"rgb(0,0,0)","stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeUniform":false,"strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","skewX":0,"skewY":0,"text":"YOUR LINE TEXT twice","fontSize":"66","fontWeight":"normal","fontFamily":"CandyCardCasual","fontStyle":"normal","lineHeight":1.16,"underline":false,"overline":false,"linethrough":false,"textAlign":"center","textBackgroundColor":"","charSpacing":0,"path":null,"minWidth":20,"splitByGrapheme":false,"styles":{}}]} `;
canvas.loadFromJSON(
jsonDesign,
canvas.renderAll.bind(canvas)
);
canvas.on('selection:created', function(obj) {
console.log(obj);
canvas.getActiveObject().enterEditing();
});
Thank you
Upvotes: 2
Views: 1134
Reputation: 12891
With a little trickery you can achieve this functionality. The IText
class provides a method called setCursorByClick({x , y})
which positions the cursor according the x and y values given to the method. So you basically need to attach a mousedown
and a mouseup
listener to your object, get the mouse position from the event and use it with the setCursorByClick method on your actual text object.
I recommend using a mousedown listener first as you probably still want your object to be draggable. So on mouseup, we're comparing the mouse position with the mousedown event and if it's equal position the cursor - if not we do not.
Here's an example:
let canvas = new fabric.Canvas('fabricjs1');
let jsonDesign = ` {"version":"4.4.0","objects":[{"type":"textbox","version":"4.4.0","originX":"left","originY":"top","left":54.99,"top":155.62,"width":381,"height":161.09,"fill":"rgb(0,0,0)","stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeUniform":false,"strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","skewX":0,"skewY":0,"text":"YOUR LINE TEXT twice","fontSize":"66","fontWeight":"normal","fontFamily":"CandyCardCasual","fontStyle":"normal","lineHeight":1.16,"underline":false,"overline":false,"linethrough":false,"textAlign":"center","textBackgroundColor":"","charSpacing":0,"path":null,"minWidth":20,"splitByGrapheme":false,"styles":{}}]} `;
canvas.loadFromJSON(
jsonDesign,
canvas.renderAll.bind(canvas)
);
let coords = {};
canvas.getObjects()[0].on('mousedown', function(obj) {
coords = this.canvas.getPointer(obj.e);
});
canvas.getObjects()[0].on('mouseup', function(obj) {
let e = this.canvas.getPointer(obj.e);
if (e.x == coords.x && e.y == coords.y) {
obj.target.enterEditing();
obj.target.setCursorByClick(e);
}
});
<canvas id="fabricjs1" width="500" height="500"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.5.0/fabric.min.js"></script>
Upvotes: 5