What is the procedure for combining individual objects into a single, unified group that maintains its structure?

I'm currently using fabricjs version 1.7.21 and I have a button that allows me to add text to the canvas. I am wondering how I can add a group of objects, such as multiple editable IText fields (as shown on the right side), to the canvas just like I can with a single IText object.

In simpler terms, I want to be able to add elements similar to those on the right side by clicking a button and then moving them around as a group.

var canvas = new fabric.Canvas("c");
canvas.setHeight(500);
canvas.setWidth(500);

// Add Text
function Addtext() {
  var text = new fabric.IText("Type...", {
    fontSize: 30,
    top: 10,
    left: 10,
    width: 200,
    height: 200,
    textAlign: "center"
  });
  canvas.add(text);
  canvas.setActiveObject(text);
  text.enterEditing();
  text.selectAll();
  text.renderCursorOrSelection(); // or canvas.renderAll();
  canvas.isDrawingMode = false;
}

// Right Side Objects

// Header Constants
const toppers = {
  fontSize: 27,
  hasBorders: true,
  hasControls: false,
  left: 380,
  lockMovementX: true,
  lockMovementY: true,
  lockRotation: true,
  originX: "center",
  originY: "center",
  selectable: true,
  align: "mid",
  centeredScaling: true,
};
const headingOne = {
  lockMovementX: true,
  lockMovementY: true,
  originX: "center",
  originY: "center",
  selectable: true,
  align: "mid",
  fontSize: 14,
  fontStyle: "italic",
  hasBorders: true,
  hasControls: false,
  hasRotatingPoint: false,
  left: 380,
};
const headingTwo = {
  align: "mid",
  centeredScaling: true,
  fontSize: 20,
  hasBorders: true,
  hasControls: false,
  hasRotatingPoint: false,
  lockMovementX: true,
  lockMovementY: true,
  lockRotation: true,
  originX: "center",
  originY: "center",
  selectable: true,

  left: 380,
};

