Merge two JSON objects to combine additional data in fabric.js canvas

{
  "objects": [{
    "type": "i-text",
    "originX": "left",
    "originY": "top",
    "left": 253.75,
    "top": 377.4,
    "width": 293.49609375,
    "height": 45.199999999999996,
    "fill": "#454545",
    "stroke": null,
    "strokeWidth": 1,
    "strokeDashArray": null,
    "strokeLineCap": "butt",
    "strokeLineJoin": "miter",
    "strokeMiterLimit": 10,
    "scaleX": 1,
    "scaleY": 1,
    "angle": 0,
    "flipX": false,
    "flipY": false,
    "opacity": 1,
    "shadow": null,
    "visible": true,
    "clipTo": null,
    "backgroundColor": "",
    "fillRule": "nonzero",
    "globalCompositeOperation": "source-over",
    "transformMatrix": null,
    "skewX": 0,
    "skewY": 0,
    "text": "Start typing here",
    "fontSize": 40,
    "fontWeight": "normal",
    "fontFamily": "arial",
    "fontStyle": "",
    "lineHeight": 1.16,
    "textDecoration": "",
    "textAlign": "left",
    "textBackgroundColor": "",
    "charSpacing": 0,
    "originalScaleX": 1,
    "originalScaleY": 1,
    "originalLeft": 253.751953125,
    "originalTop": 377.4,
    "lockMovementX": false,
    "lockMovementY": false,
    "lockScalingX": false,
    "lockScalingY": false,
    "lockUniScaling": false,
    "lockRotation": false,
    "id": 8454,
    "styles": {}
  },
  {
    "type": "i-text",
    "originX": "left",
    "originY": "top",
    "left": 253.75,
    "top": 377.4,
    "width": 293.49609375,
    "height": 45.199999999999996,
    "fill": "#454545",
    "stroke": null,
    "strokeWidth": 1,
    "strokeDashArray": null,
    "strokeLineCap": "butt",
    "strokeLineJoin": "miter",
    "strokeMiterLimit": 10,
    "scaleX": 1,
    "scaleY": 1,
    "angle": 0,
    "flipX": false,
    "flipY": false,
    "opacity": 1,
    "shadow": null,
    "visible": true,
    "clipTo": null,
    "backgroundColor": "",
    "fillRule": "nonzero",
    "globalCompositeOperation": "source-over",
    "transformMatrix": null,
    "skewX": 0,
    "skewY": 0,
    "text": "Start typing here",
    "fontSize": 40,
    "fontWeight": "normal",
    "fontFamily": "arial",
    "fontStyle": "",
    "lineHeight": 1.16,
    "textDecoration": "",
    "textAlign": "left",
    "textBackgroundColor": "",
    "charSpacing": 0,
    "originalScaleX": 1,
    "originalScaleY": 1,
    "originalLeft": 253.751953125,
    "originalTop": 377.4,
    "lockMovementX": false,
    "lockMovementY": false,
    "lockScalingX": false,
    "lockScalingY": false,
    "lockUniScaling": false,
    
    "lockRotation": false,
    "id": 6668,
    "styles": {}
  }],
  "background": "#ffffff",
  "height": 800,
  "width": 801,
  "originalHeight": 800,
  "originalWidth": 801
}

Is there a way to combine these two fabric.js JSON objects and load them onto the canvas using the fabric loadJSON method?

Answer №1

If Sagar Adke has specific goals in mind, there are various approaches he can take to achieve them. Here are some recommendations that may align with his objectives:

https://i.sstatic.net/gWbQo.png

STRATEGY 1:

To preserve the canvas content when loading different JSON objects, consider cloning the initial object, then loading the second JSON and adding the cloned object.

canvas.loadFromJSON(JSON.stringify(json1), canvas.renderAll.bind(canvas));
var item = canvas.item(0).clone();
canvas.loadFromJSON(JSON.stringify(json2), canvas.renderAll.bind(canvas));
// Adjust position of cloned object if required
item.set({
  top: item.top - 70
});
canvas.add(item);
canvas.renderAll();

Try it out on JSFiddle: http://jsfiddle.net/rekrah/wxjnu7pd/.

STRATEGY 2:

Add the objects from the second JSON onto the stack of the first JSON before loading the canvas with the combined content.

json1.objects.push(json2.objects[0]);
// Both objects may overlap as they are identical
canvas.loadFromJSON(JSON.stringify(json1), canvas.renderAll.bind(canvas));
canvas.renderAll();

Experience this approach on JSFiddle: http://jsfiddle.net/rekrah/okb2uj1m/.

STRATEGY 3:

An alternative method involves passing an array of fabric objects to enlivenObjects without prior stringification and managing object addition within the callback function.

fabric.util.enlivenObjects([json1.objects[0], json2.objects[0]], function(objects) {
  var origRenderOnAddRemove = canvas.renderOnAddRemove;
  canvas.renderOnAddRemove = false;
  objects.forEach(function(o, i) {
    // Adjust position of first object if necessary
    if (i == 0) o.set({
      top: o.top - 70
    });
    canvas.add(o);
  });
  canvas.renderOnAddRemove = origRenderOnAddRemove;
  canvas.renderAll();
});

Explore this solution on JSFiddle: http://jsfiddle.net/rekrah/jnkLjrn4/.

(Credits for Strategy 3 go to a renowned FabricJS expert: )

Answer №2

When it comes to manipulating objects, my go-to tool is underscore.js. It's the first JavaScript library I include whenever I kick off a new project.

http://underscorejs.org