canvas.add(new fabric.IText("Some Text", {
  ...toppers,
  top: 25,
}));
canvas.add(new fabric.IText("Some Text", {
  ...toppers,
  fontWeight: "bold",
  top: 60,
}));
canvas.add(new fabric.IText("Some Text", { 
  ...headingOne,
  top: 90,
}));
canvas.add(new fabric.IText("Some Text", { 
  ...headingTwo,
  top: 110,
}));
canvas {
  border: 1px solid #dddddd;
  margin-top: 10px;
  border-radius: 3px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.21/fabric.min.js"></script>
<button onclick="Addtext()">Add Text</button>
<canvas id="c"></canvas>

Answer №1

It seems like you're looking for a way to add a text field to a canvas and bind it to a group using a button. You can achieve this by following the code below:

var canvas = new fabric.Canvas("c");
canvas.setHeight(500);
canvas.setWidth(500);
canvas.isDrawingMode = false;
var myGroupOfText = new fabric.Group();

function Addtext() {
  var text = new fabric.IText("Type...", {
    fontSize: 30,
    top: 10,
    left: 10,
    width: 200,
    height: 200,
    textAlign: "center"
  });
  canvas.add(text);
  myGroupOfText.add(text);      
}

If you want to select the added text automatically, you can use the following code snippet:

canvas.setActiveObject(text);
text.enterEditing();
text.selectAll();

Remember that the 'add' method already includes a call to canvas.renderAll(), so there's no need to include it separately.

It's important not to confuse drawingMode with an imaginary insertionMode. The drawingMode setting in the canvas determines if free drawing is enabled, while re-setting it each time you add an IText is unnecessary unless there are specific constraints.

EDIT : Based on your feedback, you may find the following code useful:

 var canvas = new fabric.Canvas("c");
canvas.setHeight(500);
canvas.setWidth(500);
canvas.isDrawingMode = false;

[...]

function addGroupOfText() {
    var myGroupOfText = new fabric.Group();
    myGroupOfText.setOptions({selectable: true});
    var options = {
        fontSize: 30,
        top: 10,
        left: 10,
        width: 200,
        height: 200,
        textAlign: "center",
        selectable: false,
        fontWeight: normal, // or 'bold', or a number. see docs
        underline: false, // or true
        fontStyle: normal // or 'italic'. see docs
      }
    this.addText(myGroupOfText, options); // repeat this call as many time as needed
}

function addText(group, options) {
  var text = new fabric.IText("Type...", options);
  canvas.add(text);
  group.add(text);      
}

This code allows you to add multiple text fields and customize their options individually. For more information, refer to the documentation links provided. Feel free to ask for clarification in the comments if needed.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Set a value for the hidden field on the page using client-side scripting

When working with an ASP.net application, I often use Page.ClientScript.RegisterHiddenField("hf_Name", value). However, I am curious about how to override or set a new value for the same Hidden Field 'hf_Name' in the code behind. Can you provide ...

Tips for effectively finding information within a table

I came across this code snippet for a table created with sveltestrap. I am struggling to figure out how to make the search case insensitive and would appreciate any help or guidance on how to do so. This is the code I have tested using Svelte REPL: & ...

Revolutionize Your App with React Native's Interactive Bottom Sheet Option

Hello there! I am trying to create a FlatList with multiple items, each of which should trigger a bottom-sheet when clicked. I want to make this dynamic but I'm encountering an error. TypeError: undefined is not an object (evaluating `_this[_reactNat ...

standalone visuals generated interactively with matplotlib

While I appreciate the plots generated by matplotlib and the ability to save them as SVG, there is a feature missing that I would like to see added... I am looking for a way to save the figure as an SVG file with embedded JavaScript code to add interactiv ...

"Troubleshooting: Issues with message passing between popup.html and content.js in Chrome Extension

I'm facing a challenge in creating an Extension that transfers data from popup.html to the tab dome. Unfortunately, I am having trouble with getting the sendMessage function to work and I can't figure out why. I'm using the following guideli ...

elasticsearch query for deletion only returns documents that are not found

I have been attempting to use the https://www.npmjs.com/package/elasticsearch-deletebyquery package to delete documents using a query. However, I keep receiving a "Not found" error. Here is my code snippet: client.deleteByQuery({ index: index, type: t ...

Implementing data filtering in a React component post data retrieval

Just diving into React and experimenting with filtering data once it's fetched. I have a select tag with options and I'm looking to update the data array based on the selected option. For instance, if 'crypto' is chosen, only display da ...

Tips for resolving issues related to Nodemailer configuration

I am currently working on a script that sends form data to an email address. I am using Express and Nodemailer with Node.js, but as a beginner, I am struggling to understand why the email authorization stops and prevents the letters from being sent. Here ...

Utilizing JQuery to modify the element's id and trigger a function upon clicking

There is an element with a specific ID that I have changed. However, even after changing the ID and clicking on the element with the new ID, it still triggers the function associated with the old ID. $('#1st').click(function(){ $('#1s ...

What is the best way to surround the initial x words within an element with a span tag?

Is there a way to style the first 10 words of a paragraph in a different color when the content is constantly changing? I can't manually add a span in the HTML. My approach involves using JavaScript to iterate through all instances of .overview__text. ...

Is there a way to send a variable from a client-side script to a server-side script?

I am facing a challenge in Google App Maker where I am attempting to execute a Client Script to retrieve a variable and then pass that variable to a Server Script for further use. However, I am struggling to figure out the correct implementation. Within m ...

What might take precedence over preventing the default action? When you press the Enter key to submit the form on the target, it submits the form without triggering a click event (in

Here is a simple piece of code... document.addEventListener('keydown', function (e) { if (e.keyCode == 13 || e.keyCode == 32) { e.preventDefault(); $(e.target).trigger("click"); ...

Error Encountered: AJAX Request Failed with 400 Bad Request

I've been using mithril.js to communicate with my node back-end. I followed the documentation and added an AJAX request, but there seems to be limited information available on mithril. Encountered Error: mithril.js:2130 POST http://localhost:3000/a ...

JavaScript Mortgage Calculator: Issue with Input Field Formatting when Adding Commas

I am currently developing a mortgage calculator and I would like to include commas in the form fields. The code I found worked well initially, but once numbers reached over 1,000,000, the formatting became strange. Since I am new to JavaScript, any guidanc ...

Is there a way to transform this JavaScript/jQuery code into a function that is not written inline?

Here is the code snippet I have: $(".openDialog").on("click", function (e) { e.preventDefault(); $("<div></div>") .addClass("dialog") .attr("id", $(this).attr("data-dialog-id")) .appendTo("body") .dialog({ titl ...

Why isn't the unit test passing when it clearly should be?

I am encountering an issue with testing a simple function that I have created. Despite the fact that the function works correctly in practice, it is not being tested properly... Explanation of how my function operates (While it functions as intended, the ...

Looking for a JavaScript function that will enable the acceptance of commas and spaces

How can I modify this integer validation function to allow for commas and spaces to be entered during the keydown event? function intValidate(event) { if (event.keyCode == 46 || event.keyCode == 8 || event.keyCode == 9 || event.keyCode == 27 || even ...

The negative z-index is causing issues with my ability to select classes using jQuery

By setting a z-index of -3 for several divs in my background, I thought they wouldn't affect the formatting of elements in the foreground. But now I'm facing an issue where I can't click on those background divs when trying to target them wi ...

Can I trust the security of my credentials if they are able to be logged in the console

While working with NextJS, I've encountered a challenge in applying server-side rendering methods like getStaticProps to maintain credentials on the server rather than exposing them to the client. Despite my attempts, I couldn't find a straightfo ...

Encountering the error "Vue 2.0 encounters an undefined push during router.push

I'm currently working on a project that involves implementing a function to route the list of subMenus displayed by the mainMenu. Each subMenu is identified by its specific name, which I would like to append and use as the route path that I am aiming ...