Check out: _.extend (or better yet, explore the entire library ;))

_.extend({name: 'moe'}, {age: 50});
=> {name: 'moe', age: 50}

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

The feature "scrollTo" in mcustomscrollbar is not functional in Chrome, however, it functions properly in FireFox

It seems that there is an issue with the mcustomscrollbar "scrollTo" function not working in Chrome, although it works fine in FireFox. No errors are showing up in the console, so it appears to be a browser-specific problem. I even tested the functionali ...

Unable to retrieve the value of a JSON object

I have a JSON Object called contacts that has the following structure: {"email":"<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="337e524158737b5c5c58525b604752475a5c"><email address hidden></a>","phone":"+197969 ...

Tips for modifying HTML attributes in AngularJS

I am looking to modify an attribute of a div using AngularJS. While I am familiar with how to do this in jQuery, I am not sure how to achieve it in Angular. Here is the HTML code: <div ng-app="test"> <div ng-controller="cont"> < ...

What is the best way to apply ng-style to a single element that was generated using $index within an ng-repeat loop

I am dealing with 2 directives: wa-hotspots and wa-tooltips. When the ng-mouseover event occurs on wa-hotspots, it takes the $index of wa-hotspot and adjusts the visibility and position of wa-tooltip using ng-class:on and ng-style="tooltipCoords" by matchi ...

Update a portion of the list items

Here is the HTML code I am working with: <ul id="info"> <li> <span>Name:</span>Charis Spiropoulos </li> ... I need to change the content of the <li> element that is not within the span. How can I do this? Cur ...

Attempting to display an image based on the outcome of a function that was executed earlier

As a beginner in the world of JavaScript, I kindly ask for your patience and detailed explanations in helping me understand the concepts. My current project involves creating a button that randomly selects a name from a list and displays it along with an ...

"Delightful Data Display: Achieving Ajax Triumph with

When I include the success function in my DataTable, the rows do not automatically fill up in the table. However, when I remove the success function everything works correctly, and the datatable fills with data as expected. I am trying to retrieve a messag ...

Typescript Tooltip for eCharts

I'm working on customizing the tooltip in eChart v5.0.2 using Typescript, but I'm encountering an error related to the formatter that I can't seem to resolve. The error message regarding the function keyword is as follows: Type '(param ...

Best practices for managing a Media Stream in Node.js

One of the latest and most exciting features in modern browsers is HTMLMediaElement.captureStream(), which has recently been released in Chrome. Having grasped how it functions on the client side - allowing you to redirect the stream to other HTMLMediaEle ...

The issue of integrating jQuery with the textarea CKEditor is still unresolved

I'm having an issue with applying the ckeditor function to append data in my code. I have included a cdn link for ckeditor in the header.php file, but it's not working as expected. How can I resolve this? <script> $(document).ready(func ...

What are the steps to create a new website with a MEAN stack application on a Windows 10 home computer?

A few days ago, I successfully installed the MEAN stack application on my Windows 10 system. However, I am unsure of how to proceed with creating a new website using this MEAN stack application. Can anyone provide guidance on how to go about building a w ...

The JSON object contains arrays that I send to the server side using an AJAX call. I am wondering how I can access this data once it has been sent

$scope.addQunatity = function(){ var url="../php/mainPageFacture.php"; // store data from user in the js arrays var quan_cls_crt=[$("#quan_cls_crt").val(),$("#quan_cls_crt2").val()]; var quan_piece=[$("#quan_piece").val(),$("#quan_piece2" ...

What are the applications of global variables in node.js?

global.test = "test"; console.log(global.test); //test but I want to accomplish this: console.log(test); //test without using: var test = global.test; Is there a way to achieve this? I am looking for a solution where any module in my project does not ...

What steps should I take to ensure that the child menus of the v-navigation-drawer component are activated during the initial project launch?

I have created a v-navigation-drawer component with Vue 3 and Vuetify 3. The v-navigation-drawer functions properly, but I want the child menus to be visible by default without requiring the user's click when the project first launches. I am using v- ...

Trouble with console.log and document.addEventListener, they just won't cooperate

I'm currently working on a phonegap application for IOS. I was able to successfully create the project and when running the initial application, everything worked perfectly. However, when I tried to add my own code, it seems that none of the javascrip ...

ng-repeat exceeding the boundaries of the div

I am using ng-repeat to iterate through elements <div class="description-block" style="text-align: left; margin: 0px"> <span class="description-text">Targets: </span> <span ng-repeat="target in obj.targets" class="lab ...

I am interested in invoking a function from a different component

I am facing an issue with my component AddPost.js where I am trying to use a method from machine.js. However, when I attempt to import AddPost into the machine.js file, it throws an error: Possible Unhandled Promise Rejection (id: 0): ReferenceError: addIn ...

Creating an HTML table dynamically through JavaScript within a script block

I am working on using a JavaScript API to send emails, with the ability to include HTML. I am trying to create a table inside the email body, but it doesn't seem to be displaying properly. Here is the code snippet I'm using: <script> $ ...

I'm experiencing trouble with Shopify as it appears to be failing to execute

I have been attempting to incorporate a tracking pixel into my project. Thus far, I have tested the code in various environments, both with and without wrapping it in a function and deploying it using window.onload. If you would like to see the implementa ...

Enhance autocomplete functionality by adding an additional parameter specific to Zend Framework

My form includes two fields: country club The club field is generated using the ZendX_JQuery_Form_Element_AutoComplete Element, which also creates this javascript code: $("#club").autocomplete({"url":"\/mywebsite\/\/mycontroller\/au ...